summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2021-03-31 13:58:28 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2021-03-31 14:19:35 +0200
commitf56348e0fd57f5a2d11dafb816217dfa6f0ca643 (patch)
tree23523570735c795133502c02c52fa3950d95453f
parented3eddce65aa42b0c203aeb3631cdd8daef9f8c4 (diff)
xmlsecurity nss: fix OOXML signing with ECDSA key
Reviewed-on: https://gerrit.libreoffice.org/54779 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> (cherry picked from commit 6b1b8ef51b752f9711d6581283d6c515d3c50d9b) Change-Id: Id2b59887fcd69e294a6d9db17ec0446615054ecc
-rw-r--r--xmlsecurity/qa/unit/signing/signing.cxx43
-rw-r--r--xmlsecurity/source/helper/ooxmlsecexporter.cxx10
-rw-r--r--xmlsecurity/source/helper/ooxmlsecparser.cxx7
3 files changed, 57 insertions, 3 deletions
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index 0cf7ed8cd637..6b71bb5b7990 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -73,6 +73,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.
@@ -131,6 +132,7 @@ public:
CPPUNIT_TEST_SUITE(SigningTest);
CPPUNIT_TEST(testDescription);
CPPUNIT_TEST(testECDSA);
+ CPPUNIT_TEST(testECDSAOOXML);
CPPUNIT_TEST(testODFGood);
CPPUNIT_TEST(testODFBroken);
CPPUNIT_TEST(testODFNo);
@@ -372,6 +374,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 942a3c0a4618..e27d0f5a06f8 100644
--- a/xmlsecurity/source/helper/ooxmlsecexporter.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
@@ -130,9 +130,13 @@ void OOXMLSecExporter::Impl::writeCanonicalizationTransform()
void OOXMLSecExporter::Impl::writeSignatureMethod()
{
rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
- pAttributeList->AddAttribute("Algorithm", ALGO_RSASHA256);
- m_xDocumentHandler->startElement(
- "SignatureMethod", uno::Reference<xml::sax::XAttributeList>(pAttributeList.get()));
+
+ 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 e329b8d35176..3a9b04fe3691 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");