[Libreoffice-commits] core.git: xmlsecurity/inc xmlsecurity/source

Miklos Vajna vmiklos at collabora.co.uk
Thu Feb 11 12:34:28 UTC 2016


 xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx     |    3 +
 xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx |    1 
 xmlsecurity/source/helper/xmlsignaturehelper.cxx       |   45 +++++++++++++++++
 3 files changed, 49 insertions(+)

New commits:
commit 6e8be4c99e00d75bfb0d358f64071495ec6b21e3
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Feb 11 12:06:02 2016 +0100

    xmlsecurity OOXML export: register signature content types
    
    Our own importer is happy about the export result already, but MSO is
    more picky, and mandates the correct content types for both
    _xmlsignatures/origin.sigs and the individual signature streams.
    
    With this, MSO can open the signed file again (while previously it just
    declared the file corrupted), though it still declares the signature
    invalid.
    
    Change-Id: I199ad96bb91e7ce03fdf1f10f9500db4e05bb5c1

diff --git a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
index 90b9540..f22570a 100644
--- a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
@@ -187,7 +187,10 @@ public:
     void ExportSignatureRelations(css::uno::Reference<css::embed::XStorage> xStorage, int nSignatureCount);
     /// Given that xSignatureStorage is an OOXML _xmlsignatures storage, create and write a new signature.
     bool CreateAndWriteOOXMLSignature(css::uno::Reference<css::embed::XStorage> xRootStorage, css::uno::Reference<css::embed::XStorage> xSignatureStorage, int nSignatureIndex);
+    /// Similar to CreateAndWriteOOXMLSignature(), but used to write the signature to the persistent storage, not the temporary one.
     void ExportOOXMLSignature(css::uno::Reference<css::embed::XStorage> xRootStorage, css::uno::Reference<css::embed::XStorage> xSignatureStorage, const SignatureInformation& rInformation, int nSignatureIndex);
+    /// Given that xStorage is an OOXML root storage, advertise signatures in its [Content_Types].xml stream.
+    void ExportSignatureContentTypes(css::uno::Reference<css::embed::XStorage> xStorage, int nSignatureCount);
 };
 
 #endif // INCLUDED_XMLSECURITY_INC_XMLSECURITY_XMLSIGNATUREHELPER_HXX
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 15028b4..c53b93d 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -416,6 +416,7 @@ IMPL_LINK_NOARG_TYPED(DigitalSignaturesDialog, OKButtonHdl, Button*, void)
     {
         // OOXML
         size_t nSignatureCount = maCurrentSignatureInformations.size();
+        maSignatureHelper.ExportSignatureContentTypes(mxStore, nSignatureCount);
         maSignatureHelper.ExportSignatureRelations(aStreamHelper.xSignatureStorage, nSignatureCount);
 
         for (size_t i = 0; i < nSignatureCount; ++i)
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index 695b14b..056a187 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -513,6 +513,51 @@ void XMLSignatureHelper::ExportSignatureRelations(css::uno::Reference<css::embed
     xTransact->commit();
 }
 
+void XMLSignatureHelper::ExportSignatureContentTypes(css::uno::Reference<css::embed::XStorage> xStorage, int nSignatureCount)
+{
+    sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
+    uno::Reference<io::XStream> xStream(xStorage->openStreamElement("[Content_Types].xml", nOpenMode), uno::UNO_QUERY);
+    uno::Reference<io::XInputStream> xInputStream = xStream->getInputStream();
+    uno::Sequence< uno::Sequence<beans::StringPair> > aContentTypeInfo = comphelper::OFOPXMLHelper::ReadContentTypeSequence(xInputStream, mxCtx);
+    if (aContentTypeInfo.getLength() < 2)
+    {
+        SAL_WARN("xmlsecurity.helper", "no defaults or overrides in aContentTypeInfo");
+        return;
+    }
+
+    // Append sigs to defaults, if it's not there already.
+    uno::Sequence<beans::StringPair>& rDefaults = aContentTypeInfo[0];
+    auto it = std::find_if(rDefaults.begin(), rDefaults.end(), [](const beans::StringPair& rPair)
+    {
+        return rPair.First == "sigs";
+    });
+    if (it == rDefaults.end())
+    {
+        auto aDefaults = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rDefaults);
+        aDefaults.push_back(beans::StringPair("sigs", "application/vnd.openxmlformats-package.digital-signature-origin"));
+        rDefaults = comphelper::containerToSequence(aDefaults);
+    }
+
+    // Remove existing signature overrides.
+    uno::Sequence<beans::StringPair>& rOverrides = aContentTypeInfo[1];
+    auto aOverrides = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rOverrides);
+    aOverrides.erase(std::remove_if(aOverrides.begin(), aOverrides.end(), [](const beans::StringPair& rPair)
+    {
+        return rPair.First.startsWith("/_xmlsignatures/sig");
+    }), aOverrides.end());
+
+    // Add our signature overrides.
+    for (int i = 1; i <= nSignatureCount; ++i)
+        aOverrides.push_back(beans::StringPair("/_xmlsignatures/sig" + OUString::number(i) + ".xml", "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml"));
+
+    rOverrides = comphelper::containerToSequence(aOverrides);
+    uno::Reference<io::XOutputStream> xOutputStream = xStream->getOutputStream();
+    uno::Reference <io::XTruncate> xTruncate(xOutputStream, uno::UNO_QUERY);
+    xTruncate->truncate();
+    comphelper::OFOPXMLHelper::WriteContentSequence(xOutputStream, rDefaults, rOverrides, mxCtx);
+    uno::Reference<embed::XTransactedObject> xTransact(xStorage, uno::UNO_QUERY);
+    xTransact->commit();
+}
 bool XMLSignatureHelper::CreateAndWriteOOXMLSignature(uno::Reference<embed::XStorage> xRootStorage, uno::Reference<embed::XStorage> xSignatureStorage, int nSignatureIndex)
 {
     sal_Int32 nOpenMode = embed::ElementModes::READWRITE;


More information about the Libreoffice-commits mailing list