summaryrefslogtreecommitdiffstats
path: root/xmlsecurity/source/helper/xmlsignaturehelper.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper.cxx549
1 files changed, 549 insertions, 0 deletions
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
new file mode 100644
index 000000000..6ec834053
--- /dev/null
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -0,0 +1,549 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <xmlsignaturehelper.hxx>
+#include <documentsignaturehelper.hxx>
+#include <xsecctl.hxx>
+
+#include <xmlsignaturehelper2.hxx>
+
+#include <tools/datetime.hxx>
+
+#include <xmloff/attrlist.hxx>
+
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/StringPair.hpp>
+#include <com/sun/star/xml/sax/Parser.hpp>
+#include <com/sun/star/xml/sax/Writer.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/StorageFormats.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+
+#include <comphelper/ofopxmlhelper.hxx>
+#include <comphelper/sequence.hxx>
+#include <tools/diagnose_ex.h>
+#include <sal/log.hxx>
+
+#define NS_DOCUMENTSIGNATURES "http://openoffice.org/2004/documentsignatures"
+#define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"
+#define OOXML_SIGNATURE_ORIGIN "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin"
+#define OOXML_SIGNATURE_SIGNATURE "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::uno;
+
+XMLSignatureHelper::XMLSignatureHelper( const uno::Reference< uno::XComponentContext >& rxCtx)
+ : mxCtx(rxCtx), mbODFPre1_2(false)
+{
+ mpXSecController = new XSecController(rxCtx);
+ mbError = false;
+}
+
+XMLSignatureHelper::~XMLSignatureHelper()
+{
+}
+
+void XMLSignatureHelper::SetStorage(
+ const Reference < css::embed::XStorage >& rxStorage,
+ const OUString& sODFVersion)
+{
+ SAL_WARN_IF( mxUriBinding.is(), "xmlsecurity.helper", "SetStorage - UriBinding already set!" );
+ mxUriBinding = new UriBindingHelper( rxStorage );
+ SAL_WARN_IF(!rxStorage.is(), "xmlsecurity.helper", "SetStorage - empty storage!");
+ mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(sODFVersion);
+}
+
+
+void XMLSignatureHelper::SetStartVerifySignatureHdl( const Link<LinkParamNone*,bool>& rLink )
+{
+ maStartVerifySignatureHdl = rLink;
+}
+
+
+void XMLSignatureHelper::StartMission(const uno::Reference<xml::crypto::XXMLSecurityContext>& xSecurityContext)
+{
+ if ( !mxUriBinding.is() )
+ mxUriBinding = new UriBindingHelper();
+
+ mpXSecController->startMission(mxUriBinding, xSecurityContext);
+}
+
+void XMLSignatureHelper::EndMission()
+{
+ mpXSecController->endMission();
+}
+
+sal_Int32 XMLSignatureHelper::GetNewSecurityId()
+{
+ return mpXSecController->getNewSecurityId();
+}
+
+void XMLSignatureHelper::SetX509Certificate(
+ sal_Int32 nSecurityId,
+ const OUString& ouX509IssuerName,
+ const OUString& ouX509SerialNumber,
+ const OUString& ouX509Cert,
+ const OUString& ouX509CertDigest,
+ svl::crypto::SignatureMethodAlgorithm eAlgorithmID)
+{
+ mpXSecController->setX509Certificate(
+ nSecurityId,
+ ouX509IssuerName,
+ ouX509SerialNumber,
+ ouX509Cert,
+ ouX509CertDigest,
+ eAlgorithmID);
+}
+
+void XMLSignatureHelper::AddEncapsulatedX509Certificate(const OUString& ouEncapsulatedX509Certificate)
+{
+ mpXSecController->addEncapsulatedX509Certificate(ouEncapsulatedX509Certificate);
+}
+
+void XMLSignatureHelper::SetGpgCertificate(sal_Int32 nSecurityId,
+ const OUString& ouGpgCertDigest,
+ const OUString& ouGpgCert,
+ const OUString& ouGpgOwner)
+{
+ mpXSecController->setGpgCertificate(
+ nSecurityId,
+ ouGpgCertDigest,
+ ouGpgCert,
+ ouGpgOwner);
+}
+
+void XMLSignatureHelper::SetDateTime( sal_Int32 nSecurityId, const ::DateTime& rDateTime )
+{
+ css::util::DateTime stDateTime = rDateTime.GetUNODateTime();
+ mpXSecController->setDate( nSecurityId, stDateTime );
+}
+
+void XMLSignatureHelper::SetDescription(sal_Int32 nSecurityId, const OUString& rDescription)
+{
+ mpXSecController->setDescription(nSecurityId, rDescription);
+}
+
+void XMLSignatureHelper::SetSignatureLineId(sal_Int32 nSecurityId, const OUString& rSignatureLineId)
+{
+ mpXSecController->setSignatureLineId(nSecurityId, rSignatureLineId);
+}
+
+void XMLSignatureHelper::SetSignatureLineValidGraphic(
+ sal_Int32 nSecurityId, const css::uno::Reference<XGraphic>& xValidGraphic)
+{
+ mpXSecController->setSignatureLineValidGraphic(nSecurityId, xValidGraphic);
+}
+
+void XMLSignatureHelper::SetSignatureLineInvalidGraphic(
+ sal_Int32 nSecurityId, const css::uno::Reference<XGraphic>& xInvalidGraphic)
+{
+ mpXSecController->setSignatureLineInvalidGraphic(nSecurityId, xInvalidGraphic);
+}
+
+void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const OUString& uri, bool bBinary, bool bXAdESCompliantIfODF )
+{
+ mpXSecController->signAStream( nSecurityId, uri, bBinary, bXAdESCompliantIfODF );
+}
+
+
+uno::Reference<xml::sax::XWriter> XMLSignatureHelper::CreateDocumentHandlerWithHeader(
+ const css::uno::Reference< css::io::XOutputStream >& xOutputStream )
+{
+ /*
+ * get SAX writer component
+ */
+ uno::Reference< xml::sax::XWriter > xSaxWriter = xml::sax::Writer::create(mxCtx);
+
+ /*
+ * connect XML writer to output stream
+ */
+ xSaxWriter->setOutputStream( xOutputStream );
+
+ /*
+ * write the xml context for signatures
+ */
+ SvXMLAttributeList *pAttributeList = new SvXMLAttributeList();
+ OUString sNamespace;
+ if (mbODFPre1_2)
+ sNamespace = NS_DOCUMENTSIGNATURES;
+ else
+ sNamespace = NS_DOCUMENTSIGNATURES_ODF_1_2;
+
+ pAttributeList->AddAttribute(
+ "xmlns",
+ sNamespace);
+
+ xSaxWriter->startDocument();
+ xSaxWriter->startElement(
+ "document-signatures",
+ uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
+
+ return xSaxWriter;
+}
+
+void XMLSignatureHelper::CloseDocumentHandler( const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler )
+{
+ xDocumentHandler->endElement( "document-signatures" );
+ xDocumentHandler->endDocument();
+}
+
+void XMLSignatureHelper::ExportSignature(
+ const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler,
+ const SignatureInformation& signatureInfo,
+ bool bXAdESCompliantIfODF )
+{
+ XSecController::exportSignature(xDocumentHandler, signatureInfo, bXAdESCompliantIfODF);
+}
+
+void XMLSignatureHelper::ExportOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<embed::XStorage>& xSignatureStorage, const SignatureInformation& rInformation, int nSignatureIndex)
+{
+ uno::Reference<io::XOutputStream> xOutputStream(xSignatureStorage->openStreamElement("sig" + OUString::number(nSignatureIndex) + ".xml", embed::ElementModes::READWRITE), 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();
+
+ mpXSecController->exportOOXMLSignature(xRootStorage, xSaxWriter, rInformation);
+
+ xSaxWriter->endDocument();
+ }
+}
+
+void XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler, bool bXAdESCompliantIfODF )
+{
+ mbError = false;
+
+ if ( !mpXSecController->WriteSignature( xDocumentHandler, bXAdESCompliantIfODF ) )
+ {
+ mbError = true;
+ }
+}
+
+bool XMLSignatureHelper::ReadAndVerifySignature( const css::uno::Reference< css::io::XInputStream >& xInputStream )
+{
+ mbError = false;
+
+ SAL_WARN_IF(!xInputStream.is(), "xmlsecurity.helper", "input stream missing");
+
+ // prepare ParserInputSrouce
+ xml::sax::InputSource aParserInput;
+ aParserInput.aInputStream = xInputStream;
+
+ // get SAX parser component
+ uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(mxCtx);
+
+ // create a signature reader
+ uno::Reference< xml::sax::XDocumentHandler > xHandler
+ = mpXSecController->createSignatureReader(*this);
+
+ // setup the connection:
+ // Parser -> SignatureReader
+ xParser->setDocumentHandler( xHandler );
+
+ // parser the stream
+ try
+ {
+ xParser->parseStream( aParserInput );
+ }
+ catch( uno::Exception& )
+ {
+ mbError = true;
+ }
+
+ // release the signature reader
+ mpXSecController->releaseSignatureReader( );
+
+ return !mbError;
+}
+
+SignatureInformation XMLSignatureHelper::GetSignatureInformation( sal_Int32 nSecurityId ) const
+{
+ return mpXSecController->getSignatureInformation( nSecurityId );
+}
+
+SignatureInformations XMLSignatureHelper::GetSignatureInformations() const
+{
+ return mpXSecController->getSignatureInformations();
+}
+
+void XMLSignatureHelper::StartVerifySignatureElement()
+{
+ if ( !maStartVerifySignatureHdl.IsSet() || maStartVerifySignatureHdl.Call(nullptr) )
+ {
+ sal_Int32 nSignatureId = mpXSecController->getNewSecurityId();
+ mpXSecController->addSignature( nSignatureId );
+ }
+}
+
+namespace
+{
+bool lcl_isSignatureType(const beans::StringPair& rPair)
+{
+ return rPair.First == "Type" && rPair.Second == OOXML_SIGNATURE_SIGNATURE;
+}
+bool lcl_isSignatureOriginType(const beans::StringPair& rPair)
+{
+ return rPair.First == "Type" && rPair.Second == OOXML_SIGNATURE_ORIGIN;
+}
+}
+
+bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embed::XStorage>& xStorage, bool bCacheLastSignature)
+{
+ sal_Int32 nOpenMode = embed::ElementModes::READ;
+ if (xStorage.is() && !xStorage->hasByName("_rels"))
+ {
+ SAL_WARN("xmlsecurity.helper", "expected stream, in signature storage but not found: _rels");
+ return false;
+ }
+
+ uno::Reference<embed::XStorage> xSubStorage = xStorage->openStorageElement("_rels", nOpenMode);
+ uno::Reference<io::XInputStream> xRelStream(xSubStorage->openStreamElement("origin.sigs.rels", nOpenMode), uno::UNO_QUERY);
+ uno::Sequence< uno::Sequence<beans::StringPair> > aRelationsInfo = comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(xRelStream, "origin.sigs.rels", mxCtx);
+
+ for (sal_Int32 i = 0; i < aRelationsInfo.getLength(); ++i)
+ {
+ const uno::Sequence<beans::StringPair>& rRelation = aRelationsInfo[i];
+ auto aRelation = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rRelation);
+ if (std::any_of(aRelation.begin(), aRelation.end(), lcl_isSignatureType))
+ {
+ std::vector<beans::StringPair>::iterator it = std::find_if(aRelation.begin(), aRelation.end(), [](const beans::StringPair& rPair) { return rPair.First == "Target"; });
+ if (it != aRelation.end())
+ {
+ if (xStorage.is() && !xStorage->hasByName(it->Second))
+ {
+ SAL_WARN("xmlsecurity.helper", "expected stream, but not found: " << it->Second);
+ continue;
+ }
+
+ uno::Reference<io::XInputStream> xInputStream(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY);
+ if (!ReadAndVerifySignatureStorageStream(xInputStream))
+ return false;
+
+ // By default, we cache. If it's requested, then we don't cache the last signature.
+ bool bCache = true;
+ if (!bCacheLastSignature && i == aRelationsInfo.getLength() - 1)
+ bCache = false;
+
+ if (!bCache)
+ continue;
+ // 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())
+ continue;
+
+ sal_Int64 nSize = 0;
+ xPropertySet->getPropertyValue("Size") >>= nSize;
+ if (nSize < 0 || nSize > SAL_MAX_INT32)
+ {
+ SAL_WARN("xmlsecurity.helper", "bogus signature size: " << nSize);
+ continue;
+ }
+ uno::Sequence<sal_Int8> aData;
+ xInputStream->readBytes(aData, nSize);
+ mpXSecController->setSignatureBytes(aData);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool XMLSignatureHelper::ReadAndVerifySignatureStorageStream(const css::uno::Reference<css::io::XInputStream>& xInputStream)
+{
+ mbError = false;
+
+ // Create the input source.
+ xml::sax::InputSource aParserInput;
+ aParserInput.aInputStream = xInputStream;
+
+ // Create the sax parser.
+ uno::Reference<xml::sax::XParser> xParser = xml::sax::Parser::create(mxCtx);
+
+ // Create the signature reader.
+ uno::Reference<xml::sax::XDocumentHandler> xHandler = mpXSecController->createSignatureReader(*this, embed::StorageFormats::OFOPXML);
+
+ // Parser -> signature reader.
+ xParser->setDocumentHandler(xHandler);
+
+ // Parse the stream.
+ try
+ {
+ xParser->parseStream(aParserInput);
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("xmlsecurity.helper");
+ }
+
+ mpXSecController->releaseSignatureReader();
+
+ return !mbError;
+}
+
+void XMLSignatureHelper::EnsureSignaturesRelation(const css::uno::Reference<css::embed::XStorage>& xStorage, bool bAdd)
+{
+ sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
+ uno::Reference<embed::XStorage> xSubStorage = xStorage->openStorageElement("_rels", nOpenMode);
+ uno::Reference<io::XInputStream> xRelStream(xSubStorage->openStreamElement(".rels", nOpenMode), uno::UNO_QUERY);
+ std::vector< uno::Sequence<beans::StringPair> > aRelationsInfo = comphelper::sequenceToContainer< std::vector< uno::Sequence<beans::StringPair> > >(comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(xRelStream, ".rels", mxCtx));
+
+ // Do we have a relation already?
+ bool bHaveRelation = false;
+ int nCount = 0;
+ for (const uno::Sequence<beans::StringPair>& rRelation : aRelationsInfo)
+ {
+ auto aRelation = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rRelation);
+ if (std::any_of(aRelation.begin(), aRelation.end(), lcl_isSignatureOriginType))
+ {
+ bHaveRelation = true;
+ break;
+ }
+ ++nCount;
+ }
+
+ if (!bHaveRelation && bAdd)
+ {
+ // No, and have to add one.
+ std::vector<beans::StringPair> aRelation;
+ aRelation.emplace_back("Id", "rId" + OUString::number(++nCount));
+ aRelation.emplace_back("Type", OOXML_SIGNATURE_ORIGIN);
+ aRelation.emplace_back("Target", "_xmlsignatures/origin.sigs");
+ aRelationsInfo.push_back(comphelper::containerToSequence(aRelation));
+ }
+ else if (bHaveRelation && !bAdd)
+ {
+ // Yes, and need to remove it.
+ for (std::vector< uno::Sequence<beans::StringPair> >::iterator it = aRelationsInfo.begin(); it != aRelationsInfo.end();)
+ {
+ auto aRelation = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(*it);
+ if (std::any_of(aRelation.begin(), aRelation.end(), lcl_isSignatureOriginType))
+ it = aRelationsInfo.erase(it);
+ else
+ ++it;
+ }
+ }
+
+ // Write it back.
+ uno::Reference<io::XTruncate> xTruncate(xRelStream, uno::UNO_QUERY);
+ xTruncate->truncate();
+ uno::Reference<io::XOutputStream> xOutputStream(xRelStream, uno::UNO_QUERY);
+ comphelper::OFOPXMLHelper::WriteRelationsInfoSequence(xOutputStream, comphelper::containerToSequence(aRelationsInfo), mxCtx);
+
+ // Commit it.
+ uno::Reference<embed::XTransactedObject> xTransact(xSubStorage, uno::UNO_QUERY);
+ xTransact->commit();
+ xTransact.set(xStorage, uno::UNO_QUERY);
+ xTransact->commit();
+}
+
+void XMLSignatureHelper::ExportSignatureRelations(const css::uno::Reference<css::embed::XStorage>& xStorage, int nSignatureCount)
+{
+ // Write the empty file, its relations will be the signatures.
+ sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
+ uno::Reference<io::XOutputStream> xOriginStream(xStorage->openStreamElement("origin.sigs", nOpenMode), uno::UNO_QUERY);
+ uno::Reference<io::XTruncate> xTruncate(xOriginStream, uno::UNO_QUERY);
+ xTruncate->truncate();
+ xOriginStream->closeOutput();
+
+ // Write the relations.
+ uno::Reference<embed::XStorage> xSubStorage = xStorage->openStorageElement("_rels", nOpenMode);
+ uno::Reference<io::XOutputStream> xRelStream(xSubStorage->openStreamElement("origin.sigs.rels", nOpenMode), uno::UNO_QUERY);
+ std::vector< uno::Sequence<beans::StringPair> > aRelations;
+ for (int i = 0; i < nSignatureCount; ++i)
+ {
+ std::vector<beans::StringPair> aRelation;
+ aRelation.emplace_back("Id", "rId" + OUString::number(i + 1));
+ aRelation.emplace_back("Type", OOXML_SIGNATURE_SIGNATURE);
+ aRelation.emplace_back("Target", "sig" + OUString::number(i + 1) + ".xml");
+ aRelations.push_back(comphelper::containerToSequence(aRelation));
+ }
+ comphelper::OFOPXMLHelper::WriteRelationsInfoSequence(xRelStream, comphelper::containerToSequence(aRelations), mxCtx);
+ uno::Reference<embed::XTransactedObject> xTransact(xSubStorage, uno::UNO_QUERY);
+ xTransact->commit();
+}
+
+void XMLSignatureHelper::ExportSignatureContentTypes(const css::uno::Reference<css::embed::XStorage>& xStorage, int nSignatureCount)
+{
+ uno::Reference<io::XStream> xStream = xStorage->openStreamElement("[Content_Types].xml", embed::ElementModes::READWRITE);
+ 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 rels and sigs to defaults, if it's not there already.
+ uno::Sequence<beans::StringPair>& rDefaults = aContentTypeInfo[0];
+ auto aDefaults = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rDefaults);
+ if (std::none_of(rDefaults.begin(), rDefaults.end(), [](const beans::StringPair& rPair) { return rPair.First == "rels"; }))
+ aDefaults.emplace_back("rels", "application/vnd.openxmlformats-package.relationships+xml");
+
+ if (std::none_of(rDefaults.begin(), rDefaults.end(), [](const beans::StringPair& rPair) { return rPair.First == "sigs"; }))
+ aDefaults.emplace_back("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.emplace_back("/_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();
+}
+void XMLSignatureHelper::CreateAndWriteOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<embed::XStorage>& xSignatureStorage, int nSignatureIndex)
+{
+ uno::Reference<io::XOutputStream> xOutputStream(xSignatureStorage->openStreamElement("sig" + OUString::number(nSignatureIndex) + ".xml", embed::ElementModes::READWRITE), uno::UNO_QUERY);
+ uno::Reference<xml::sax::XWriter> xSaxWriter = xml::sax::Writer::create(mxCtx);
+ xSaxWriter->setOutputStream(xOutputStream);
+ xSaxWriter->startDocument();
+
+ mbError = false;
+ if (!mpXSecController->WriteOOXMLSignature(xRootStorage, xSaxWriter))
+ mbError = true;
+
+ xSaxWriter->endDocument();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */