summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-03-04 09:40:17 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-03-04 11:48:48 +0100
commit38c39dc49c502683a3ccbcbfaa7e7ecee413c30f (patch)
treeadc7836638648f8f4c869680bc98d4a4702e7a1a /xmlsecurity
parentb9fb9062a999b3342010e6d26919e6d49065abb1 (diff)
xmlsecurity OOXML export: fix appending new signatures next to existing ones
We append a new signature to a document by re-exporting the existing ones, then writing the new signature. Given that existing signatures aren't canonicalized before hashing, write them back as-is. With this, our own signature verification is happy about the export result, containing an existing and a newly created signature. Change-Id: I0ff57a2266c6070a945f0c45ca5793406678be60
Diffstat (limited to 'xmlsecurity')
-rw-r--r--xmlsecurity/inc/xmlsecurity/sigstruct.hxx3
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper.cxx33
-rw-r--r--xmlsecurity/source/helper/xsecctl.hxx3
-rw-r--r--xmlsecurity/source/helper/xsecverify.cxx9
4 files changed, 42 insertions, 6 deletions
diff --git a/xmlsecurity/inc/xmlsecurity/sigstruct.hxx b/xmlsecurity/inc/xmlsecurity/sigstruct.hxx
index e501239b8765..3cb1e7d46924 100644
--- a/xmlsecurity/inc/xmlsecurity/sigstruct.hxx
+++ b/xmlsecurity/inc/xmlsecurity/sigstruct.hxx
@@ -23,6 +23,7 @@
#include <rtl/ustring.hxx>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
+#include <com/sun/star/uno/Sequence.h>
#include <vector>
@@ -83,6 +84,8 @@ struct SignatureInformation
OUString ouDescriptionPropertyId;
/// OOXML certificate SHA-256 digest, empty for ODF.
OUString ouCertDigest;
+ /// A full OOXML signguature for unchanged roundtrip, empty for ODF.
+ css::uno::Sequence<sal_Int8> aSignatureBytes;
SignatureInformation( sal_Int32 nId )
{
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index 59d5ec4ed4a4..2b05621a8c8c 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -44,6 +44,7 @@
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/embed/StorageFormats.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
#include <tools/date.hxx>
#include <tools/time.hxx>
@@ -207,14 +208,21 @@ void XMLSignatureHelper::ExportOOXMLSignature(uno::Reference<embed::XStorage> xR
{
sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
uno::Reference<io::XOutputStream> xOutputStream(xSignatureStorage->openStreamElement("sig" + OUString::number(nSignatureIndex) + ".xml", nOpenMode), uno::UNO_QUERY);
- uno::Reference<xml::sax::XWriter> xSaxWriter = xml::sax::Writer::create(mxCtx);
- xSaxWriter->setOutputStream(xOutputStream);
- xSaxWriter->startDocument();
- uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY);
- mpXSecController->exportOOXMLSignature(xRootStorage, xDocumentHandler, rInformation);
+ if (rInformation.aSignatureBytes.hasElements())
+ // This is a signature roundtrip, just write back the signature as-is.
+ xOutputStream->writeBytes(rInformation.aSignatureBytes);
+ else
+ {
+ uno::Reference<xml::sax::XWriter> xSaxWriter = xml::sax::Writer::create(mxCtx);
+ xSaxWriter->setOutputStream(xOutputStream);
+ xSaxWriter->startDocument();
- xSaxWriter->endDocument();
+ uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY);
+ mpXSecController->exportOOXMLSignature(xRootStorage, xDocumentHandler, rInformation);
+
+ xSaxWriter->endDocument();
+ }
}
bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler )
@@ -403,6 +411,19 @@ bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embe
uno::Reference<io::XInputStream> xInputStream(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY);
if (!ReadAndVerifySignatureStorageStream(xInputStream))
return false;
+
+ // Store the contents of the stream as is, in case we need to write it back later.
+ xInputStream.clear();
+ xInputStream.set(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropertySet(xInputStream, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ sal_Int64 nSize = 0;
+ xPropertySet->getPropertyValue("Size") >>= nSize;
+ uno::Sequence<sal_Int8> aData;
+ xInputStream->readBytes(aData, nSize);
+ mpXSecController->setSignatureBytes(aData);
+ }
}
}
}
diff --git a/xmlsecurity/source/helper/xsecctl.hxx b/xmlsecurity/source/helper/xsecctl.hxx
index 1b52072046ed..595ea82ab89f 100644
--- a/xmlsecurity/source/helper/xsecctl.hxx
+++ b/xmlsecurity/source/helper/xsecctl.hxx
@@ -390,7 +390,10 @@ private:
void setDate( OUString& ouDate );
void setDescription(const OUString& rDescription);
void setCertDigest(const OUString& rCertDigest);
+public:
+ void setSignatureBytes(const css::uno::Sequence<sal_Int8>& rBytes);
+private:
void setId( OUString& ouId );
void setPropertyId( OUString& ouPropertyId );
diff --git a/xmlsecurity/source/helper/xsecverify.cxx b/xmlsecurity/source/helper/xsecverify.cxx
index a7e218398924..bef6fa706945 100644
--- a/xmlsecurity/source/helper/xsecverify.cxx
+++ b/xmlsecurity/source/helper/xsecverify.cxx
@@ -274,6 +274,15 @@ void XSecController::setDescription(const OUString& rDescription)
rInformation.signatureInfor.ouDescription = rDescription;
}
+void XSecController::setSignatureBytes(const uno::Sequence<sal_Int8>& rBytes)
+{
+ if (m_vInternalSignatureInformations.empty())
+ return;
+
+ InternalSignatureInformation& rInformation = m_vInternalSignatureInformations.back();
+ rInformation.signatureInfor.aSignatureBytes = rBytes;
+}
+
void XSecController::setCertDigest(const OUString& rCertDigest)
{
if (m_vInternalSignatureInformations.empty())