diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-02-05 11:01:11 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-02-05 11:02:32 +0100 |
commit | 79d565408eabc846692a2ed027707e6fe33adba4 (patch) | |
tree | be31c07b5ffbcec8876b3fc035cf4d61edcbc2c7 /xmlsecurity | |
parent | 080e5f2f24513e871f2563c88a69fa8a9ecfe0eb (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.hxx | 2 | ||||
-rw-r--r-- | xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 5 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xmlsignaturehelper.cxx | 45 |
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: */ |