diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2018-05-24 21:03:24 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2018-05-25 08:44:36 +0200 |
commit | 6b1b8ef51b752f9711d6581283d6c515d3c50d9b (patch) | |
tree | 7c58b1e283e131d80c68453bef4020665c014c96 | |
parent | 8628b4aeabd83b98edac5d537cd3901d22cf0c54 (diff) |
xmlsecurity nss: fix OOXML signing with ECDSA key
Change-Id: Id2b59887fcd69e294a6d9db17ec0446615054ecc
Reviewed-on: https://gerrit.libreoffice.org/54779
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
-rw-r--r-- | xmlsecurity/qa/unit/signing/signing.cxx | 43 | ||||
-rw-r--r-- | xmlsecurity/source/helper/ooxmlsecexporter.cxx | 7 | ||||
-rw-r--r-- | xmlsecurity/source/helper/ooxmlsecparser.cxx | 7 |
3 files changed, 56 insertions, 1 deletions
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx index 31382925a092..7e326f2467bf 100644 --- a/xmlsecurity/qa/unit/signing/signing.cxx +++ b/xmlsecurity/qa/unit/signing/signing.cxx @@ -66,6 +66,7 @@ public: void testDescription(); void testECDSA(); + void testECDSAOOXML(); /// Test a typical ODF where all streams are signed. void testODFGood(); /// Test a typical broken ODF signature where one stream is corrupted. @@ -116,6 +117,7 @@ public: CPPUNIT_TEST_SUITE(SigningTest); CPPUNIT_TEST(testDescription); CPPUNIT_TEST(testECDSA); + CPPUNIT_TEST(testECDSAOOXML); CPPUNIT_TEST(testODFGood); CPPUNIT_TEST(testODFBroken); CPPUNIT_TEST(testODFNo); @@ -303,6 +305,47 @@ void SigningTest::testECDSA() CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED, rInformations[0].nStatus); } +void SigningTest::testECDSAOOXML() +{ + // Create an empty document and store it to a tempfile, finally load it as a storage. + createDoc(""); + + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= OUString("MS Word 2007 XML"); + xStorable->storeAsURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + + DocumentSignatureManager aManager(mxComponentContext, DocumentSignatureMode::Content); + CPPUNIT_ASSERT(aManager.init()); + uno::Reference<embed::XStorage> xStorage + = comphelper::OStorageHelper::GetStorageOfFormatFromURL( + ZIP_STORAGE_FORMAT_STRING, aTempFile.GetURL(), embed::ElementModes::READWRITE); + CPPUNIT_ASSERT(xStorage.is()); + aManager.mxStore = xStorage; + aManager.maSignatureHelper.SetStorage(xStorage, "1.2"); + + // Then add a document signature. + uno::Reference<security::XCertificate> xCertificate + = getCertificate(aManager, svl::crypto::SignatureMethodAlgorithm::ECDSA); + if (!xCertificate.is()) + return; + OUString aDescription; + sal_Int32 nSecurityId; + aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, + /*bAdESCompliant=*/false); + + // Read back the signature and make sure that it's valid. + aManager.read(/*bUseTempStream=*/true); + std::vector<SignatureInformation>& rInformations = aManager.maCurrentSignatureInformations; + CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), rInformations.size()); + // This was SecurityOperationStatus_UNKNOWN, signing with an ECDSA key was + // broken. + CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED, + rInformations[0].nStatus); +} + void SigningTest::testOOXMLDescription() { // Create an empty document and store it to a tempfile, finally load it as a storage. diff --git a/xmlsecurity/source/helper/ooxmlsecexporter.cxx b/xmlsecurity/source/helper/ooxmlsecexporter.cxx index 7d177c8dda15..abb0a648b520 100644 --- a/xmlsecurity/source/helper/ooxmlsecexporter.cxx +++ b/xmlsecurity/source/helper/ooxmlsecexporter.cxx @@ -130,7 +130,12 @@ void OOXMLSecExporter::Impl::writeCanonicalizationTransform() void OOXMLSecExporter::Impl::writeSignatureMethod() { rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList()); - pAttributeList->AddAttribute("Algorithm", ALGO_RSASHA256); + + if (m_rInformation.eAlgorithmID == svl::crypto::SignatureMethodAlgorithm::ECDSA) + pAttributeList->AddAttribute("Algorithm", ALGO_ECDSASHA256); + else + pAttributeList->AddAttribute("Algorithm", ALGO_RSASHA256); + m_xDocumentHandler->startElement("SignatureMethod", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get())); m_xDocumentHandler->endElement("SignatureMethod"); } diff --git a/xmlsecurity/source/helper/ooxmlsecparser.cxx b/xmlsecurity/source/helper/ooxmlsecparser.cxx index cb5334cc8a59..2128c5108c1c 100644 --- a/xmlsecurity/source/helper/ooxmlsecparser.cxx +++ b/xmlsecurity/source/helper/ooxmlsecparser.cxx @@ -60,6 +60,13 @@ void SAL_CALL OOXMLSecParser::startElement(const OUString& rName, const uno::Ref if (!aId.isEmpty()) m_pXSecController->setId(aId); } + else if (rName == "SignatureMethod") + { + OUString ouAlgorithm = xAttribs->getValueByName("Algorithm"); + if (ouAlgorithm == ALGO_ECDSASHA1 || ouAlgorithm == ALGO_ECDSASHA256 + || ouAlgorithm == ALGO_ECDSASHA512) + m_pXSecController->setSignatureMethod(svl::crypto::SignatureMethodAlgorithm::ECDSA); + } else if (rName == "Reference") { OUString aURI = xAttribs->getValueByName("URI"); |