summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-02-11 12:06:02 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-07-07 12:27:50 +0200
commit7ccf5aedb59e6488cfdd5b4990efd74f8d607a19 (patch)
treeed407d19efe1f7528d178d4deb35ee8b8e73ce67 /xmlsecurity
parente90221c51437bb57411cc77c5505e7067e252625 (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 (cherry picked from commit 6e8be4c99e00d75bfb0d358f64071495ec6b21e3)
Diffstat (limited to 'xmlsecurity')
-rw-r--r--xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx3
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx1
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper.cxx45
3 files changed, 49 insertions, 0 deletions
diff --git a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
index 8bcf001ed117..65583b59ae76 100644
--- a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
@@ -188,7 +188,10 @@ public:
void ExportSignatureRelations(css::uno::Reference<css::embed::XStorage> xStorage, int nSignatureCount);
/// Given that xSignatureStorage is an OOXML _xmlsignatures storage, create and write a new signature.
bool CreateAndWriteOOXMLSignature(css::uno::Reference<css::embed::XStorage> xRootStorage, css::uno::Reference<css::embed::XStorage> xSignatureStorage, int nSignatureIndex);
+ /// Similar to CreateAndWriteOOXMLSignature(), but used to write the signature to the persistent storage, not the temporary one.
void ExportOOXMLSignature(css::uno::Reference<css::embed::XStorage> xRootStorage, css::uno::Reference<css::embed::XStorage> xSignatureStorage, const SignatureInformation& rInformation, int nSignatureIndex);
+ /// Given that xStorage is an OOXML root storage, advertise signatures in its [Content_Types].xml stream.
+ void ExportSignatureContentTypes(css::uno::Reference<css::embed::XStorage> xStorage, int nSignatureCount);
};
#endif // INCLUDED_XMLSECURITY_INC_XMLSECURITY_XMLSIGNATUREHELPER_HXX
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 2449123b84c9..39f29f83f411 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;