build fix
[LibreOffice.git] / xmlsecurity / source / helper / xmlsignaturehelper.cxx
blob36a6117c29a0087a6aa2eaf919916b4c133e8825
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <xmlsignaturehelper.hxx>
22 #include <documentsignaturehelper.hxx>
23 #include "xsecctl.hxx"
25 #include "xmlsignaturehelper2.hxx"
27 #include <tools/stream.hxx>
28 #include <tools/datetime.hxx>
30 #include <xmloff/attrlist.hxx>
32 #include <com/sun/star/io/XOutputStream.hpp>
33 #include <com/sun/star/io/XInputStream.hpp>
34 #include <com/sun/star/io/XActiveDataSource.hpp>
35 #include <com/sun/star/io/XTruncate.hpp>
36 #include <com/sun/star/lang/XComponent.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/beans/StringPair.hpp>
39 #include <com/sun/star/xml/sax/Parser.hpp>
40 #include <com/sun/star/xml/sax/Writer.hpp>
41 #include <com/sun/star/embed/ElementModes.hpp>
42 #include <com/sun/star/embed/XStorage.hpp>
43 #include <com/sun/star/embed/StorageFormats.hpp>
44 #include <com/sun/star/embed/XTransactedObject.hpp>
45 #include <com/sun/star/io/XSeekable.hpp>
47 #include <tools/date.hxx>
48 #include <tools/time.hxx>
49 #include <comphelper/ofopxmlhelper.hxx>
50 #include <comphelper/sequence.hxx>
52 #define NS_DOCUMENTSIGNATURES "http://openoffice.org/2004/documentsignatures"
53 #define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"
54 #define OOXML_SIGNATURE_ORIGIN "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin"
55 #define OOXML_SIGNATURE_SIGNATURE "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature"
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::uno;
60 XMLSignatureHelper::XMLSignatureHelper( const uno::Reference< uno::XComponentContext >& rxCtx)
61 : mxCtx(rxCtx), mbODFPre1_2(false)
63 mpXSecController = new XSecController(rxCtx);
64 mbError = false;
67 XMLSignatureHelper::~XMLSignatureHelper()
71 void XMLSignatureHelper::SetStorage(
72 const Reference < css::embed::XStorage >& rxStorage,
73 const OUString& sODFVersion)
75 SAL_WARN_IF( mxUriBinding.is(), "xmlsecurity.helper", "SetStorage - UriBinding already set!" );
76 mxUriBinding = new UriBindingHelper( rxStorage );
77 SAL_WARN_IF(!rxStorage.is(), "xmlsecurity.helper", "SetStorage - empty storage!");
78 mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(sODFVersion);
82 void XMLSignatureHelper::SetStartVerifySignatureHdl( const Link<LinkParamNone*,bool>& rLink )
84 maStartVerifySignatureHdl = rLink;
88 void XMLSignatureHelper::StartMission(const uno::Reference<xml::crypto::XXMLSecurityContext>& xSecurityContext)
90 if ( !mxUriBinding.is() )
91 mxUriBinding = new UriBindingHelper();
93 mpXSecController->startMission(mxUriBinding, xSecurityContext);
96 void XMLSignatureHelper::EndMission()
98 mpXSecController->endMission();
101 sal_Int32 XMLSignatureHelper::GetNewSecurityId()
103 return mpXSecController->getNewSecurityId();
106 void XMLSignatureHelper::SetX509Certificate(
107 sal_Int32 nSecurityId,
108 const OUString& ouX509IssuerName,
109 const OUString& ouX509SerialNumber,
110 const OUString& ouX509Cert,
111 const OUString& ouX509CertDigest)
113 mpXSecController->setX509Certificate(
114 nSecurityId,
115 ouX509IssuerName,
116 ouX509SerialNumber,
117 ouX509Cert,
118 ouX509CertDigest);
121 void XMLSignatureHelper::AddEncapsulatedX509Certificate(const OUString& ouEncapsulatedX509Certificate)
123 mpXSecController->addEncapsulatedX509Certificate(ouEncapsulatedX509Certificate);
126 void XMLSignatureHelper::SetDateTime( sal_Int32 nSecurityId, const ::Date& rDate, const tools::Time& rTime )
128 css::util::DateTime stDateTime = ::DateTime(rDate, rTime).GetUNODateTime();
129 mpXSecController->setDate( nSecurityId, stDateTime );
132 void XMLSignatureHelper::SetDescription(sal_Int32 nSecurityId, const OUString& rDescription)
134 mpXSecController->setDescription(nSecurityId, rDescription);
137 void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const OUString& uri, const OUString& objectURL, bool bBinary, bool bXAdESCompliantIfODF )
139 mpXSecController->signAStream( nSecurityId, uri, objectURL, bBinary, bXAdESCompliantIfODF );
143 uno::Reference<xml::sax::XWriter> XMLSignatureHelper::CreateDocumentHandlerWithHeader(
144 const css::uno::Reference< css::io::XOutputStream >& xOutputStream )
147 * get SAX writer component
149 uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
150 uno::Reference< xml::sax::XWriter > xSaxWriter = xml::sax::Writer::create(mxCtx);
153 * connect XML writer to output stream
155 xSaxWriter->setOutputStream( xOutputStream );
158 * write the xml context for signatures
160 SvXMLAttributeList *pAttributeList = new SvXMLAttributeList();
161 OUString sNamespace;
162 if (mbODFPre1_2)
163 sNamespace = NS_DOCUMENTSIGNATURES;
164 else
165 sNamespace = NS_DOCUMENTSIGNATURES_ODF_1_2;
167 pAttributeList->AddAttribute(
168 "xmlns",
169 sNamespace);
171 xSaxWriter->startDocument();
172 xSaxWriter->startElement(
173 "document-signatures",
174 uno::Reference< css::xml::sax::XAttributeList > (pAttributeList));
176 return xSaxWriter;
179 void XMLSignatureHelper::CloseDocumentHandler( const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler )
181 xDocumentHandler->endElement( "document-signatures" );
182 xDocumentHandler->endDocument();
185 void XMLSignatureHelper::ExportSignature(
186 const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler,
187 const SignatureInformation& signatureInfo,
188 bool bXAdESCompliantIfODF )
190 XSecController::exportSignature(xDocumentHandler, signatureInfo, bXAdESCompliantIfODF);
193 void XMLSignatureHelper::ExportOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<embed::XStorage>& xSignatureStorage, const SignatureInformation& rInformation, int nSignatureIndex)
195 sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
196 uno::Reference<io::XOutputStream> xOutputStream(xSignatureStorage->openStreamElement("sig" + OUString::number(nSignatureIndex) + ".xml", nOpenMode), uno::UNO_QUERY);
198 if (rInformation.aSignatureBytes.hasElements())
199 // This is a signature roundtrip, just write back the signature as-is.
200 xOutputStream->writeBytes(rInformation.aSignatureBytes);
201 else
203 uno::Reference<xml::sax::XWriter> xSaxWriter = xml::sax::Writer::create(mxCtx);
204 xSaxWriter->setOutputStream(xOutputStream);
205 xSaxWriter->startDocument();
207 uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY);
208 mpXSecController->exportOOXMLSignature(xRootStorage, xDocumentHandler, rInformation);
210 xSaxWriter->endDocument();
214 bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler, bool bXAdESCompliantIfODF )
216 mbError = false;
218 if ( !mpXSecController->WriteSignature( xDocumentHandler, bXAdESCompliantIfODF ) )
220 mbError = true;
223 return !mbError;
226 bool XMLSignatureHelper::ReadAndVerifySignature( const css::uno::Reference< css::io::XInputStream >& xInputStream )
228 mbError = false;
230 SAL_WARN_IF(!xInputStream.is(), "xmlsecurity.helper", "input stream missing");
233 * prepare ParserInputSrouce
235 xml::sax::InputSource aParserInput;
236 aParserInput.aInputStream = xInputStream;
239 * get SAX parser component
241 uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(mxCtx);
244 * create a signature reader
246 uno::Reference< xml::sax::XDocumentHandler > xHandler
247 = mpXSecController->createSignatureReader( );
250 * create a signature listener
252 ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener(
253 LINK( this, XMLSignatureHelper, SignatureCreationResultListener ),
254 LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ),
255 LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) );
258 * configure the signature verify listener
262 * setup the connection:
263 * Parser -> SignatureListener -> SignatureReader
265 pSignatureListener->setNextHandler(xHandler);
266 xParser->setDocumentHandler( pSignatureListener );
269 * parser the stream
273 xParser->parseStream( aParserInput );
275 catch( uno::Exception& )
277 mbError = true;
281 * clear up the connection
283 pSignatureListener->setNextHandler( nullptr );
286 * clear up the signature verify listener
290 * release the signature reader
292 mpXSecController->releaseSignatureReader( );
294 return !mbError;
297 SignatureInformation XMLSignatureHelper::GetSignatureInformation( sal_Int32 nSecurityId ) const
299 return mpXSecController->getSignatureInformation( nSecurityId );
302 SignatureInformations XMLSignatureHelper::GetSignatureInformations() const
304 return mpXSecController->getSignatureInformations();
307 IMPL_LINK( XMLSignatureHelper, SignatureCreationResultListener, XMLSignatureCreationResult&, rResult, void )
309 maCreationResults.insert( maCreationResults.begin() + maCreationResults.size(), rResult );
310 if ( rResult.nSignatureCreationResult != css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
311 mbError = true;
314 IMPL_LINK( XMLSignatureHelper, SignatureVerifyResultListener, XMLSignatureVerifyResult&, rResult, void )
316 maVerifyResults.insert( maVerifyResults.begin() + maVerifyResults.size(), rResult );
317 if ( rResult.nSignatureVerifyResult != css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
318 mbError = true;
321 IMPL_LINK_NOARG( XMLSignatureHelper, StartVerifySignatureElement, LinkParamNone*, void )
323 if ( !maStartVerifySignatureHdl.IsSet() || maStartVerifySignatureHdl.Call(nullptr) )
325 sal_Int32 nSignatureId = mpXSecController->getNewSecurityId();
326 mpXSecController->addSignature( nSignatureId );
330 namespace
332 bool lcl_isSignatureType(const beans::StringPair& rPair)
334 return rPair.First == "Type" && rPair.Second == OOXML_SIGNATURE_SIGNATURE;
336 bool lcl_isSignatureOriginType(const beans::StringPair& rPair)
338 return rPair.First == "Type" && rPair.Second == OOXML_SIGNATURE_ORIGIN;
342 bool XMLSignatureHelper::ReadAndVerifySignatureStorage(const uno::Reference<embed::XStorage>& xStorage, bool bCacheLastSignature)
344 sal_Int32 nOpenMode = embed::ElementModes::READ;
345 uno::Reference<container::XNameAccess> xNameAccess(xStorage, uno::UNO_QUERY);
346 if (xNameAccess.is() && !xNameAccess->hasByName("_rels"))
348 SAL_WARN("xmlsecurity.helper", "expected stream, in signature storage but not found: _rels");
349 return false;
352 uno::Reference<embed::XStorage> xSubStorage = xStorage->openStorageElement("_rels", nOpenMode);
353 uno::Reference<io::XInputStream> xRelStream(xSubStorage->openStreamElement("origin.sigs.rels", nOpenMode), uno::UNO_QUERY);
354 uno::Sequence< uno::Sequence<beans::StringPair> > aRelationsInfo;
355 aRelationsInfo = comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(xRelStream, "origin.sigs.rels", mxCtx);
357 for (sal_Int32 i = 0; i < aRelationsInfo.getLength(); ++i)
359 const uno::Sequence<beans::StringPair>& rRelation = aRelationsInfo[i];
360 auto aRelation = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rRelation);
361 if (std::find_if(aRelation.begin(), aRelation.end(), lcl_isSignatureType) != aRelation.end())
363 std::vector<beans::StringPair>::iterator it = std::find_if(aRelation.begin(), aRelation.end(), [](const beans::StringPair& rPair) { return rPair.First == "Target"; });
364 if (it != aRelation.end())
366 if (xNameAccess.is() && !xNameAccess->hasByName(it->Second))
368 SAL_WARN("xmlsecurity.helper", "expected stream, but not found: " << it->Second);
369 continue;
372 uno::Reference<io::XInputStream> xInputStream(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY);
373 if (!ReadAndVerifySignatureStorageStream(xInputStream))
374 return false;
376 // By default, we cache. If it's requested, then we don't cache the last signature.
377 bool bCache = true;
378 if (!bCacheLastSignature && i == aRelationsInfo.getLength() - 1)
379 bCache = false;
381 if (bCache)
383 // Store the contents of the stream as is, in case we need to write it back later.
384 xInputStream.clear();
385 xInputStream.set(xStorage->openStreamElement(it->Second, nOpenMode), uno::UNO_QUERY);
386 uno::Reference<beans::XPropertySet> xPropertySet(xInputStream, uno::UNO_QUERY);
387 if (xPropertySet.is())
389 sal_Int64 nSize = 0;
390 xPropertySet->getPropertyValue("Size") >>= nSize;
391 uno::Sequence<sal_Int8> aData;
392 xInputStream->readBytes(aData, nSize);
393 mpXSecController->setSignatureBytes(aData);
400 return true;
403 bool XMLSignatureHelper::ReadAndVerifySignatureStorageStream(const css::uno::Reference<css::io::XInputStream>& xInputStream)
405 mbError = false;
407 // Create the input source.
408 xml::sax::InputSource aParserInput;
409 aParserInput.aInputStream = xInputStream;
411 // Create the sax parser.
412 uno::Reference<xml::sax::XParser> xParser = xml::sax::Parser::create(mxCtx);
414 // Create the signature reader.
415 uno::Reference<xml::sax::XDocumentHandler> xHandler = mpXSecController->createSignatureReader(embed::StorageFormats::OFOPXML);
417 // Create the signature listener.
418 ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener(
419 LINK(this, XMLSignatureHelper, SignatureCreationResultListener),
420 LINK(this, XMLSignatureHelper, SignatureVerifyResultListener),
421 LINK(this, XMLSignatureHelper, StartVerifySignatureElement));
422 uno::Reference<xml::sax::XDocumentHandler> xSignatureListener(pSignatureListener);
424 // Parser -> signature listener -> signature reader.
425 pSignatureListener->setNextHandler(xHandler);
426 xParser->setDocumentHandler(xSignatureListener);
428 // Parse the stream.
431 xParser->parseStream(aParserInput);
433 catch(const uno::Exception& rException)
435 SAL_WARN("xmlsecurity.helper", "XMLSignatureHelper::ReadAndVerifySignatureStorageStream: " << rException.Message);
438 pSignatureListener->setNextHandler(nullptr);
439 mpXSecController->releaseSignatureReader();
441 return !mbError;
444 void XMLSignatureHelper::EnsureSignaturesRelation(const css::uno::Reference<css::embed::XStorage>& xStorage, bool bAdd)
446 sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
447 uno::Reference<embed::XStorage> xSubStorage = xStorage->openStorageElement("_rels", nOpenMode);
448 uno::Reference<io::XInputStream> xRelStream(xSubStorage->openStreamElement(".rels", nOpenMode), uno::UNO_QUERY);
449 std::vector< uno::Sequence<beans::StringPair> > aRelationsInfo;
450 aRelationsInfo = comphelper::sequenceToContainer< std::vector< uno::Sequence<beans::StringPair> > >(comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(xRelStream, ".rels", mxCtx));
452 // Do we have a relation already?
453 bool bHaveRelation = false;
454 int nCount = 0;
455 for (const uno::Sequence<beans::StringPair>& rRelation : aRelationsInfo)
457 auto aRelation = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rRelation);
458 if (std::find_if(aRelation.begin(), aRelation.end(), lcl_isSignatureOriginType) != aRelation.end())
460 bHaveRelation = true;
461 break;
463 ++nCount;
466 if (!bHaveRelation && bAdd)
468 // No, and have to add one.
469 std::vector<beans::StringPair> aRelation;
470 aRelation.push_back(beans::StringPair("Id", "rId" + OUString::number(++nCount)));
471 aRelation.push_back(beans::StringPair("Type", OOXML_SIGNATURE_ORIGIN));
472 aRelation.push_back(beans::StringPair("Target", "_xmlsignatures/origin.sigs"));
473 aRelationsInfo.push_back(comphelper::containerToSequence(aRelation));
475 else if (bHaveRelation && !bAdd)
477 // Yes, and need to remove it.
478 for (std::vector< uno::Sequence<beans::StringPair> >::iterator it = aRelationsInfo.begin(); it != aRelationsInfo.end();)
480 auto aRelation = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(*it);
481 if (std::find_if(aRelation.begin(), aRelation.end(), lcl_isSignatureOriginType) != aRelation.end())
482 it = aRelationsInfo.erase(it);
483 else
484 ++it;
488 // Write it back.
489 uno::Reference<io::XTruncate> xTruncate(xRelStream, uno::UNO_QUERY);
490 xTruncate->truncate();
491 uno::Reference<io::XOutputStream> xOutputStream(xRelStream, uno::UNO_QUERY);
492 comphelper::OFOPXMLHelper::WriteRelationsInfoSequence(xOutputStream, comphelper::containerToSequence(aRelationsInfo), mxCtx);
494 // Commit it.
495 uno::Reference<embed::XTransactedObject> xTransact(xSubStorage, uno::UNO_QUERY);
496 xTransact->commit();
497 xTransact.set(xStorage, uno::UNO_QUERY);
498 xTransact->commit();
501 void XMLSignatureHelper::ExportSignatureRelations(const css::uno::Reference<css::embed::XStorage>& xStorage, int nSignatureCount)
503 // Write the empty file, its relations will be the signatures.
504 sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
505 uno::Reference<io::XOutputStream> xOriginStream(xStorage->openStreamElement("origin.sigs", nOpenMode), uno::UNO_QUERY);
506 uno::Reference<io::XTruncate> xTruncate(xOriginStream, uno::UNO_QUERY);
507 xTruncate->truncate();
508 xOriginStream->closeOutput();
510 // Write the relations.
511 uno::Reference<embed::XStorage> xSubStorage(xStorage->openStorageElement("_rels", nOpenMode), uno::UNO_QUERY);
512 uno::Reference<io::XOutputStream> xRelStream(xSubStorage->openStreamElement("origin.sigs.rels", nOpenMode), uno::UNO_QUERY);
513 std::vector< uno::Sequence<beans::StringPair> > aRelations;
514 for (int i = 0; i < nSignatureCount; ++i)
516 std::vector<beans::StringPair> aRelation;
517 aRelation.push_back(beans::StringPair("Id", "rId" + OUString::number(i + 1)));
518 aRelation.push_back(beans::StringPair("Type", OOXML_SIGNATURE_SIGNATURE));
519 aRelation.push_back(beans::StringPair("Target", "sig" + OUString::number(i + 1) + ".xml"));
520 aRelations.push_back(comphelper::containerToSequence(aRelation));
522 comphelper::OFOPXMLHelper::WriteRelationsInfoSequence(xRelStream, comphelper::containerToSequence(aRelations), mxCtx);
523 uno::Reference<embed::XTransactedObject> xTransact(xSubStorage, uno::UNO_QUERY);
524 xTransact->commit();
527 void XMLSignatureHelper::ExportSignatureContentTypes(const css::uno::Reference<css::embed::XStorage>& xStorage, int nSignatureCount)
529 sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
530 uno::Reference<io::XStream> xStream(xStorage->openStreamElement("[Content_Types].xml", nOpenMode), uno::UNO_QUERY);
531 uno::Reference<io::XInputStream> xInputStream = xStream->getInputStream();
532 uno::Sequence< uno::Sequence<beans::StringPair> > aContentTypeInfo = comphelper::OFOPXMLHelper::ReadContentTypeSequence(xInputStream, mxCtx);
533 if (aContentTypeInfo.getLength() < 2)
535 SAL_WARN("xmlsecurity.helper", "no defaults or overrides in aContentTypeInfo");
536 return;
539 // Append rels and sigs to defaults, if it's not there already.
540 uno::Sequence<beans::StringPair>& rDefaults = aContentTypeInfo[0];
541 auto aDefaults = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rDefaults);
542 auto it = std::find_if(rDefaults.begin(), rDefaults.end(), [](const beans::StringPair& rPair)
544 return rPair.First == "rels";
546 if (it == rDefaults.end())
547 aDefaults.push_back(beans::StringPair("rels", "application/vnd.openxmlformats-package.relationships+xml"));
549 it = std::find_if(rDefaults.begin(), rDefaults.end(), [](const beans::StringPair& rPair)
551 return rPair.First == "sigs";
553 if (it == rDefaults.end())
554 aDefaults.push_back(beans::StringPair("sigs", "application/vnd.openxmlformats-package.digital-signature-origin"));
555 rDefaults = comphelper::containerToSequence(aDefaults);
557 // Remove existing signature overrides.
558 uno::Sequence<beans::StringPair>& rOverrides = aContentTypeInfo[1];
559 auto aOverrides = comphelper::sequenceToContainer< std::vector<beans::StringPair> >(rOverrides);
560 aOverrides.erase(std::remove_if(aOverrides.begin(), aOverrides.end(), [](const beans::StringPair& rPair)
562 return rPair.First.startsWith("/_xmlsignatures/sig");
563 }), aOverrides.end());
565 // Add our signature overrides.
566 for (int i = 1; i <= nSignatureCount; ++i)
567 aOverrides.push_back(beans::StringPair("/_xmlsignatures/sig" + OUString::number(i) + ".xml", "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml"));
569 rOverrides = comphelper::containerToSequence(aOverrides);
570 uno::Reference<io::XOutputStream> xOutputStream = xStream->getOutputStream();
571 uno::Reference <io::XTruncate> xTruncate(xOutputStream, uno::UNO_QUERY);
572 xTruncate->truncate();
573 comphelper::OFOPXMLHelper::WriteContentSequence(xOutputStream, rDefaults, rOverrides, mxCtx);
574 uno::Reference<embed::XTransactedObject> xTransact(xStorage, uno::UNO_QUERY);
575 xTransact->commit();
577 bool XMLSignatureHelper::CreateAndWriteOOXMLSignature(const uno::Reference<embed::XStorage>& xRootStorage, const uno::Reference<embed::XStorage>& xSignatureStorage, int nSignatureIndex)
579 sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
580 uno::Reference<io::XOutputStream> xOutputStream(xSignatureStorage->openStreamElement("sig" + OUString::number(nSignatureIndex) + ".xml", nOpenMode), uno::UNO_QUERY);
581 uno::Reference<xml::sax::XWriter> xSaxWriter = xml::sax::Writer::create(mxCtx);
582 xSaxWriter->setOutputStream(xOutputStream);
583 xSaxWriter->startDocument();
585 mbError = false;
586 uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY);
587 if (!mpXSecController->WriteOOXMLSignature(xRootStorage, xDocumentHandler))
588 mbError = true;
590 xSaxWriter->endDocument();
592 return !mbError;
595 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */