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
This commit is contained in:
@@ -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 )
|
||||
{
|
||||
|
@@ -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,6 +208,12 @@ 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);
|
||||
|
||||
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();
|
||||
@@ -215,6 +222,7 @@ void XMLSignatureHelper::ExportOOXMLSignature(uno::Reference<embed::XStorage> xR
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 );
|
||||
|
||||
|
@@ -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())
|
||||
|
Reference in New Issue
Block a user