diff --git a/include/svl/cryptosign.hxx b/include/svl/cryptosign.hxx index a558690bbf48..a547036813c1 100644 --- a/include/svl/cryptosign.hxx +++ b/include/svl/cryptosign.hxx @@ -39,6 +39,7 @@ class SvStream; struct SignatureInformation; namespace svl::crypto { +class SigningContext; /// Converts a hex-encoded string into a byte array. SVL_DLLPUBLIC std::vector DecodeHexString(std::string_view rHex); @@ -49,8 +50,8 @@ class SVL_DLLPUBLIC Signing { public: - Signing(css::uno::Reference xCertificate) : - m_xCertificate(std::move(xCertificate)) + Signing(svl::crypto::SigningContext& rSigningContext) : + m_rSigningContext(rSigningContext) { } @@ -84,7 +85,7 @@ public: private: /// The certificate to use for signing. - const css::uno::Reference m_xCertificate; + svl::crypto::SigningContext& m_rSigningContext; /// Data blocks (pointer-size pairs). std::vector> m_dataBlocks; @@ -99,7 +100,8 @@ class SVL_DLLPUBLIC SigningContext public: /// If set, the certificate used for signing. css::uno::Reference m_xCertificate; - /// If m_xCertificate is not set, the time that would be used. + /// If m_xCertificate is not set, the time that would be used, in milliseconds since the epoch + /// (1970-01-01 UTC). sal_Int64 m_nSignatureTime = 0; }; diff --git a/include/vcl/filter/pdfdocument.hxx b/include/vcl/filter/pdfdocument.hxx index 05e471e65e01..32850c3ddc00 100644 --- a/include/vcl/filter/pdfdocument.hxx +++ b/include/vcl/filter/pdfdocument.hxx @@ -35,6 +35,10 @@ namespace tools { class Rectangle; } +namespace svl::crypto +{ +class SigningContext; +} namespace vcl::filter { @@ -588,8 +592,8 @@ public: void SetSignatureLine(std::vector&& rSignatureLine); void SetSignaturePage(size_t nPage); /// Sign the read document with xCertificate in the edit buffer. - bool Sign(const css::uno::Reference& xCertificate, - const OUString& rDescription, bool bAdES); + bool Sign(svl::crypto::SigningContext& rSigningContext, const OUString& rDescription, + bool bAdES); /// Serializes the contents of the edit buffer. bool Write(SvStream& rStream); /// Get a list of signatures embedded into this document. diff --git a/sfx2/qa/cppunit/data/unsigned.pdf b/sfx2/qa/cppunit/data/unsigned.pdf new file mode 100644 index 000000000000..64a29a593d16 Binary files /dev/null and b/sfx2/qa/cppunit/data/unsigned.pdf differ diff --git a/sfx2/qa/cppunit/view.cxx b/sfx2/qa/cppunit/view.cxx index 91dc6703595b..4c8e47582643 100644 --- a/sfx2/qa/cppunit/view.cxx +++ b/sfx2/qa/cppunit/view.cxx @@ -9,6 +9,8 @@ #include +#include + #include #include @@ -21,6 +23,7 @@ #include #include #include +#include using namespace com::sun::star; @@ -109,6 +112,28 @@ CPPUNIT_TEST_FIXTURE(Sfx2ViewTest, testLokHelperAddCertifices) // i.e. the signature status for an opened document was not updated when trusting a CA. CPPUNIT_ASSERT_EQUAL(SignatureState::OK, pObjectShell->GetDocumentSignatureState()); } + +CPPUNIT_TEST_FIXTURE(Sfx2ViewTest, testLokHelperCommandValuesSignature) +{ + // Given an unsigned PDF file: + loadFromFile(u"unsigned.pdf"); + + // When extracting hashes: + tools::JsonWriter aWriter; + SfxLokHelper::getCommandValues(aWriter, ".uno:Signature"); + OString aJson = aWriter.finishAndGetAsOString(); + + // Then make sure that we get a signature time: + CPPUNIT_ASSERT(SfxLokHelper::supportsCommand(u"Signature")); + std::stringstream aStream{ std::string(aJson) }; + boost::property_tree::ptree aTree; + boost::property_tree::read_json(aStream, aTree); + // Non-zero timestamp: + auto it = aTree.find("signatureTime"); + CPPUNIT_ASSERT(it != aTree.not_found()); + auto nSignatureTime = it->second.get_value(); + CPPUNIT_ASSERT(nSignatureTime != 0); +} #endif CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx index 7b410b38b32d..c3a73d43290a 100644 --- a/svl/source/crypto/cryptosign.cxx +++ b/svl/source/crypto/cryptosign.cxx @@ -950,22 +950,18 @@ bool Signing::Sign(OStringBuffer& rCMSHexBuffer) return false; #else // Create the PKCS#7 object. - css::uno::Sequence aDerEncoded = m_xCertificate->getEncoded(); - if (!aDerEncoded.hasElements()) + css::uno::Sequence aDerEncoded; + if (m_rSigningContext.m_xCertificate.is()) { - SAL_WARN("svl.crypto", "Crypto::Signing: empty certificate"); - return false; + aDerEncoded = m_rSigningContext.m_xCertificate->getEncoded(); + if (!aDerEncoded.hasElements()) + { + SAL_WARN("svl.crypto", "Crypto::Signing: empty certificate"); + return false; + } } #if USE_CRYPTO_NSS - CERTCertificate *cert = CERT_DecodeCertFromPackage(reinterpret_cast(aDerEncoded.getArray()), aDerEncoded.getLength()); - - if (!cert) - { - SAL_WARN("svl.crypto", "CERT_DecodeCertFromPackage failed"); - return false; - } - std::vector aHashResult; { comphelper::Hash aHash(comphelper::HashType::SHA256); @@ -980,6 +976,24 @@ bool Signing::Sign(OStringBuffer& rCMSHexBuffer) digest.len = aHashResult.size(); PRTime now = PR_Now(); + + if (!m_rSigningContext.m_xCertificate.is()) + { + // The context unit is milliseconds, PR_Now() unit is microseconds. + m_rSigningContext.m_nSignatureTime = now / 1000; + // No certificate is provided: don't actually sign -- just update the context with the + // parameters for the signing and return. + return false; + } + + CERTCertificate *cert = CERT_DecodeCertFromPackage(reinterpret_cast(aDerEncoded.getArray()), aDerEncoded.getLength()); + + if (!cert) + { + SAL_WARN("svl.crypto", "CERT_DecodeCertFromPackage failed"); + return false; + } + NSSCMSSignedData *cms_sd(nullptr); NSSCMSSignerInfo *cms_signer(nullptr); NSSCMSMessage *cms_msg = CreateCMSMessage(nullptr, &cms_sd, &cms_signer, cert, &digest); diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx index bc14b129e81d..f3efc8a03015 100644 --- a/sw/source/core/edit/edfcol.cxx +++ b/sw/source/core/edit/edfcol.cxx @@ -1789,7 +1789,9 @@ void SwEditShell::SignParagraph() return; // 3. Sign it. - svl::crypto::Signing signing(xCertificate); + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + svl::crypto::Signing signing(aSigningContext); signing.AddDataRange(utf8Text.getStr(), utf8Text.getLength()); OStringBuffer sigBuf; if (!signing.Sign(sigBuf)) diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx index b0547a01ac25..3842b0c3baaa 100644 --- a/vcl/source/filter/ipdf/pdfdocument.cxx +++ b/vcl/source/filter/ipdf/pdfdocument.cxx @@ -855,8 +855,8 @@ void PDFDocument::WriteXRef(sal_uInt64 nXRefOffset, PDFReferenceElement const* p } } -bool PDFDocument::Sign(const uno::Reference& xCertificate, - const OUString& rDescription, bool bAdES) +bool PDFDocument::Sign(svl::crypto::SigningContext& rSigningContext, const OUString& rDescription, + bool bAdES) { m_aEditBuffer.Seek(STREAM_SEEK_TO_END); m_aEditBuffer.WriteOString("\n"); @@ -923,11 +923,14 @@ bool PDFDocument::Sign(const uno::Reference& xCertificat m_aEditBuffer.WriteOString(aByteRangeBuffer); // Create the PKCS#7 object. - css::uno::Sequence aDerEncoded = xCertificate->getEncoded(); - if (!aDerEncoded.hasElements()) + if (rSigningContext.m_xCertificate) { - SAL_WARN("vcl.filter", "PDFDocument::Sign: empty certificate"); - return false; + css::uno::Sequence aDerEncoded = rSigningContext.m_xCertificate->getEncoded(); + if (!aDerEncoded.hasElements()) + { + SAL_WARN("vcl.filter", "PDFDocument::Sign: empty certificate"); + return false; + } } m_aEditBuffer.Seek(0); @@ -941,12 +944,15 @@ bool PDFDocument::Sign(const uno::Reference& xCertificat m_aEditBuffer.ReadBytes(aBuffer2.get(), nBufferSize2); OStringBuffer aCMSHexBuffer; - svl::crypto::Signing aSigning(xCertificate); + svl::crypto::Signing aSigning(rSigningContext); aSigning.AddDataRange(aBuffer1.get(), nBufferSize1); aSigning.AddDataRange(aBuffer2.get(), nBufferSize2); if (!aSigning.Sign(aCMSHexBuffer)) { - SAL_WARN("vcl.filter", "PDFDocument::Sign: PDFWriter::Sign() failed"); + if (rSigningContext.m_xCertificate.is()) + { + SAL_WARN("vcl.filter", "PDFDocument::Sign: PDFWriter::Sign() failed"); + } return false; } diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index d29659aa5b42..3dc4ada0e210 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -5727,7 +5727,9 @@ bool PDFWriterImpl::finalizeSignature() } OStringBuffer aCMSHexBuffer; - svl::crypto::Signing aSigning(m_aContext.SignCertificate); + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = m_aContext.SignCertificate; + svl::crypto::Signing aSigning(aSigningContext); aSigning.AddDataRange(buffer1.get(), bytesRead1); aSigning.AddDataRange(buffer2.get(), bytesRead2); aSigning.SetSignTSA(m_aContext.SignTSA); diff --git a/xmlsecurity/CppunitTest_xmlsecurity_pdfsigning.mk b/xmlsecurity/CppunitTest_xmlsecurity_pdfsigning.mk index 667acc97e3e1..faf6944a0773 100644 --- a/xmlsecurity/CppunitTest_xmlsecurity_pdfsigning.mk +++ b/xmlsecurity/CppunitTest_xmlsecurity_pdfsigning.mk @@ -22,6 +22,7 @@ $(eval $(call gb_CppunitTest_use_libraries,xmlsecurity_pdfsigning, \ sal \ sax \ sfx \ + svl \ test \ tl \ unotest \ diff --git a/xmlsecurity/Executable_pdfverify.mk b/xmlsecurity/Executable_pdfverify.mk index ed8e9559fc18..8efbd84aa1d6 100644 --- a/xmlsecurity/Executable_pdfverify.mk +++ b/xmlsecurity/Executable_pdfverify.mk @@ -23,6 +23,7 @@ $(eval $(call gb_Executable_use_libraries,pdfverify,\ cppu \ cppuhelper \ sal \ + svl \ tl \ vcl \ xmlsecurity \ diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx index 56597106f9c1..3cf2151883d8 100644 --- a/xmlsecurity/inc/documentsignaturemanager.hxx +++ b/xmlsecurity/inc/documentsignaturemanager.hxx @@ -53,6 +53,10 @@ namespace uno class XComponentContext; } } +namespace svl::crypto +{ +class SigningContext; +} class PDFSignatureHelper; class Xmlsec; @@ -93,7 +97,7 @@ public: SignatureStreamHelper ImplOpenSignatureStream(sal_Int32 nStreamOpenMode, bool bTempStream); /// Add a new signature, using xCert as a signing certificate, and rDescription as description. - bool add(const css::uno::Reference& xCert, + bool add(svl::crypto::SigningContext& rSigningContext, const css::uno::Reference& xSecurityContext, const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant, const OUString& rSignatureLineId = OUString(), diff --git a/xmlsecurity/inc/pdfsignaturehelper.hxx b/xmlsecurity/inc/pdfsignaturehelper.hxx index ea24685d2ae4..a20598131db1 100644 --- a/xmlsecurity/inc/pdfsignaturehelper.hxx +++ b/xmlsecurity/inc/pdfsignaturehelper.hxx @@ -37,6 +37,10 @@ namespace xml::crypto class XSecurityEnvironment; } } +namespace svl::crypto +{ +class SigningContext; +} class SvStream; /// Handles signatures of a PDF file. @@ -44,7 +48,7 @@ class XMLSECURITY_DLLPUBLIC PDFSignatureHelper { SignatureInformations m_aSignatureInfos; - css::uno::Reference m_xCertificate; + svl::crypto::SigningContext* m_pSigningContext = nullptr; OUString m_aDescription; public: @@ -59,7 +63,7 @@ public: /// Return the ID of the next created signature. sal_Int32 GetNewSecurityId() const; /// Certificate to be used next time signing is performed. - void SetX509Certificate(const css::uno::Reference& xCertificate); + void SetX509Certificate(svl::crypto::SigningContext& rSigningContext); /// Comment / reason to be used next time signing is performed. void SetDescription(const OUString& rDescription); /// Append a new signature at the end of xInputStream. diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx index a43cec683fd9..36a5a3d19a9b 100644 --- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx +++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -136,7 +137,9 @@ bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL, // Only try certificates that are already active and not expired if (IsValid(cert, xSecurityEnvironment)) { - bool bSignResult = aDocument.Sign(cert, u"test"_ustr, /*bAdES=*/true); + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = cert; + bool bSignResult = aDocument.Sign(aSigningContext, u"test"_ustr, /*bAdES=*/true); #ifdef _WIN32 if (!bSignResult) { diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx index dbee1cba4587..0a22681fb9a0 100644 --- a/xmlsecurity/qa/unit/signing/signing.cxx +++ b/xmlsecurity/qa/unit/signing/signing.cxx @@ -159,7 +159,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testDescription) return; OUString aDescription(u"SigningTest::testDescription"_ustr); sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, false); + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, aDescription, nSecurityId, false); // Read back the signature and make sure that the description survives the roundtrip. aManager.read(/*bUseTempStream=*/true); @@ -190,7 +192,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testECDSA) if (!xCertificate.is()) return; sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId, false); + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId, false); // Read back the signature and make sure that it's valid. aManager.read(/*bUseTempStream=*/true); @@ -224,7 +228,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testECDSAOOXML) if (!xCertificate.is()) return; sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId, + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId, /*bAdESCompliant=*/false); // Read back the signature and make sure that it's valid. @@ -259,7 +265,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testECDSAPDF) if (!xCertificate.is()) return; sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId, + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId, /*bAdESCompliant=*/true); // Read back the signature and make sure that it's valid. @@ -301,7 +309,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testOOXMLDescription) return; OUString aDescription(u"SigningTest::testDescription"_ustr); sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, false); + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, aDescription, nSecurityId, false); // Read back the signature and make sure that the description survives the roundtrip. aManager.read(/*bUseTempStream=*/true); @@ -334,7 +344,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testOOXMLAppend) if (!xCertificate.is()) return; sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, OUString(), nSecurityId, false); + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, OUString(), nSecurityId, false); // Read back the signatures and make sure that we have the expected amount. aManager.read(/*bUseTempStream=*/true); @@ -860,7 +872,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testXAdESNotype) if (!xCertificate.is()) return; sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, /*bAdESCompliant=*/true); // Write to storage. @@ -915,7 +929,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testXAdES) if (!xCertificate.is()) return; sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, /*bAdESCompliant=*/true); // Write to storage. @@ -969,7 +985,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_ODT) if (!xCertificate.is()) return; sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, /*bAdESCompliant=*/true); // Read back the signature and make sure that it's valid. @@ -982,7 +1000,7 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_ODT) rInformations[0].nStatus); } - aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, + aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, /*bAdESCompliant=*/true); aManager.read(/*bUseTempStream=*/true); { @@ -993,7 +1011,7 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_ODT) rInformations[1].nStatus); } - aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, + aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, /*bAdESCompliant=*/true); aManager.read(/*bUseTempStream=*/true); { @@ -1042,7 +1060,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML) return; sal_Int32 nSecurityId; - aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId, + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId, /*bAdESCompliant=*/false); aManager.read(/*bUseTempStream=*/true); { @@ -1053,7 +1073,7 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML) rInformations[0].nStatus); } - aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId, + aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId, /*bAdESCompliant=*/false); aManager.read(/*bUseTempStream=*/true); { @@ -1064,7 +1084,7 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML) rInformations[1].nStatus); } - aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId, + aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId, /*bAdESCompliant=*/false); aManager.read(/*bUseTempStream=*/true); { @@ -1191,11 +1211,14 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testImplicitScriptSign) OUString aDescription; sal_Int32 nSecurityId; bool bAdESCompliant = true; - aScriptManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, bAdESCompliant); + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + aScriptManager.add(aSigningContext, mxSecurityContext, aDescription, nSecurityId, + bAdESCompliant); aScriptManager.read(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false); aScriptManager.write(bAdESCompliant); aManager.setScriptingSignatureStream(xScriptingStream); - aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, bAdESCompliant); + aManager.add(aSigningContext, mxSecurityContext, aDescription, nSecurityId, bAdESCompliant); aManager.read(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false); aManager.write(bAdESCompliant); diff --git a/xmlsecurity/qa/xmlsec/xmlsec.cxx b/xmlsecurity/qa/xmlsec/xmlsec.cxx index d36bce860e0e..cc24b7e4db58 100644 --- a/xmlsecurity/qa/xmlsec/xmlsec.cxx +++ b/xmlsecurity/qa/xmlsec/xmlsec.cxx @@ -14,6 +14,7 @@ #include #include +#include #include @@ -83,7 +84,10 @@ CPPUNIT_TEST_FIXTURE(Test, testInsertPrivateKey) xSecurityEnvironment->getCertificateCharacters(xCertificate); OUString aDescription; sal_Int32 nSecurityId; - CPPUNIT_ASSERT(aManager.add(xCertificate, xSecurityContext, aDescription, nSecurityId, false)); + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + CPPUNIT_ASSERT( + aManager.add(aSigningContext, xSecurityContext, aDescription, nSecurityId, false)); // Then make sure that signing succeeds: aManager.read(/*bUseTempStream=*/true); diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx index bff14dd61a8a..541748fc7c73 100644 --- a/xmlsecurity/source/component/documentdigitalsignatures.cxx +++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx @@ -297,7 +297,9 @@ sal_Bool DocumentDigitalSignatures::signSignatureLine( xSecurityContext = aSignatureManager.getSecurityContext(); sal_Int32 nSecurityId; - bool bSuccess = aSignatureManager.add(xCertificate, xSecurityContext, aComment, nSecurityId, + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = xCertificate; + bool bSuccess = aSignatureManager.add(aSigningContext, xSecurityContext, aComment, nSecurityId, true, aSignatureLineId, xValidGraphic, xInvalidGraphic); if (!bSuccess) return false; @@ -852,7 +854,7 @@ bool DocumentDigitalSignatures::signWithCertificateImpl( sal_Int32 nSecurityId; - bool bSuccess = aSignatureManager.add(rSigningContext.m_xCertificate, xSecurityContext, u""_ustr, nSecurityId, true); + bool bSuccess = aSignatureManager.add(rSigningContext, xSecurityContext, u""_ustr, nSecurityId, true); if (!bSuccess) return false; diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx index c7193e4c1b8f..aa4bfec4664b 100644 --- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx +++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx @@ -53,6 +53,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -510,9 +511,11 @@ void DigitalSignaturesDialog::AddButtonHdlImpl() { sal_Int32 nSecurityId; + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = aChooser->GetSelectedCertificates()[0]; if (moScriptSignatureManager) { - if (!moScriptSignatureManager->add(aChooser->GetSelectedCertificates()[0], + if (!moScriptSignatureManager->add(aSigningContext, aChooser->GetSelectedSecurityContext(), aChooser->GetDescription(), nSecurityId, m_bAdESCompliant)) @@ -526,7 +529,7 @@ void DigitalSignaturesDialog::AddButtonHdlImpl() maSignatureManager.setScriptingSignatureStream(moScriptSignatureManager->getSignatureStream()); } - if (!maSignatureManager.add(aChooser->GetSelectedCertificates()[0], aChooser->GetSelectedSecurityContext(), + if (!maSignatureManager.add(aSigningContext, aChooser->GetSelectedSecurityContext(), aChooser->GetDescription(), nSecurityId, m_bAdESCompliant)) return; mbSignaturesChanged = true; diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx index d74c9a12f900..2a4be54594f5 100644 --- a/xmlsecurity/source/helper/documentsignaturemanager.cxx +++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -327,20 +328,23 @@ SignatureStreamHelper DocumentSignatureManager::ImplOpenSignatureStream(sal_Int3 } bool DocumentSignatureManager::add( - const uno::Reference& xCert, + svl::crypto::SigningContext& rSigningContext, const uno::Reference& xSecurityContext, const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant, const OUString& rSignatureLineId, const Reference& xValidGraphic, const Reference& xInvalidGraphic) { - if (!xCert.is()) + uno::Reference xCert = rSigningContext.m_xCertificate; + uno::Reference xServiceInfo(xSecurityContext, uno::UNO_QUERY); + if (!xCert.is() + && xServiceInfo->getImplementationName() + == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl") { SAL_WARN("xmlsecurity.helper", "no certificate selected"); return false; } // GPG or X509 key? - uno::Reference xServiceInfo(xSecurityContext, uno::UNO_QUERY); if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl") { @@ -374,6 +378,24 @@ bool DocumentSignatureManager::add( } else { + if (!mxStore.is()) + { + // Something not ZIP based, try PDF. + nSecurityId = getPDFSignatureHelper().GetNewSecurityId(); + getPDFSignatureHelper().SetX509Certificate(rSigningContext); + getPDFSignatureHelper().SetDescription(rDescription); + uno::Reference xInputStream(mxSignatureStream, uno::UNO_QUERY); + if (!getPDFSignatureHelper().Sign(mxModel, xInputStream, bAdESCompliant)) + { + if (rSigningContext.m_xCertificate.is()) + { + SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::Sign() failed"); + } + return false; + } + return true; + } + OUString aCertSerial = xmlsecurity::bigIntegerToNumericString(xCert->getSerialNumber()); if (aCertSerial.isEmpty()) { @@ -381,21 +403,6 @@ bool DocumentSignatureManager::add( return false; } - if (!mxStore.is()) - { - // Something not ZIP based, try PDF. - nSecurityId = getPDFSignatureHelper().GetNewSecurityId(); - getPDFSignatureHelper().SetX509Certificate(xCert); - getPDFSignatureHelper().SetDescription(rDescription); - uno::Reference xInputStream(mxSignatureStream, uno::UNO_QUERY); - if (!getPDFSignatureHelper().Sign(mxModel, xInputStream, bAdESCompliant)) - { - SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::Sign() failed"); - return false; - } - return true; - } - maSignatureHelper.StartMission(xSecurityContext); nSecurityId = maSignatureHelper.GetNewSecurityId(); diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx b/xmlsecurity/source/helper/pdfsignaturehelper.cxx index 9927f8773d8a..79ee45c0e3c3 100644 --- a/xmlsecurity/source/helper/pdfsignaturehelper.cxx +++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx @@ -536,10 +536,9 @@ PDFSignatureHelper::GetDocumentSignatureInformations( sal_Int32 PDFSignatureHelper::GetNewSecurityId() const { return m_aSignatureInfos.size(); } -void PDFSignatureHelper::SetX509Certificate( - const uno::Reference& xCertificate) +void PDFSignatureHelper::SetX509Certificate(svl::crypto::SigningContext& rSigningContext) { - m_xCertificate = xCertificate; + m_pSigningContext = &rSigningContext; } void PDFSignatureHelper::SetDescription(const OUString& rDescription) @@ -571,9 +570,12 @@ bool PDFSignatureHelper::Sign(const uno::Reference& xModel, aDocument.SetSignatureLine(std::move(aSignatureLineShape)); } - if (!aDocument.Sign(m_xCertificate, m_aDescription, bAdES)) + if (!m_pSigningContext || !aDocument.Sign(*m_pSigningContext, m_aDescription, bAdES)) { - SAL_WARN("xmlsecurity.helper", "failed to sign"); + if (m_pSigningContext && m_pSigningContext->m_xCertificate.is()) + { + SAL_WARN("xmlsecurity.helper", "failed to sign"); + } return false; } diff --git a/xmlsecurity/workben/pdfverify.cxx b/xmlsecurity/workben/pdfverify.cxx index 9acabc2d3766..09ac89ab4705 100644 --- a/xmlsecurity/workben/pdfverify.cxx +++ b/xmlsecurity/workben/pdfverify.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -183,7 +184,9 @@ int pdfVerify(int nArgc, char** pArgv) SAL_WARN("xmlsecurity.workben", "no signing certificates found"); return 1; } - if (!aDocument.Sign(aCertificates[0], u"pdfverify"_ustr, /*bAdES=*/true)) + svl::crypto::SigningContext aSigningContext; + aSigningContext.m_xCertificate = aCertificates[0]; + if (!aDocument.Sign(aSigningContext, u"pdfverify"_ustr, /*bAdES=*/true)) { SAL_WARN("xmlsecurity.workben", "failed to sign"); return 1;