Bump version to 6.0-36
[LibreOffice.git] / xmlsecurity / source / helper / pdfsignaturehelper.cxx
blob5356705f7b17b5233296886384773b94fca67076
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 <pdfsignaturehelper.hxx>
12 #include <memory>
14 #include <com/sun/star/io/XTruncate.hpp>
15 #include <com/sun/star/security/CertificateValidity.hpp>
16 #include <com/sun/star/uno/SecurityException.hpp>
17 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
19 #include <comphelper/sequence.hxx>
20 #include <tools/stream.hxx>
21 #include <unotools/ucbstreamhelper.hxx>
23 #include <pdfio/pdfdocument.hxx>
25 using namespace ::com::sun::star;
27 PDFSignatureHelper::PDFSignatureHelper() = default;
29 bool PDFSignatureHelper::ReadAndVerifySignature(const uno::Reference<io::XInputStream>& xInputStream)
31 if (!xInputStream.is())
33 SAL_WARN("xmlsecurity.helper", "input stream missing");
34 return false;
37 std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
38 vcl::filter::PDFDocument aDocument;
39 if (!aDocument.Read(*pStream))
41 SAL_WARN("xmlsecurity.helper", "failed to read the document");
42 return false;
45 std::vector<vcl::filter::PDFObjectElement*> aSignatures = aDocument.GetSignatureWidgets();
46 if (aSignatures.empty())
47 return true;
49 m_aSignatureInfos.clear();
51 for (size_t i = 0; i < aSignatures.size(); ++i)
53 SignatureInformation aInfo(i);
55 bool bLast = i == aSignatures.size() - 1;
56 if (!xmlsecurity::pdfio::ValidateSignature(*pStream, aSignatures[i], aInfo, bLast))
57 SAL_WARN("xmlsecurity.helper", "failed to determine digest match");
59 m_aSignatureInfos.push_back(aInfo);
62 return true;
65 SignatureInformations PDFSignatureHelper::GetSignatureInformations() const
67 return m_aSignatureInfos;
70 uno::Sequence<security::DocumentSignatureInformation> PDFSignatureHelper::GetDocumentSignatureInformations(const uno::Reference<xml::crypto::XSecurityEnvironment>& xSecEnv) const
72 uno::Sequence<security::DocumentSignatureInformation> aRet(m_aSignatureInfos.size());
74 for (size_t i = 0; i < m_aSignatureInfos.size(); ++i)
76 const SignatureInformation& rInternal = m_aSignatureInfos[i];
77 security::DocumentSignatureInformation& rExternal = aRet[i];
78 rExternal.SignatureIsValid = rInternal.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
79 if (!rInternal.ouX509Certificate.isEmpty())
80 rExternal.Signer = xSecEnv->createCertificateFromAscii(rInternal.ouX509Certificate);
81 rExternal.PartialDocumentSignature = rInternal.bPartialDocumentSignature;
83 // Verify certificate.
84 if (rExternal.Signer.is())
86 try
88 rExternal.CertificateStatus = xSecEnv->verifyCertificate(rExternal.Signer, {});
90 catch (const uno::SecurityException& rException)
92 SAL_WARN("xmlsecurity.helper", "failed to verify certificate: " << rException);
93 rExternal.CertificateStatus = security::CertificateValidity::INVALID;
96 else
97 rExternal.CertificateStatus = security::CertificateValidity::INVALID;
100 return aRet;
103 sal_Int32 PDFSignatureHelper::GetNewSecurityId() const
105 return m_aSignatureInfos.size();
108 void PDFSignatureHelper::SetX509Certificate(const uno::Reference<security::XCertificate>& xCertificate)
110 m_xCertificate = xCertificate;
113 void PDFSignatureHelper::SetDescription(const OUString& rDescription)
115 m_aDescription = rDescription;
118 bool PDFSignatureHelper::Sign(const uno::Reference<io::XInputStream>& xInputStream, bool bAdES)
120 std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
121 vcl::filter::PDFDocument aDocument;
122 if (!aDocument.Read(*pStream))
124 SAL_WARN("xmlsecurity.helper", "failed to read the document");
125 return false;
128 if (!aDocument.Sign(m_xCertificate, m_aDescription, bAdES))
130 SAL_WARN("xmlsecurity.helper", "failed to sign");
131 return false;
134 uno::Reference<io::XStream> xStream(xInputStream, uno::UNO_QUERY);
135 std::unique_ptr<SvStream> pOutStream(utl::UcbStreamHelper::CreateStream(xStream, true));
136 if (!aDocument.Write(*pOutStream))
138 SAL_WARN("xmlsecurity.helper", "failed to write signed data");
139 return false;
142 return true;
145 bool PDFSignatureHelper::RemoveSignature(const uno::Reference<io::XInputStream>& xInputStream, sal_uInt16 nPosition)
147 std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
148 vcl::filter::PDFDocument aDocument;
149 if (!aDocument.Read(*pStream))
151 SAL_WARN("xmlsecurity.helper", "failed to read the document");
152 return false;
155 if (!aDocument.RemoveSignature(nPosition))
157 SAL_WARN("xmlsecurity.helper", "failed to remove signature");
158 return false;
161 uno::Reference<io::XStream> xStream(xInputStream, uno::UNO_QUERY);
162 uno::Reference<io::XTruncate> xTruncate(xStream, uno::UNO_QUERY);
163 if (!xTruncate.is())
165 SAL_WARN("xmlsecurity.helper", "failed to truncate");
166 return false;
168 xTruncate->truncate();
169 std::unique_ptr<SvStream> pOutStream(utl::UcbStreamHelper::CreateStream(xStream, true));
170 if (!aDocument.Write(*pOutStream))
172 SAL_WARN("xmlsecurity.helper", "failed to write without signature");
173 return false;
176 return true;
179 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */