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 .
20 #include <documentsignaturemanager.hxx>
21 #include <config_gpgme.h>
23 #include <gpg/SEInitializer.hxx>
25 #include <com/sun/star/embed/StorageFormats.hpp>
26 #include <com/sun/star/embed/ElementModes.hpp>
27 #include <com/sun/star/io/TempFile.hpp>
28 #include <com/sun/star/io/XTruncate.hpp>
29 #include <com/sun/star/embed/XTransactedObject.hpp>
30 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <com/sun/star/graphic/XGraphic.hpp>
34 #include <comphelper/base64.hxx>
35 #include <comphelper/storagehelper.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <sax/tools/converter.hxx>
38 #include <tools/datetime.hxx>
39 #include <o3tl/make_unique.hxx>
41 #include <certificate.hxx>
42 #include <biginteger.hxx>
44 #include <xmlsec/xmlsec_init.hxx>
46 #include <pdfsignaturehelper.hxx>
49 using namespace css::graphic
;
50 using namespace css::uno
;
52 DocumentSignatureManager::DocumentSignatureManager(
53 const uno::Reference
<uno::XComponentContext
>& xContext
, DocumentSignatureMode eMode
)
55 , maSignatureHelper(xContext
)
56 , meSignatureMode(eMode
)
60 DocumentSignatureManager::~DocumentSignatureManager() { deInitXmlSec(); }
62 bool DocumentSignatureManager::init()
64 SAL_WARN_IF(mxSEInitializer
.is(), "xmlsecurity.helper",
65 "DocumentSignatureManager::Init - mxSEInitializer already set!");
66 SAL_WARN_IF(mxSecurityContext
.is(), "xmlsecurity.helper",
67 "DocumentSignatureManager::Init - mxSecurityContext already set!");
68 SAL_WARN_IF(mxGpgSEInitializer
.is(), "xmlsecurity.helper",
69 "DocumentSignatureManager::Init - mxGpgSEInitializer already set!");
71 // xmlsec is needed by both services, so init before those
74 mxSEInitializer
= xml::crypto::SEInitializer::create(mxContext
);
75 #if HAVE_FEATURE_GPGME
76 mxGpgSEInitializer
.set(new SEInitializerGpg());
79 if (mxSEInitializer
.is())
80 mxSecurityContext
= mxSEInitializer
->createSecurityContext(OUString());
82 #if HAVE_FEATURE_GPGME
83 if (mxGpgSEInitializer
.is())
84 mxGpgSecurityContext
= mxGpgSEInitializer
->createSecurityContext(OUString());
86 return mxSecurityContext
.is() || mxGpgSecurityContext
.is();
88 return mxSecurityContext
.is();
92 PDFSignatureHelper
& DocumentSignatureManager::getPDFSignatureHelper()
95 if (!mxSecurityContext
.is())
98 SAL_WARN_IF(!bInit
, "xmlsecurity.comp", "Error initializing security context!");
100 if (!mpPDFSignatureHelper
)
101 mpPDFSignatureHelper
= o3tl::make_unique
<PDFSignatureHelper
>();
103 return *mpPDFSignatureHelper
;
106 #if 0 // For some reason does not work
107 bool DocumentSignatureManager::IsXAdESRelevant()
111 // ZIP-based: ODF or OOXML.
112 maSignatureHelper
.StartMission();
114 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(embed::ElementModes::READ
, /*bUseTempStream=*/true);
115 if (aStreamHelper
.nStorageFormat
== embed::StorageFormats::OFOPXML
)
117 maSignatureHelper
.EndMission();
120 // FIXME: How to figure out if it is ODF 1.2?
121 maSignatureHelper
.EndMission();
128 /* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
129 We use the manifest to find out if a file is xml and if it is encrypted.
130 The parameter is an encoded uri. However, the manifest contains paths. Therefore
131 the path is encoded as uri, so they can be compared.
133 bool DocumentSignatureManager::isXML(const OUString
& rURI
)
135 SAL_WARN_IF(!mxStore
.is(), "xmlsecurity.helper", "empty storage reference");
138 bool bPropsAvailable
= false;
139 const OUString
sPropFullPath("FullPath");
140 const OUString
sPropMediaType("MediaType");
141 const OUString
sPropDigest("Digest");
143 for (int i
= 0; i
< m_manifest
.getLength(); i
++)
145 const uno::Sequence
<beans::PropertyValue
>& entry
= m_manifest
[i
];
146 OUString sPath
, sMediaType
;
147 bool bEncrypted
= false;
148 for (int j
= 0; j
< entry
.getLength(); j
++)
150 const beans::PropertyValue
& prop
= entry
[j
];
152 if (prop
.Name
== sPropFullPath
)
153 prop
.Value
>>= sPath
;
154 else if (prop
.Name
== sPropMediaType
)
155 prop
.Value
>>= sMediaType
;
156 else if (prop
.Name
== sPropDigest
)
159 if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI
, sPath
))
161 bIsXML
= sMediaType
== "text/xml" && !bEncrypted
;
162 bPropsAvailable
= true;
166 if (!bPropsAvailable
)
168 //This would be the case for at least mimetype, META-INF/manifest.xml
169 //META-INF/macrosignatures.xml.
170 //Files can only be encrypted if they are in the manifest.xml.
171 //That is, the current file cannot be encrypted, otherwise bPropsAvailable
173 sal_Int32 nSep
= rURI
.lastIndexOf('.');
176 OUString aExt
= rURI
.copy(nSep
+ 1);
177 if (aExt
.equalsIgnoreAsciiCase("XML"))
184 //If bTempStream is true, then a temporary stream is return. If it is false then, the actual
185 //signature stream is used.
186 //Every time the user presses Add a new temporary stream is created.
187 //We keep the temporary stream as member because ImplGetSignatureInformations
188 //will later access the stream to create DocumentSignatureInformation objects
189 //which are stored in maCurrentSignatureInformations.
190 SignatureStreamHelper
DocumentSignatureManager::ImplOpenSignatureStream(sal_Int32 nStreamOpenMode
,
193 SignatureStreamHelper aHelper
;
196 uno::Reference
<container::XNameAccess
> xNameAccess(mxStore
, uno::UNO_QUERY
);
197 if (xNameAccess
.is() && xNameAccess
->hasByName("[Content_Types].xml"))
198 aHelper
.nStorageFormat
= embed::StorageFormats::OFOPXML
;
203 if (nStreamOpenMode
& embed::ElementModes::TRUNCATE
)
205 //We write always into a new temporary stream.
206 mxTempSignatureStream
.set(io::TempFile::create(mxContext
), uno::UNO_QUERY_THROW
);
207 if (aHelper
.nStorageFormat
!= embed::StorageFormats::OFOPXML
)
208 aHelper
.xSignatureStream
= mxTempSignatureStream
;
211 mxTempSignatureStorage
= comphelper::OStorageHelper::GetStorageOfFormatFromStream(
212 ZIP_STORAGE_FORMAT_STRING
, mxTempSignatureStream
);
213 aHelper
.xSignatureStorage
= mxTempSignatureStorage
;
218 //When we read from the temp stream, then we must have previously
220 SAL_WARN_IF(!mxTempSignatureStream
.is(), "xmlsecurity.helper",
221 "empty temp. signature stream reference");
223 aHelper
.xSignatureStream
= mxTempSignatureStream
;
224 if (aHelper
.nStorageFormat
== embed::StorageFormats::OFOPXML
)
225 aHelper
.xSignatureStorage
= mxTempSignatureStorage
;
229 //No temporary stream
230 if (!mxSignatureStream
.is())
232 //We may not have a dedicated stream for writing the signature
233 //So we take one directly from the storage
234 //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
235 //in which case Add/Remove is not allowed. This is done, for example, if the
236 //document is readonly
237 aHelper
= DocumentSignatureHelper::OpenSignatureStream(mxStore
, nStreamOpenMode
,
242 aHelper
.xSignatureStream
= mxSignatureStream
;
246 if (nStreamOpenMode
& embed::ElementModes::TRUNCATE
)
248 if (aHelper
.xSignatureStream
.is()
249 && aHelper
.nStorageFormat
!= embed::StorageFormats::OFOPXML
)
251 uno::Reference
<io::XTruncate
> xTruncate(aHelper
.xSignatureStream
, uno::UNO_QUERY_THROW
);
252 xTruncate
->truncate();
255 else if (bTempStream
|| mxSignatureStream
.is())
257 //In case we read the signature stream from the storage directly,
258 //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
259 //then XSeakable is not supported
260 uno::Reference
<io::XSeekable
> xSeek(aHelper
.xSignatureStream
, uno::UNO_QUERY_THROW
);
267 bool DocumentSignatureManager::add(
268 const uno::Reference
<security::XCertificate
>& xCert
,
269 const uno::Reference
<xml::crypto::XXMLSecurityContext
>& xSecurityContext
,
270 const OUString
& rDescription
, sal_Int32
& nSecurityId
, bool bAdESCompliant
,
271 const OUString
& rSignatureLineId
, const Reference
<XGraphic
> xValidGraphic
,
272 const Reference
<XGraphic
> xInvalidGraphic
)
276 SAL_WARN("xmlsecurity.helper", "no certificate selected");
281 uno::Reference
<lang::XServiceInfo
> xServiceInfo(xSecurityContext
, uno::UNO_QUERY
);
282 if (xServiceInfo
->getImplementationName()
283 == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
285 // GPG keys only really have PGPKeyId and PGPKeyPacket
288 SAL_WARN("xmlsecurity.helper", "cannot sign pdfs with GPG keys");
292 maSignatureHelper
.StartMission(xSecurityContext
);
294 nSecurityId
= maSignatureHelper
.GetNewSecurityId();
296 OUStringBuffer aStrBuffer
;
297 comphelper::Base64::encode(aStrBuffer
, xCert
->getEncoded());
300 if (auto pCertificate
= dynamic_cast<xmlsecurity::Certificate
*>(xCert
.get()))
302 OUStringBuffer aBuffer
;
303 comphelper::Base64::encode(aBuffer
, pCertificate
->getSHA256Thumbprint());
304 aKeyId
= aBuffer
.makeStringAndClear();
307 SAL_WARN("xmlsecurity.helper",
308 "XCertificate implementation without an xmlsecurity::Certificate one");
310 maSignatureHelper
.SetGpgCertificate(nSecurityId
, aKeyId
, aStrBuffer
.makeStringAndClear(),
311 xCert
->getIssuerName());
315 OUString aCertSerial
= xmlsecurity::bigIntegerToNumericString(xCert
->getSerialNumber());
316 if (aCertSerial
.isEmpty())
318 SAL_WARN("xmlsecurity.helper", "Error in Certificate, problem with serial number!");
324 // Something not ZIP based, try PDF.
325 nSecurityId
= getPDFSignatureHelper().GetNewSecurityId();
326 getPDFSignatureHelper().SetX509Certificate(xCert
);
327 getPDFSignatureHelper().SetDescription(rDescription
);
328 uno::Reference
<io::XInputStream
> xInputStream(mxSignatureStream
, uno::UNO_QUERY
);
329 if (!getPDFSignatureHelper().Sign(xInputStream
, bAdESCompliant
))
331 SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::Sign() failed");
337 maSignatureHelper
.StartMission(xSecurityContext
);
339 nSecurityId
= maSignatureHelper
.GetNewSecurityId();
341 OUStringBuffer aStrBuffer
;
342 comphelper::Base64::encode(aStrBuffer
, xCert
->getEncoded());
344 OUString aCertDigest
;
345 svl::crypto::SignatureMethodAlgorithm eAlgorithmID
346 = svl::crypto::SignatureMethodAlgorithm::RSA
;
347 if (auto pCertificate
= dynamic_cast<xmlsecurity::Certificate
*>(xCert
.get()))
349 OUStringBuffer aBuffer
;
350 comphelper::Base64::encode(aBuffer
, pCertificate
->getSHA256Thumbprint());
351 aCertDigest
= aBuffer
.makeStringAndClear();
353 eAlgorithmID
= pCertificate
->getSignatureMethodAlgorithm();
356 SAL_WARN("xmlsecurity.helper",
357 "XCertificate implementation without an xmlsecurity::Certificate one");
359 maSignatureHelper
.SetX509Certificate(nSecurityId
, xCert
->getIssuerName(), aCertSerial
,
360 aStrBuffer
.makeStringAndClear(), aCertDigest
,
364 uno::Sequence
<uno::Reference
<security::XCertificate
>> aCertPath
365 = xSecurityContext
->getSecurityEnvironment()->buildCertificatePath(xCert
);
366 const uno::Reference
<security::XCertificate
>* pCertPath
= aCertPath
.getConstArray();
367 sal_Int32 nCnt
= aCertPath
.getLength();
369 OUStringBuffer aStrBuffer
;
370 for (int i
= 0; i
< nCnt
; i
++)
372 comphelper::Base64::encode(aStrBuffer
, pCertPath
[i
]->getEncoded());
373 maSignatureHelper
.AddEncapsulatedX509Certificate(aStrBuffer
.makeStringAndClear());
376 std::vector
<OUString
> aElements
= DocumentSignatureHelper::CreateElementList(
377 mxStore
, meSignatureMode
, DocumentSignatureAlgorithm::OOo3_2
);
378 DocumentSignatureHelper::AppendContentTypes(mxStore
, aElements
);
380 sal_Int32 nElements
= aElements
.size();
381 for (sal_Int32 n
= 0; n
< nElements
; n
++)
383 bool bBinaryMode
= !isXML(aElements
[n
]);
384 maSignatureHelper
.AddForSigning(nSecurityId
, aElements
[n
], bBinaryMode
, bAdESCompliant
);
387 maSignatureHelper
.SetDateTime(nSecurityId
, DateTime(DateTime::SYSTEM
));
388 maSignatureHelper
.SetDescription(nSecurityId
, rDescription
);
390 if (!rSignatureLineId
.isEmpty())
391 maSignatureHelper
.SetSignatureLineId(nSecurityId
, rSignatureLineId
);
393 if (xValidGraphic
.is())
394 maSignatureHelper
.SetSignatureLineValidGraphic(nSecurityId
, xValidGraphic
);
396 if (xInvalidGraphic
.is())
397 maSignatureHelper
.SetSignatureLineInvalidGraphic(nSecurityId
, xInvalidGraphic
);
399 // We open a signature stream in which the existing and the new
400 //signature is written. ImplGetSignatureInformation (later in this function) will
401 //then read the stream and fill maCurrentSignatureInformations. The final signature
402 //is written when the user presses OK. Then only maCurrentSignatureInformation and
403 //a sax writer are used to write the information.
404 SignatureStreamHelper aStreamHelper
405 = ImplOpenSignatureStream(embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
, true);
407 if (aStreamHelper
.nStorageFormat
!= embed::StorageFormats::OFOPXML
)
409 uno::Reference
<io::XOutputStream
> xOutputStream(aStreamHelper
.xSignatureStream
,
410 uno::UNO_QUERY_THROW
);
411 uno::Reference
<xml::sax::XWriter
> xSaxWriter
412 = maSignatureHelper
.CreateDocumentHandlerWithHeader(xOutputStream
);
414 // Export old signatures...
415 uno::Reference
<xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
,
416 uno::UNO_QUERY_THROW
);
417 std::size_t nInfos
= maCurrentSignatureInformations
.size();
418 for (std::size_t n
= 0; n
< nInfos
; n
++)
419 XMLSignatureHelper::ExportSignature(xDocumentHandler
, maCurrentSignatureInformations
[n
],
422 // Create a new one...
423 maSignatureHelper
.CreateAndWriteSignature(xDocumentHandler
, bAdESCompliant
);
426 XMLSignatureHelper::CloseDocumentHandler(xDocumentHandler
);
433 maSignatureHelper
.EnsureSignaturesRelation(mxStore
, /*bAdd=*/true);
434 // Old signatures + the new one.
435 int nSignatureCount
= maCurrentSignatureInformations
.size() + 1;
436 maSignatureHelper
.ExportSignatureRelations(aStreamHelper
.xSignatureStorage
,
439 // Export old signatures.
440 for (std::size_t i
= 0; i
< maCurrentSignatureInformations
.size(); ++i
)
441 maSignatureHelper
.ExportOOXMLSignature(mxStore
, aStreamHelper
.xSignatureStorage
,
442 maCurrentSignatureInformations
[i
], i
+ 1);
444 // Create a new signature.
445 maSignatureHelper
.CreateAndWriteOOXMLSignature(mxStore
, aStreamHelper
.xSignatureStorage
,
449 uno::Reference
<embed::XTransactedObject
> xTransact(aStreamHelper
.xSignatureStorage
,
452 uno::Reference
<io::XOutputStream
> xOutputStream(aStreamHelper
.xSignatureStream
,
454 xOutputStream
->closeOutput();
456 uno::Reference
<io::XTempFile
> xTempFile(aStreamHelper
.xSignatureStream
, uno::UNO_QUERY
);
457 SAL_INFO("xmlsecurity.helper",
458 "DocumentSignatureManager::add temporary storage at " << xTempFile
->getUri());
461 maSignatureHelper
.EndMission();
465 void DocumentSignatureManager::remove(sal_uInt16 nPosition
)
469 // Something not ZIP based, try PDF.
470 uno::Reference
<io::XInputStream
> xInputStream(mxSignatureStream
, uno::UNO_QUERY
);
471 if (!PDFSignatureHelper::RemoveSignature(xInputStream
, nPosition
))
473 SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::RemoveSignature() failed");
477 // Only erase when the removal was successful, it may fail for PDF.
478 // Also, erase the requested and all following signatures, as PDF signatures are always chained.
479 maCurrentSignatureInformations
.erase(maCurrentSignatureInformations
.begin() + nPosition
,
480 maCurrentSignatureInformations
.end());
484 maCurrentSignatureInformations
.erase(maCurrentSignatureInformations
.begin() + nPosition
);
486 // Export all other signatures...
487 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
488 embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
, /*bTempStream=*/true);
490 if (aStreamHelper
.nStorageFormat
!= embed::StorageFormats::OFOPXML
)
492 uno::Reference
<io::XOutputStream
> xOutputStream(aStreamHelper
.xSignatureStream
,
493 uno::UNO_QUERY_THROW
);
494 uno::Reference
<xml::sax::XWriter
> xSaxWriter
495 = maSignatureHelper
.CreateDocumentHandlerWithHeader(xOutputStream
);
497 uno::Reference
<xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
,
498 uno::UNO_QUERY_THROW
);
499 std::size_t nInfos
= maCurrentSignatureInformations
.size();
500 for (std::size_t n
= 0; n
< nInfos
; ++n
)
501 XMLSignatureHelper::ExportSignature(xDocumentHandler
, maCurrentSignatureInformations
[n
],
504 XMLSignatureHelper::CloseDocumentHandler(xDocumentHandler
);
511 int nSignatureCount
= maCurrentSignatureInformations
.size();
512 maSignatureHelper
.ExportSignatureRelations(aStreamHelper
.xSignatureStorage
,
515 // Export old signatures.
516 for (std::size_t i
= 0; i
< maCurrentSignatureInformations
.size(); ++i
)
517 maSignatureHelper
.ExportOOXMLSignature(mxStore
, aStreamHelper
.xSignatureStorage
,
518 maCurrentSignatureInformations
[i
], i
+ 1);
521 uno::Reference
<embed::XTransactedObject
> xTransact(aStreamHelper
.xSignatureStorage
,
524 uno::Reference
<io::XOutputStream
> xOutputStream(aStreamHelper
.xSignatureStream
,
526 xOutputStream
->closeOutput();
528 uno::Reference
<io::XTempFile
> xTempFile(aStreamHelper
.xSignatureStream
, uno::UNO_QUERY
);
529 SAL_INFO("xmlsecurity.helper", "DocumentSignatureManager::remove: temporary storage is at "
530 << xTempFile
->getUri());
534 void DocumentSignatureManager::read(bool bUseTempStream
, bool bCacheLastSignature
)
536 maCurrentSignatureInformations
.clear();
540 // ZIP-based: ODF or OOXML.
541 maSignatureHelper
.StartMission(mxSecurityContext
);
543 SignatureStreamHelper aStreamHelper
544 = ImplOpenSignatureStream(embed::ElementModes::READ
, bUseTempStream
);
545 if (aStreamHelper
.nStorageFormat
!= embed::StorageFormats::OFOPXML
546 && aStreamHelper
.xSignatureStream
.is())
548 uno::Reference
<io::XInputStream
> xInputStream(aStreamHelper
.xSignatureStream
,
550 maSignatureHelper
.ReadAndVerifySignature(xInputStream
);
552 else if (aStreamHelper
.nStorageFormat
== embed::StorageFormats::OFOPXML
553 && aStreamHelper
.xSignatureStorage
.is())
554 maSignatureHelper
.ReadAndVerifySignatureStorage(aStreamHelper
.xSignatureStorage
,
555 bCacheLastSignature
);
556 maSignatureHelper
.EndMission();
558 maCurrentSignatureInformations
= maSignatureHelper
.GetSignatureInformations();
562 // Something not ZIP based, try PDF.
563 uno::Reference
<io::XInputStream
> xInputStream(mxSignatureStream
, uno::UNO_QUERY
);
564 if (getPDFSignatureHelper().ReadAndVerifySignature(xInputStream
))
565 maCurrentSignatureInformations
= getPDFSignatureHelper().GetSignatureInformations();
569 void DocumentSignatureManager::write(bool bXAdESCompliantIfODF
)
573 // Something not ZIP based, assume PDF, which is written directly in add() already.
577 // Export all other signatures...
578 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
579 embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
, false);
581 if (aStreamHelper
.xSignatureStream
.is()
582 && aStreamHelper
.nStorageFormat
!= embed::StorageFormats::OFOPXML
)
585 uno::Reference
<io::XOutputStream
> xOutputStream(aStreamHelper
.xSignatureStream
,
587 uno::Reference
<xml::sax::XWriter
> xSaxWriter
588 = maSignatureHelper
.CreateDocumentHandlerWithHeader(xOutputStream
);
590 uno::Reference
<xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
,
591 uno::UNO_QUERY_THROW
);
592 std::size_t nInfos
= maCurrentSignatureInformations
.size();
593 for (std::size_t n
= 0; n
< nInfos
; ++n
)
594 XMLSignatureHelper::ExportSignature(xDocumentHandler
, maCurrentSignatureInformations
[n
],
595 bXAdESCompliantIfODF
);
597 XMLSignatureHelper::CloseDocumentHandler(xDocumentHandler
);
599 else if (aStreamHelper
.xSignatureStorage
.is()
600 && aStreamHelper
.nStorageFormat
== embed::StorageFormats::OFOPXML
)
603 std::size_t nSignatureCount
= maCurrentSignatureInformations
.size();
604 maSignatureHelper
.ExportSignatureContentTypes(mxStore
, nSignatureCount
);
605 if (nSignatureCount
> 0)
606 maSignatureHelper
.ExportSignatureRelations(aStreamHelper
.xSignatureStorage
,
610 // Removing all signatures: then need to remove the signature relation as well.
611 maSignatureHelper
.EnsureSignaturesRelation(mxStore
, /*bAdd=*/false);
612 // Also remove the whole signature sub-storage: release our read-write reference + remove the element.
613 aStreamHelper
= SignatureStreamHelper();
614 mxStore
->removeElement("_xmlsignatures");
617 for (std::size_t i
= 0; i
< nSignatureCount
; ++i
)
618 maSignatureHelper
.ExportOOXMLSignature(mxStore
, aStreamHelper
.xSignatureStorage
,
619 maCurrentSignatureInformations
[i
], i
+ 1);
622 // If stream was not provided, we are responsible for committing it....
623 if (!mxSignatureStream
.is() && aStreamHelper
.xSignatureStorage
.is())
625 uno::Reference
<embed::XTransactedObject
> xTrans(aStreamHelper
.xSignatureStorage
,
631 uno::Reference
<xml::crypto::XSecurityEnvironment
> DocumentSignatureManager::getSecurityEnvironment()
633 return mxSecurityContext
.is() ? mxSecurityContext
->getSecurityEnvironment()
634 : uno::Reference
<xml::crypto::XSecurityEnvironment
>();
637 uno::Reference
<xml::crypto::XSecurityEnvironment
>
638 DocumentSignatureManager::getGpgSecurityEnvironment()
640 return mxGpgSecurityContext
.is() ? mxGpgSecurityContext
->getSecurityEnvironment()
641 : uno::Reference
<xml::crypto::XSecurityEnvironment
>();
644 uno::Reference
<xml::crypto::XXMLSecurityContext
> const&
645 DocumentSignatureManager::getSecurityContext()
647 return mxSecurityContext
;
650 uno::Reference
<xml::crypto::XXMLSecurityContext
> const&
651 DocumentSignatureManager::getGpgSecurityContext()
653 return mxGpgSecurityContext
;
656 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */