diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-02-11 12:06:02 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-02-11 13:33:59 +0100 |
commit | 6e8be4c99e00d75bfb0d358f64071495ec6b21e3 (patch) | |
tree | a9093c7862c866a7f0efc26ebd101d3c319c3ac6 /xmlsecurity/source | |
parent | 09a4abf2e1dd3e081d835a537ec913c71aa6c53e (diff) |
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
Diffstat (limited to 'xmlsecurity/source')
-rw-r--r-- | xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 1 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xmlsignaturehelper.cxx | 45 |
2 files changed, 46 insertions, 0 deletions
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx index 15028b49d50d..c53b93d41978 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 695b14b1bb32..056a187a70a2 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; |