Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / xmlsecurity / workben / pdfverify.cxx
blob191ca8c087eb656baafc658c95ed692a5e429e0a
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>
12 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
13 #include <com/sun/star/uno/XComponentContext.hpp>
14 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
16 #include <comphelper/processfactory.hxx>
17 #include <cppuhelper/bootstrap.hxx>
18 #include <osl/file.hxx>
19 #include <sal/log.hxx>
20 #include <sal/main.h>
21 #include <tools/diagnose_ex.h>
22 #include <vcl/pngwrite.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/graphicfilter.hxx>
25 #include <vcl/filter/pdfdocument.hxx>
27 #include <pdfio/pdfdocument.hxx>
29 #include <svl/sigstruct.hxx>
31 using namespace com::sun::star;
33 namespace
35 /// Does PDF to PNG conversion using pdfium.
36 void generatePreview(const OString& rPdfPath, const OString& rPngPath)
38 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
39 Graphic aGraphic;
40 OUString aInURL;
41 osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(rPdfPath), aInURL);
42 SvFileStream aInStream(aInURL, StreamMode::READ);
43 WmfExternal* pExtHeader = nullptr;
44 if (rFilter.ImportGraphic(aGraphic, OUString(), aInStream, GRFILTER_FORMAT_DONTKNOW, nullptr,
45 GraphicFilterImportFlags::NONE, pExtHeader)
46 != ERRCODE_NONE)
47 return;
49 BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
50 vcl::PNGWriter aWriter(aBitmapEx);
51 OUString aOutURL;
52 osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(rPngPath), aOutURL);
53 SvFileStream aOutStream(aOutURL, StreamMode::WRITE);
54 aWriter.Write(aOutStream);
57 int pdfVerify(int nArgc, char** pArgv)
59 if (nArgc < 2)
61 SAL_WARN("xmlsecurity.pdfio", "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.pdfio",
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 if (nArgc > 3 && OString(pArgv[3]) == "-p")
85 InitVCL();
86 generatePreview(pArgv[1], pArgv[2]);
87 DeInitVCL();
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.pdfio",
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 && OString(pArgv[3]) == "-r")
113 bRemoveSignature = true;
115 SvFileStream aStream(aInURL, StreamMode::READ);
116 vcl::filter::PDFDocument aDocument;
117 if (!aDocument.Read(aStream))
119 SAL_WARN("xmlsecurity.pdfio", "failed to read the document");
120 return 1;
123 if (bRemoveSignature)
125 std::cerr << "removing the last signature" << std::endl;
126 std::vector<vcl::filter::PDFObjectElement*> aSignatures = aDocument.GetSignatureWidgets();
127 if (aSignatures.empty())
129 std::cerr << "found no signatures" << std::endl;
130 return 1;
133 size_t nPosition = aSignatures.size() - 1;
134 if (!aDocument.RemoveSignature(nPosition))
136 SAL_WARN("xmlsecurity.pdfio", "failed to remove signature #" << nPosition);
137 return 1;
140 SvFileStream aOutStream(aOutURL, StreamMode::WRITE | StreamMode::TRUNC);
141 if (!aDocument.Write(aOutStream))
143 SAL_WARN("xmlsecurity.pdfio", "failed to write the document");
144 return 1;
147 return 0;
150 if (aOutURL.isEmpty())
152 std::cerr << "verifying signatures" << std::endl;
153 std::vector<vcl::filter::PDFObjectElement*> aSignatures = aDocument.GetSignatureWidgets();
154 if (aSignatures.empty())
155 std::cerr << "found no signatures" << std::endl;
156 else
158 std::cerr << "found " << aSignatures.size() << " signatures" << std::endl;
159 for (size_t i = 0; i < aSignatures.size(); ++i)
161 SignatureInformation aInfo(i);
162 bool bLast = i == aSignatures.size() - 1;
163 if (!xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[i], aInfo, bLast))
165 SAL_WARN("xmlsecurity.pdfio", "failed to determine digest match");
166 return 1;
169 bool bSuccess
170 = aInfo.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
171 std::cerr << "signature #" << i << ": digest match? " << bSuccess << std::endl;
175 return 0;
178 std::cerr << "adding a new signature" << std::endl;
179 uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment
180 = xSecurityContext->getSecurityEnvironment();
181 uno::Sequence<uno::Reference<security::XCertificate>> aCertificates
182 = xSecurityEnvironment->getPersonalCertificates();
183 if (!aCertificates.hasElements())
185 SAL_WARN("xmlsecurity.pdfio", "no signing certificates found");
186 return 1;
188 if (!aDocument.Sign(aCertificates[0], "pdfverify", /*bAdES=*/true))
190 SAL_WARN("xmlsecurity.pdfio", "failed to sign");
191 return 1;
194 SvFileStream aOutStream(aOutURL, StreamMode::WRITE | StreamMode::TRUNC);
195 if (!aDocument.Write(aOutStream))
197 SAL_WARN("xmlsecurity.pdfio", "failed to write the document");
198 return 1;
201 return 0;
205 SAL_IMPLEMENT_MAIN_WITH_ARGS(nArgc, pArgv)
209 return pdfVerify(nArgc, pArgv);
211 catch (...)
213 std::cerr << "pdfverify: uncaught exception while invoking pdfVerify()" << std::endl;
214 return 1;
218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */