summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2021-11-01 21:46:43 +0100
committerXisco Fauli <xiscofauli@libreoffice.org>2021-11-02 21:10:50 +0100
commitb8ae4bcd5c642a29202529fc6bf4c3a91a713230 (patch)
tree04e3e6ce1d6487be243f6d9907cfbe900b5b707b
parenttdf#145361 fix XSLT for older libxslt (diff)
downloadcore-b8ae4bcd5c642a29202529fc6bf4c3a91a713230.tar.gz
core-b8ae4bcd5c642a29202529fc6bf4c3a91a713230.zip
xmlsec: fix OOXML signing with multiple certs, extend the test
Signing OOXML with 3 or more times didn't work as other ids ("idPackageObject", "idOfficeObject", ...) were not uniqe. This change makes those ids unique by appending the signature id. The signature ID is now generated for OOXML too, while previously it was a hardcoded string ("idPackageSignature"). The test for signing multiple OOXML was written before, but didn't catch the issues because it didn't assert the status of the document after loading it again. This is which is now fixed (and also added changed for the ODF test case). Change-Id: Ifa20ea17498b117a4c57f6eddf82f8e83bc640bc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124571 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> (cherry picked from commit 5a7030f5cea26019aa8ff921f6035cfa0e3f93db) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124480 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r--xmlsecurity/qa/unit/signing/signing.cxx209
-rw-r--r--xmlsecurity/source/helper/ooxmlsecexporter.cxx53
-rw-r--r--xmlsecurity/source/helper/xsecsign.cxx10
3 files changed, 153 insertions, 119 deletions
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index 293e938863c4..24101ab74e22 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -60,6 +60,7 @@
#include <sfx2/viewsh.hxx>
#include <comphelper/propertyvalue.hxx>
#include <vcl/filter/PDFiumLibrary.hxx>
+#include <vcl/scheduler.hxx>
using namespace com::sun::star;
@@ -1061,55 +1062,72 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_ODT)
aMediaDescriptor["FilterName"] <<= OUString("writer8");
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.setStore(xStorage);
- aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
-
- // Create a signature.
- uno::Reference<security::XCertificate> xCertificate
- = getCertificate(aManager, svl::crypto::SignatureMethodAlgorithm::RSA);
- if (!xCertificate.is())
- return;
- sal_Int32 nSecurityId;
- aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
- /*bAdESCompliant=*/true);
-
- // Read back the signature and make sure that it's valid.
- aManager.read(/*bUseTempStream=*/true);
{
- std::vector<SignatureInformation>& rInformations
- = aManager.getCurrentSignatureInformations();
- CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), rInformations.size());
- CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
- rInformations[0].nStatus);
+ 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.setStore(xStorage);
+ aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
+
+ // Create a signature.
+ uno::Reference<security::XCertificate> xCertificate
+ = getCertificate(aManager, svl::crypto::SignatureMethodAlgorithm::RSA);
+
+ if (!xCertificate.is())
+ return;
+ sal_Int32 nSecurityId;
+ aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
+ /*bAdESCompliant=*/true);
+
+ // Read back the signature and make sure that it's valid.
+ aManager.read(/*bUseTempStream=*/true);
+ {
+ std::vector<SignatureInformation>& rInformations
+ = aManager.getCurrentSignatureInformations();
+ CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), rInformations.size());
+ CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+ rInformations[0].nStatus);
+ }
+
+ aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
+ /*bAdESCompliant=*/true);
+ aManager.read(/*bUseTempStream=*/true);
+ {
+ std::vector<SignatureInformation>& rInformations
+ = aManager.getCurrentSignatureInformations();
+ CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), rInformations.size());
+ CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+ rInformations[1].nStatus);
+ }
+
+ aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
+ /*bAdESCompliant=*/true);
+ aManager.read(/*bUseTempStream=*/true);
+ {
+ std::vector<SignatureInformation>& rInformations
+ = aManager.getCurrentSignatureInformations();
+ CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), rInformations.size());
+ CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+ rInformations[2].nStatus);
+ }
+
+ aManager.write(/*bXAdESCompliantIfODF=*/true);
+ uno::Reference<embed::XTransactedObject> xTransactedObject(xStorage, uno::UNO_QUERY);
+ xTransactedObject->commit();
}
- aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
- /*bAdESCompliant=*/true);
- aManager.read(/*bUseTempStream=*/true);
- {
- std::vector<SignatureInformation>& rInformations
- = aManager.getCurrentSignatureInformations();
- CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), rInformations.size());
- CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
- rInformations[1].nStatus);
- }
+ Scheduler::ProcessEventsToIdle();
- aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
- /*bAdESCompliant=*/true);
- aManager.read(/*bUseTempStream=*/true);
- {
- std::vector<SignatureInformation>& rInformations
- = aManager.getCurrentSignatureInformations();
- CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), rInformations.size());
- CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
- rInformations[2].nStatus);
- }
+ createDoc(aTempFile.GetURL());
+
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ CPPUNIT_ASSERT_EQUAL(SignatureState::OK, pObjectShell->GetDocumentSignatureState());
}
CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML)
@@ -1123,54 +1141,67 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML)
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.setStore(xStorage);
- aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
-
- // Create a signature.
- uno::Reference<security::XCertificate> xCertificate
- = getCertificate(aManager, svl::crypto::SignatureMethodAlgorithm::ECDSA);
- if (!xCertificate.is())
- return;
-
- sal_Int32 nSecurityId;
- aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, /*bAdESCompliant=*/false);
- aManager.read(/*bUseTempStream=*/true);
{
- std::vector<SignatureInformation>& rInformations
- = aManager.getCurrentSignatureInformations();
- CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), rInformations.size());
- CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
- rInformations[0].nStatus);
+ 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.setStore(xStorage);
+ aManager.getSignatureHelper().SetStorage(xStorage, "1.2");
+
+ // Create a signature.
+ uno::Reference<security::XCertificate> xCertificate
+ = getCertificate(aManager, svl::crypto::SignatureMethodAlgorithm::ECDSA);
+ if (!xCertificate.is())
+ return;
+
+ sal_Int32 nSecurityId;
+ aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, /*bAdESCompliant=*/false);
+ aManager.read(/*bUseTempStream=*/true);
+ {
+ std::vector<SignatureInformation>& rInformations
+ = aManager.getCurrentSignatureInformations();
+ CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), rInformations.size());
+ CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+ rInformations[0].nStatus);
+ }
+
+ aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, /*bAdESCompliant=*/false);
+ aManager.read(/*bUseTempStream=*/true);
+ {
+ std::vector<SignatureInformation>& rInformations
+ = aManager.getCurrentSignatureInformations();
+ CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), rInformations.size());
+ CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+ rInformations[1].nStatus);
+ }
+
+ aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, /*bAdESCompliant=*/false);
+ aManager.read(/*bUseTempStream=*/true);
+ {
+ std::vector<SignatureInformation>& rInformations
+ = aManager.getCurrentSignatureInformations();
+ CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), rInformations.size());
+ CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
+ rInformations[2].nStatus);
+ }
+
+ aManager.write(/*bXAdESCompliantIfODF=*/true);
+ uno::Reference<embed::XTransactedObject> xTransactedObject(xStorage, uno::UNO_QUERY);
+ xTransactedObject->commit();
}
- aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, /*bAdESCompliant=*/false);
- aManager.read(/*bUseTempStream=*/true);
- {
- std::vector<SignatureInformation>& rInformations
- = aManager.getCurrentSignatureInformations();
- CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), rInformations.size());
- CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
- rInformations[1].nStatus);
- }
+ Scheduler::ProcessEventsToIdle();
- aManager.add(xCertificate, mxSecurityContext, "", nSecurityId, /*bAdESCompliant=*/false);
- aManager.read(/*bUseTempStream=*/true);
- {
- std::vector<SignatureInformation>& rInformations
- = aManager.getCurrentSignatureInformations();
- CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(3), rInformations.size());
- CPPUNIT_ASSERT_EQUAL(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED,
- rInformations[2].nStatus);
- }
- aManager.write(/*bXAdESCompliantIfODF=*/true);
- uno::Reference<embed::XTransactedObject> xTransactedObject(xStorage, uno::UNO_QUERY);
- xTransactedObject->commit();
+ createDoc(aTempFile.GetURL());
+
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ CPPUNIT_ASSERT_EQUAL(SignatureState::PARTIAL_OK, pObjectShell->GetDocumentSignatureState());
}
/// Works with an existing good XAdES signature.
diff --git a/xmlsecurity/source/helper/ooxmlsecexporter.cxx b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
index 443266b1a40a..a948f76bb425 100644
--- a/xmlsecurity/source/helper/ooxmlsecexporter.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
@@ -64,6 +64,7 @@ public:
return m_xDocumentHandler;
}
+ void writeSignature();
void writeSignedInfo();
void writeCanonicalizationMethod();
void writeCanonicalizationTransform();
@@ -222,7 +223,7 @@ void OOXMLSecExporter::Impl::writeKeyInfo()
void OOXMLSecExporter::Impl::writePackageObject()
{
rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
- pAttributeList->AddAttribute("Id", "idPackageObject");
+ pAttributeList->AddAttribute("Id", "idPackageObject_" + m_rInformation.ouSignatureId);
m_xDocumentHandler->startElement("Object",
uno::Reference<xml::sax::XAttributeList>(pAttributeList));
@@ -300,8 +301,8 @@ void OOXMLSecExporter::Impl::writePackageObjectSignatureProperties()
"SignatureProperties", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
{
rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
- pAttributeList->AddAttribute("Id", "idSignatureTime");
- pAttributeList->AddAttribute("Target", "#idPackageSignature");
+ pAttributeList->AddAttribute("Id", "idSignatureTime_" + m_rInformation.ouSignatureId);
+ pAttributeList->AddAttribute("Target", "#" + m_rInformation.ouSignatureId);
m_xDocumentHandler->startElement("SignatureProperty",
uno::Reference<xml::sax::XAttributeList>(pAttributeList));
}
@@ -380,7 +381,7 @@ void OOXMLSecExporter::Impl::writeOfficeObject()
{
{
rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
- pAttributeList->AddAttribute("Id", "idOfficeObject");
+ pAttributeList->AddAttribute("Id", "idOfficeObject_" + m_rInformation.ouSignatureId);
m_xDocumentHandler->startElement("Object",
uno::Reference<xml::sax::XAttributeList>(pAttributeList));
}
@@ -388,8 +389,8 @@ void OOXMLSecExporter::Impl::writeOfficeObject()
"SignatureProperties", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
{
rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
- pAttributeList->AddAttribute("Id", "idOfficeV1Details");
- pAttributeList->AddAttribute("Target", "#idPackageSignature");
+ pAttributeList->AddAttribute("Id", "idOfficeV1Details_" + m_rInformation.ouSignatureId);
+ pAttributeList->AddAttribute("Target", "#" + m_rInformation.ouSignatureId);
m_xDocumentHandler->startElement("SignatureProperty",
uno::Reference<xml::sax::XAttributeList>(pAttributeList));
}
@@ -477,7 +478,7 @@ void OOXMLSecExporter::Impl::writePackageSignature()
{
rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
pAttributeList->AddAttribute("xmlns:xd", NS_XD);
- pAttributeList->AddAttribute("Target", "#idPackageSignature");
+ pAttributeList->AddAttribute("Target", "#" + m_rInformation.ouSignatureId);
m_xDocumentHandler->startElement("xd:QualifyingProperties",
uno::Reference<xml::sax::XAttributeList>(pAttributeList));
}
@@ -519,6 +520,25 @@ void OOXMLSecExporter::Impl::writeSignatureLineImages()
m_xDocumentHandler->endElement("Object");
}
+void OOXMLSecExporter::Impl::writeSignature()
+{
+ rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
+ pAttributeList->AddAttribute("xmlns", NS_XMLDSIG);
+ pAttributeList->AddAttribute("Id", m_rInformation.ouSignatureId);
+ getDocumentHandler()->startElement("Signature",
+ uno::Reference<xml::sax::XAttributeList>(pAttributeList));
+
+ writeSignedInfo();
+ writeSignatureValue();
+ writeKeyInfo();
+ writePackageObject();
+ writeOfficeObject();
+ writePackageSignature();
+ writeSignatureLineImages();
+
+ getDocumentHandler()->endElement("Signature");
+}
+
OOXMLSecExporter::OOXMLSecExporter(
const uno::Reference<uno::XComponentContext>& xComponentContext,
const uno::Reference<embed::XStorage>& xRootStorage,
@@ -531,23 +551,6 @@ OOXMLSecExporter::OOXMLSecExporter(
OOXMLSecExporter::~OOXMLSecExporter() = default;
-void OOXMLSecExporter::writeSignature()
-{
- rtl::Reference<SvXMLAttributeList> pAttributeList(new SvXMLAttributeList());
- pAttributeList->AddAttribute("xmlns", NS_XMLDSIG);
- pAttributeList->AddAttribute("Id", "idPackageSignature");
- m_pImpl->getDocumentHandler()->startElement(
- "Signature", uno::Reference<xml::sax::XAttributeList>(pAttributeList));
-
- m_pImpl->writeSignedInfo();
- m_pImpl->writeSignatureValue();
- m_pImpl->writeKeyInfo();
- m_pImpl->writePackageObject();
- m_pImpl->writeOfficeObject();
- m_pImpl->writePackageSignature();
- m_pImpl->writeSignatureLineImages();
-
- m_pImpl->getDocumentHandler()->endElement("Signature");
-}
+void OOXMLSecExporter::writeSignature() { m_pImpl->writeSignature(); }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/helper/xsecsign.cxx b/xmlsecurity/source/helper/xsecsign.cxx
index 65c2b62374d9..a58a266f4dd8 100644
--- a/xmlsecurity/source/helper/xsecsign.cxx
+++ b/xmlsecurity/source/helper/xsecsign.cxx
@@ -150,14 +150,14 @@ css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > XSecCon
}
else // OOXML
{
- internalSignatureInfor.signatureInfor.ouSignatureId = "idPackageSignature";
+ OUString aID = createId();
+ internalSignatureInfor.signatureInfor.ouSignatureId = aID;
- internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idPackageObject", -1, OUString());
+ internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idPackageObject_" + aID, -1, OUString());
size++;
- internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idOfficeObject", -1, OUString());
+ internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idOfficeObject_" + aID, -1, OUString());
size++;
- OUString aId = "idSignedProperties_" + internalSignatureInfor.signatureInfor.ouSignatureId;
- internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, aId, -1, OUString());
+ internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idSignedProperties_" + aID, -1, OUString());
size++;
}