tdf#157086 invert the blur mask instead of the alpha mask
[LibreOffice.git] / xmlsecurity / workben / pdfverify.cxx
blob361e0ae4ae1e8490730f170ce6d0ba0a8e39dc5d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <iostream>
11 #include <string_view>
13 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
14 #include <com/sun/star/uno/XComponentContext.hpp>
15 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
17 #include <comphelper/processfactory.hxx>
18 #include <cppuhelper/bootstrap.hxx>
19 #include <osl/file.hxx>
20 #include <sal/log.hxx>
21 #include <sal/main.h>
22 #include <comphelper/diagnose_ex.hxx>
23 #include <vcl/filter/PngImageWriter.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/graphicfilter.hxx>
26 #include <vcl/filter/pdfdocument.hxx>
27 #include <comphelper/scopeguard.hxx>
28 #include <svl/sigstruct.hxx>
30 #include <pdfsignaturehelper.hxx>
32 using namespace com::sun::star;
34 namespace
36 /// Does PDF to PNG conversion using pdfium.
37 void generatePreview(std::string_view rPdfPath, std::string_view rPngPath)
39 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
40 Graphic aGraphic;
41 OUString aInURL;
42 osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(rPdfPath), aInURL);
43 SvFileStream aInStream(aInURL, StreamMode::READ);
44 if (rFilter.ImportGraphic(aGraphic, u"", aInStream, GRFILTER_FORMAT_DONTKNOW, nullptr,
45 GraphicFilterImportFlags::NONE)
46 != ERRCODE_NONE)
47 return;
49 BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
50 OUString aOutURL;
51 osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(rPngPath), aOutURL);
52 SvFileStream aOutStream(aOutURL, StreamMode::WRITE);
53 vcl::PngImageWriter aWriter(aOutStream);
54 aWriter.write(aBitmapEx);
57 int pdfVerify(int nArgc, char** pArgv)
59 if (nArgc < 2)
61 SAL_WARN("xmlsecurity.workben", "not enough parameters");
62 return 1;
65 // Initialize nss / mscrypto.
66 uno::Reference<uno::XComponentContext> xComponentContext;
67 try
69 xComponentContext = cppu::defaultBootstrap_InitialComponentContext();
71 catch (const uno::RuntimeException&)
73 TOOLS_WARN_EXCEPTION("xmlsecurity.workben",
74 "cppu::defaultBootstrap_InitialComponentContext() failed:");
75 return 1;
77 uno::Reference<lang::XMultiComponentFactory> xMultiComponentFactory
78 = xComponentContext->getServiceManager();
79 uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xMultiComponentFactory,
80 uno::UNO_QUERY);
81 comphelper::setProcessServiceFactory(xMultiServiceFactory);
83 InitVCL();
84 comphelper::ScopeGuard g([] { DeInitVCL(); });
85 if (nArgc > 3 && pArgv[3] == std::string_view("-p"))
87 generatePreview(pArgv[1], pArgv[2]);
88 return 0;
91 uno::Reference<xml::crypto::XSEInitializer> xSEInitializer;
92 try
94 xSEInitializer = xml::crypto::SEInitializer::create(xComponentContext);
96 catch (const uno::DeploymentException&)
98 TOOLS_WARN_EXCEPTION("xmlsecurity.workben",
99 "DeploymentException while creating SEInitializer:");
100 return 1;
102 uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
103 = xSEInitializer->createSecurityContext(OUString());
105 OUString aInURL;
106 osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(pArgv[1]), aInURL);
107 OUString aOutURL;
108 if (nArgc > 2)
109 osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(pArgv[2]), aOutURL);
111 bool bRemoveSignature = false;
112 if (nArgc > 3 && pArgv[3] == std::string_view("-r"))
113 bRemoveSignature = true;
115 SvFileStream aStream(aInURL, StreamMode::READ);
116 if (aOutURL.isEmpty() && !bRemoveSignature)
118 std::cerr << "verifying signatures" << std::endl;
119 PDFSignatureHelper aHelper;
120 aStream.Seek(0);
121 aHelper.ReadAndVerifySignatureSvStream(aStream);
122 if (aHelper.GetSignatureInformations().empty())
123 std::cerr << "found no signatures" << std::endl;
124 else
126 std::cerr << "found " << aHelper.GetSignatureInformations().size() << " signatures"
127 << std::endl;
128 for (size_t i = 0; i < aHelper.GetSignatureInformations().size(); ++i)
130 const SignatureInformation& rInfo = aHelper.GetSignatureInformations()[i];
131 bool bSuccess
132 = rInfo.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
133 std::cerr << "signature #" << i << ": digest match? " << bSuccess << std::endl;
134 std::cerr << "signature #" << i << ": partial? " << rInfo.bPartialDocumentSignature
135 << std::endl;
139 return 0;
142 vcl::filter::PDFDocument aDocument;
143 if (!aDocument.Read(aStream))
145 SAL_WARN("xmlsecurity.workben", "failed to read the document");
146 return 1;
149 if (bRemoveSignature)
151 std::cerr << "removing the last signature" << std::endl;
152 std::vector<vcl::filter::PDFObjectElement*> aSignatures = aDocument.GetSignatureWidgets();
153 if (aSignatures.empty())
155 std::cerr << "found no signatures" << std::endl;
156 return 1;
159 size_t nPosition = aSignatures.size() - 1;
160 if (!aDocument.RemoveSignature(nPosition))
162 SAL_WARN("xmlsecurity.workben", "failed to remove signature #" << nPosition);
163 return 1;
166 SvFileStream aOutStream(aOutURL, StreamMode::WRITE | StreamMode::TRUNC);
167 if (!aDocument.Write(aOutStream))
169 SAL_WARN("xmlsecurity.workben", "failed to write the document");
170 return 1;
173 return 0;
176 std::cerr << "adding a new signature" << std::endl;
177 uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment
178 = xSecurityContext->getSecurityEnvironment();
179 uno::Sequence<uno::Reference<security::XCertificate>> aCertificates
180 = xSecurityEnvironment->getPersonalCertificates();
181 if (!aCertificates.hasElements())
183 SAL_WARN("xmlsecurity.workben", "no signing certificates found");
184 return 1;
186 if (!aDocument.Sign(aCertificates[0], "pdfverify", /*bAdES=*/true))
188 SAL_WARN("xmlsecurity.workben", "failed to sign");
189 return 1;
192 SvFileStream aOutStream(aOutURL, StreamMode::WRITE | StreamMode::TRUNC);
193 if (!aDocument.Write(aOutStream))
195 SAL_WARN("xmlsecurity.workben", "failed to write the document");
196 return 1;
199 return 0;
203 SAL_IMPLEMENT_MAIN_WITH_ARGS(nArgc, pArgv)
207 return pdfVerify(nArgc, pArgv);
209 catch (...)
211 std::cerr << "pdfverify: uncaught exception while invoking pdfVerify()" << std::endl;
212 return 1;
216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */