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 <[email protected]> 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: */ _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
