summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-02-05 11:01:11 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-02-05 11:02:32 +0100
commit79d565408eabc846692a2ed027707e6fe33adba4 (patch)
treebe31c07b5ffbcec8876b3fc035cf4d61edcbc2c7 /xmlsecurity
parent080e5f2f24513e871f2563c88a69fa8a9ecfe0eb (diff)
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
Diffstat (limited to 'xmlsecurity')
-rw-r--r--xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx2
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx5
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper.cxx45
3 files changed, 52 insertions, 0 deletions
diff --git a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
index ea954d1e470a..543ec618f919 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 a5effe9f7abb..6641c0d6df3c 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 e2f60f574406..4d2293c4b6d9 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: */