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

Miklos Vajna vmiklos at collabora.co.uk
Fri Feb 5 10:04:13 UTC 2016


 sfx2/source/doc/docfile.cxx                            |    3 -
 xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx     |    2 
 xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx |    5 +
 xmlsecurity/source/helper/xmlsignaturehelper.cxx       |   45 +++++++++++++++++
 4 files changed, 54 insertions(+), 1 deletion(-)

New commits:
commit 79d565408eabc846692a2ed027707e6fe33adba4
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 5 11:01:11 2016 +0100

    xmlsecurity: ensure OOXML signatures relation when adding a signature
    
    A 'signatures relation' is kind of a pointer that says where is the list
    of signatures. When adding the first signature, this has to be created,
    in addition to the actual signature relation.
    
    This is yet another difference to ODF signing, where the signature is
    just another additional stream in the package, while OOXML signing first
    modifies the package to add the signatures relation, and then signs the
    streams, so the input storage of the OOXML signing can't be a read-only
    storage.
    
    Change-Id: I81a976c945b28ddf7f347c4a7bfd51f98a1fc225

diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index af4224a..0f4ec67 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -3607,7 +3607,8 @@ bool SfxMedium::SignContents_Impl( bool bScriptingContent, const OUString& aODFV
                     {
                         // OOXML.
                         uno::Reference<io::XStream> xStream;
-                        if (xSigner->signDocumentContent(GetZipStorageToSign_Impl(), xStream))
+                        // We need read-write to be able to add the signature relation.
+                        if (xSigner->signDocumentContent(GetZipStorageToSign_Impl(/*bReadOnly=*/false), xStream))
                         {
                             uno::Reference<embed::XTransactedObject> xTransact(xWriteableZipStor, uno::UNO_QUERY_THROW);
                             xTransact->commit();
diff --git a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
index ea954d1..543ec61 100644
--- a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
@@ -182,6 +182,8 @@ public:
     bool ReadAndVerifySignatureStorage(const css::uno::Reference<css::embed::XStorage>& xStorage);
     /// Read and verify a single OOXML signature.
     bool ReadAndVerifySignatureStorageStream(const css::uno::Reference<css::io::XInputStream>& xInputStream);
+    /// Adds an OOXML digital signature relation to _rels/.rels if there wasn't any before.
+    void EnsureSignaturesRelation(css::uno::Reference<css::embed::XStorage> xStorage);
 };
 
 #endif // INCLUDED_XMLSECURITY_INC_XMLSECURITY_XMLSIGNATUREHELPER_HXX
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index a5effe9..6641c0d 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -512,6 +512,11 @@ IMPL_LINK_NOARG_TYPED(DigitalSignaturesDialog, AddButtonHdl, Button*, void)
                 // That's it...
                 XMLSignatureHelper::CloseDocumentHandler( xDocumentHandler);
             }
+            else
+            {
+                // OOXML
+                maSignatureHelper.EnsureSignaturesRelation(mxStore);
+            }
 
             maSignatureHelper.EndMission();
 
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index e2f60f5..4d2293c 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -33,6 +33,7 @@
 #include <com/sun/star/io/XOutputStream.hpp>
 #include <com/sun/star/io/XInputStream.hpp>
 #include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
 #include <com/sun/star/lang/XComponent.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/beans/StringPair.hpp>
@@ -42,6 +43,7 @@
 #include <com/sun/star/embed/ElementModes.hpp>
 #include <com/sun/star/embed/XStorage.hpp>
 #include <com/sun/star/embed/StorageFormats.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
 
 #include <tools/date.hxx>
 #include <tools/time.hxx>
@@ -51,6 +53,7 @@
 #define TAG_DOCUMENTSIGNATURES  "document-signatures"
 #define NS_DOCUMENTSIGNATURES   "http://openoffice.org/2004/documentsignatures"
 #define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"
+#define OOXML_SIGNATURE_ORIGIN "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin"
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -351,6 +354,10 @@ bool lcl_isSignatureType(const beans::StringPair& rPair)
 {
     return rPair.First == "Type" && rPair.Second == "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature";
 }
+bool lcl_isSignatureOriginType(const beans::StringPair& rPair)
+{
+    return rPair.First == "Type" && rPair.Second == OOXML_SIGNATURE_ORIGIN;
+}
 }
 
 bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embed::XStorage>& xStorage)
@@ -420,4 +427,42 @@ bool XMLSignatureHelper::ReadAndVerifySignatureStorageStream(const css::uno::Ref
     return !mbError;
 }
 
+void XMLSignatureHelper::EnsureSignaturesRelation(css::uno::Reference<css::embed::XStorage> xStorage)
+{
+    sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
+    uno::Reference<embed::XStorage> xSubStorage = xStorage->openStorageElement("_rels", nOpenMode);
+    uno::Reference<io::XInputStream> xRelStream(xSubStorage->openStreamElement(".rels", nOpenMode), uno::UNO_QUERY);
+    std::vector< uno::Sequence<beans::StringPair> > aRelationsInfo;
+    aRelationsInfo = comphelper::sequenceToContainer< std::vector< uno::Sequence<beans::StringPair> > >(comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(xRelStream, ".rels", mxCtx));
+
+    // Do we have a relation already?
+    int nCount = 0;
+    for (const uno::Sequence<beans::StringPair>& rRelation : aRelationsInfo)
+    {
+        auto aRelation = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rRelation);
+        if (std::find_if(aRelation.begin(), aRelation.end(), lcl_isSignatureOriginType) != aRelation.end())
+            return;
+        ++nCount;
+    }
+
+    // No, then add one.
+    std::vector<beans::StringPair> aRelation;
+    aRelation.push_back(beans::StringPair("Id", "rId" + OUString::number(++nCount)));
+    aRelation.push_back(beans::StringPair("Type", OOXML_SIGNATURE_ORIGIN));
+    aRelation.push_back(beans::StringPair("Target", "_xmlsignatures/origin.sigs"));
+    aRelationsInfo.push_back(comphelper::containerToSequence(aRelation));
+
+    // Write it back.
+    uno::Reference<io::XTruncate> xTruncate(xRelStream, uno::UNO_QUERY);
+    xTruncate->truncate();
+    uno::Reference<io::XOutputStream> xOutputStream(xRelStream, uno::UNO_QUERY);
+    comphelper::OFOPXMLHelper::WriteRelationsInfoSequence(xOutputStream, comphelper::containerToSequence(aRelationsInfo), mxCtx);
+
+    // Commit it.
+    uno::Reference<embed::XTransactedObject> xTransact(xSubStorage, uno::UNO_QUERY);
+    xTransact->commit();
+    xTransact.set(xStorage, uno::UNO_QUERY);
+    xTransact->commit();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list