From 940b4d1848e8c70ab7642901a68594e8016caffc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 18:51:28 +0200 Subject: Adding upstream version 1:7.0.4. Signed-off-by: Daniel Baumann --- xmlsecurity/workben/pdfverify.cxx | 222 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 xmlsecurity/workben/pdfverify.cxx (limited to 'xmlsecurity/workben/pdfverify.cxx') diff --git a/xmlsecurity/workben/pdfverify.cxx b/xmlsecurity/workben/pdfverify.cxx new file mode 100644 index 000000000..c44803594 --- /dev/null +++ b/xmlsecurity/workben/pdfverify.cxx @@ -0,0 +1,222 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +using namespace com::sun::star; + +namespace +{ +/// Does PDF to PNG conversion using pdfium. +void generatePreview(const OString& rPdfPath, const OString& rPngPath) +{ + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + Graphic aGraphic; + OUString aInURL; + osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(rPdfPath), aInURL); + SvFileStream aInStream(aInURL, StreamMode::READ); + WmfExternal* pExtHeader = nullptr; + if (rFilter.ImportGraphic(aGraphic, OUString(), aInStream, GRFILTER_FORMAT_DONTKNOW, nullptr, + GraphicFilterImportFlags::NONE, pExtHeader) + != ERRCODE_NONE) + return; + + BitmapEx aBitmapEx = aGraphic.GetBitmapEx(); + vcl::PNGWriter aWriter(aBitmapEx); + OUString aOutURL; + osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(rPngPath), aOutURL); + SvFileStream aOutStream(aOutURL, StreamMode::WRITE); + aWriter.Write(aOutStream); +} + +int pdfVerify(int nArgc, char** pArgv) +{ + if (nArgc < 2) + { + SAL_WARN("xmlsecurity.pdfio", "not enough parameters"); + return 1; + } + + // Initialize nss / mscrypto. + uno::Reference xComponentContext; + try + { + xComponentContext = cppu::defaultBootstrap_InitialComponentContext(); + } + catch (const uno::RuntimeException&) + { + TOOLS_WARN_EXCEPTION("xmlsecurity.pdfio", + "cppu::defaultBootstrap_InitialComponentContext() failed:"); + return 1; + } + uno::Reference xMultiComponentFactory + = xComponentContext->getServiceManager(); + uno::Reference xMultiServiceFactory(xMultiComponentFactory, + uno::UNO_QUERY); + comphelper::setProcessServiceFactory(xMultiServiceFactory); + + InitVCL(); + comphelper::ScopeGuard g([] { DeInitVCL(); }); + if (nArgc > 3 && OString(pArgv[3]) == "-p") + { + generatePreview(pArgv[1], pArgv[2]); + return 0; + } + + uno::Reference xSEInitializer; + try + { + xSEInitializer = xml::crypto::SEInitializer::create(xComponentContext); + } + catch (const uno::DeploymentException&) + { + TOOLS_WARN_EXCEPTION("xmlsecurity.pdfio", + "DeploymentException while creating SEInitializer:"); + return 1; + } + uno::Reference xSecurityContext + = xSEInitializer->createSecurityContext(OUString()); + + OUString aInURL; + osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(pArgv[1]), aInURL); + OUString aOutURL; + if (nArgc > 2) + osl::FileBase::getFileURLFromSystemPath(OUString::fromUtf8(pArgv[2]), aOutURL); + + bool bRemoveSignature = false; + if (nArgc > 3 && OString(pArgv[3]) == "-r") + bRemoveSignature = true; + + SvFileStream aStream(aInURL, StreamMode::READ); + vcl::filter::PDFDocument aDocument; + if (!aDocument.Read(aStream)) + { + SAL_WARN("xmlsecurity.pdfio", "failed to read the document"); + return 1; + } + + if (bRemoveSignature) + { + std::cerr << "removing the last signature" << std::endl; + std::vector aSignatures = aDocument.GetSignatureWidgets(); + if (aSignatures.empty()) + { + std::cerr << "found no signatures" << std::endl; + return 1; + } + + size_t nPosition = aSignatures.size() - 1; + if (!aDocument.RemoveSignature(nPosition)) + { + SAL_WARN("xmlsecurity.pdfio", "failed to remove signature #" << nPosition); + return 1; + } + + SvFileStream aOutStream(aOutURL, StreamMode::WRITE | StreamMode::TRUNC); + if (!aDocument.Write(aOutStream)) + { + SAL_WARN("xmlsecurity.pdfio", "failed to write the document"); + return 1; + } + + return 0; + } + + if (aOutURL.isEmpty()) + { + std::cerr << "verifying signatures" << std::endl; + std::vector aSignatures = aDocument.GetSignatureWidgets(); + if (aSignatures.empty()) + std::cerr << "found no signatures" << std::endl; + else + { + std::cerr << "found " << aSignatures.size() << " signatures" << std::endl; + int nMDPPerm = aDocument.GetMDPPerm(); + for (size_t i = 0; i < aSignatures.size(); ++i) + { + SignatureInformation aInfo(i); + if (!xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[i], aInfo, + aDocument, nMDPPerm)) + { + SAL_WARN("xmlsecurity.pdfio", "failed to determine digest match"); + return 1; + } + + bool bSuccess + = aInfo.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED; + std::cerr << "signature #" << i << ": digest match? " << bSuccess << std::endl; + std::cerr << "signature #" << i << ": partial? " << aInfo.bPartialDocumentSignature + << std::endl; + } + } + + return 0; + } + + std::cerr << "adding a new signature" << std::endl; + uno::Reference xSecurityEnvironment + = xSecurityContext->getSecurityEnvironment(); + uno::Sequence> aCertificates + = xSecurityEnvironment->getPersonalCertificates(); + if (!aCertificates.hasElements()) + { + SAL_WARN("xmlsecurity.pdfio", "no signing certificates found"); + return 1; + } + if (!aDocument.Sign(aCertificates[0], "pdfverify", /*bAdES=*/true)) + { + SAL_WARN("xmlsecurity.pdfio", "failed to sign"); + return 1; + } + + SvFileStream aOutStream(aOutURL, StreamMode::WRITE | StreamMode::TRUNC); + if (!aDocument.Write(aOutStream)) + { + SAL_WARN("xmlsecurity.pdfio", "failed to write the document"); + return 1; + } + + return 0; +} +} + +SAL_IMPLEMENT_MAIN_WITH_ARGS(nArgc, pArgv) +{ + try + { + return pdfVerify(nArgc, pArgv); + } + catch (...) + { + std::cerr << "pdfverify: uncaught exception while invoking pdfVerify()" << std::endl; + return 1; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3