diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-03-04 09:40:17 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-03-04 11:48:48 +0100 |
commit | 38c39dc49c502683a3ccbcbfaa7e7ecee413c30f (patch) | |
tree | adc7836638648f8f4c869680bc98d4a4702e7a1a /xmlsecurity | |
parent | b9fb9062a999b3342010e6d26919e6d49065abb1 (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.hxx | 3 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xmlsignaturehelper.cxx | 33 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecctl.hxx | 3 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecverify.cxx | 9 |
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()) |