Kaydet (Commit) 6e8be4c9 authored tarafından Miklos Vajna's avatar Miklos Vajna

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
üst 09a4abf2
......@@ -187,7 +187,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
......
......@@ -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)
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment