bump product version to 7.2.5.1
[LibreOffice.git] / xmlsecurity / workben / pdfverify.cxx
blob0951eb7c5e6516fba5453adf379099d7950d2fa3
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 <tools/diagnose_ex.h>
23 #include <vcl/pngwrite.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 WmfExternal* pExtHeader = nullptr;
45 if (rFilter.ImportGraphic(aGraphic, OUString(), aInStream, GRFILTER_FORMAT_DONTKNOW, nullptr,
46 GraphicFilterImportFlags::NONE, pExtHeader)
47 != ERRCODE_NONE)
48 return;
50 BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
51 vcl::PNGWriter aWriter(aBitmapEx);
52 OUString aOutURL;
53 osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(rPngPath), aOutURL);
54 SvFileStream aOutStream(aOutURL, StreamMode::WRITE);
55 aWriter.Write(aOutStream);
58 int pdfVerify(int nArgc, char** pArgv)
60 if (nArgc < 2)
62 SAL_WARN("xmlsecurity.workben", "not enough parameters");
63 return 1;
66 // Initialize nss / mscrypto.
67 uno::Reference<uno::XComponentContext> xComponentContext;
68 try
70 xComponentContext = cppu::defaultBootstrap_InitialComponentContext();
72 catch (const uno::RuntimeException&)
74 TOOLS_WARN_EXCEPTION("xmlsecurity.workben",
75 "cppu::defaultBootstrap_InitialComponentContext() failed:");
76 return 1;
78 uno::Reference<lang::XMultiComponentFactory> xMultiComponentFactory
79 = xComponentContext->getServiceManager();
80 uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xMultiComponentFactory,
81 uno::UNO_QUERY);
82 comphelper::setProcessServiceFactory(xMultiServiceFactory);
84 InitVCL();
85 comphelper::ScopeGuard g([] { DeInitVCL(); });
86 if (nArgc > 3 && pArgv[3] == std::string_view("-p"))
88 generatePreview(pArgv[1], pArgv[2]);
89 return 0;
92 uno::Reference<xml::crypto::XSEInitializer> xSEInitializer;
93 try
95 xSEInitializer = xml::crypto::SEInitializer::create(xComponentContext);
97 catch (const uno::DeploymentException&)
99 TOOLS_WARN_EXCEPTION("xmlsecurity.workben",
100 "DeploymentException while creating SEInitializer:");
101 return 1;
103 uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
104 = xSEInitializer->createSecurityContext(OUString());
106 OUString aInURL;
107 osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(pArgv[1]), aInURL);
108 OUString aOutURL;
109 if (nArgc > 2)
110 osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(pArgv[2]), aOutURL);
112 bool bRemoveSignature = false;
113 if (nArgc > 3 && pArgv[3] == std::string_view("-r"))
114 bRemoveSignature = true;
116 SvFileStream aStream(aInURL, StreamMode::READ);
117 if (aOutURL.isEmpty() && !bRemoveSignature)
119 std::cerr << "verifying signatures" << std::endl;
120 PDFSignatureHelper aHelper;
121 aStream.Seek(0);
122 aHelper.ReadAndVerifySignatureSvStream(aStream);
123 if (aHelper.GetSignatureInformations().empty())
124 std::cerr << "found no signatures" << std::endl;
125 else
127 std::cerr << "found " << aHelper.GetSignatureInformations().size() << " signatures"
128 << std::endl;
129 for (size_t i = 0; i < aHelper.GetSignatureInformations().size(); ++i)
131 const SignatureInformation& rInfo = aHelper.GetSignatureInformations()[i];
132 bool bSuccess
133 = rInfo.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
134 std::cerr << "signature #" << i << ": digest match? " << bSuccess << std::endl;
135 std::cerr << "signature #" << i << ": partial? " << rInfo.bPartialDocumentSignature
136 << std::endl;
140 return 0;
143 vcl::filter::PDFDocument aDocument;
144 if (!aDocument.Read(aStream))
146 SAL_WARN("xmlsecurity.workben", "failed to read the document");
147 return 1;
150 if (bRemoveSignature)
152 std::cerr << "removing the last signature" << std::endl;
153 std::vector<vcl::filter::PDFObjectElement*> aSignatures = aDocument.GetSignatureWidgets();
154 if (aSignatures.empty())
156 std::cerr << "found no signatures" << std::endl;
157 return 1;
160 size_t nPosition = aSignatures.size() - 1;
161 if (!aDocument.RemoveSignature(nPosition))
163 SAL_WARN("xmlsecurity.workben", "failed to remove signature #" << nPosition);
164 return 1;
167 SvFileStream aOutStream(aOutURL, StreamMode::WRITE | StreamMode::TRUNC);
168 if (!aDocument.Write(aOutStream))
170 SAL_WARN("xmlsecurity.workben", "failed to write the document");
171 return 1;
174 return 0;
177 std::cerr << "adding a new signature" << std::endl;
178 uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment
179 = xSecurityContext->getSecurityEnvironment();
180 uno::Sequence<uno::Reference<security::XCertificate>> aCertificates
181 = xSecurityEnvironment->getPersonalCertificates();
182 if (!aCertificates.hasElements())
184 SAL_WARN("xmlsecurity.workben", "no signing certificates found");
185 return 1;
187 if (!aDocument.Sign(aCertificates[0], "pdfverify", /*bAdES=*/true))
189 SAL_WARN("xmlsecurity.workben", "failed to sign");
190 return 1;
193 SvFileStream aOutStream(aOutURL, StreamMode::WRITE | StreamMode::TRUNC);
194 if (!aDocument.Write(aOutStream))
196 SAL_WARN("xmlsecurity.workben", "failed to write the document");
197 return 1;
200 return 0;
204 SAL_IMPLEMENT_MAIN_WITH_ARGS(nArgc, pArgv)
208 return pdfVerify(nArgc, pArgv);
210 catch (...)
212 std::cerr << "pdfverify: uncaught exception while invoking pdfVerify()" << std::endl;
213 return 1;
217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */