1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
);
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(
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();
163 sNamespace
= NS_DOCUMENTSIGNATURES
;
165 sNamespace
= NS_DOCUMENTSIGNATURES_ODF_1_2
;
167 pAttributeList
->AddAttribute(
171 xSaxWriter
->startDocument();
172 xSaxWriter
->startElement(
173 "document-signatures",
174 uno::Reference
< css::xml::sax::XAttributeList
> (pAttributeList
));
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
);
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
)
218 if ( !mpXSecController
->WriteSignature( xDocumentHandler
, bXAdESCompliantIfODF
) )
226 bool XMLSignatureHelper::ReadAndVerifySignature( const css::uno::Reference
< css::io::XInputStream
>& xInputStream
)
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
);
273 xParser
->parseStream( aParserInput
);
275 catch( uno::Exception
& )
281 * clear up the connection
283 pSignatureListener
->setNextHandler( nullptr );
286 * clear up the signature verify listener
290 * release the signature reader
292 mpXSecController
->releaseSignatureReader( );
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
)
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
)
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
);
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");
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
);
372 uno::Reference
<io::XInputStream
> xInputStream(xStorage
->openStreamElement(it
->Second
, nOpenMode
), uno::UNO_QUERY
);
373 if (!ReadAndVerifySignatureStorageStream(xInputStream
))
376 // By default, we cache. If it's requested, then we don't cache the last signature.
378 if (!bCacheLastSignature
&& i
== aRelationsInfo
.getLength() - 1)
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())
390 xPropertySet
->getPropertyValue("Size") >>= nSize
;
391 uno::Sequence
<sal_Int8
> aData
;
392 xInputStream
->readBytes(aData
, nSize
);
393 mpXSecController
->setSignatureBytes(aData
);
403 bool XMLSignatureHelper::ReadAndVerifySignatureStorageStream(const css::uno::Reference
<css::io::XInputStream
>& xInputStream
)
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
);
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();
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;
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;
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
);
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
);
495 uno::Reference
<embed::XTransactedObject
> xTransact(xSubStorage
, uno::UNO_QUERY
);
497 xTransact
.set(xStorage
, uno::UNO_QUERY
);
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
);
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");
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
);
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();
586 uno::Reference
<xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
, uno::UNO_QUERY
);
587 if (!mpXSecController
->WriteOOXMLSignature(xRootStorage
, xDocumentHandler
))
590 xSaxWriter
->endDocument();
595 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */