Bump version to 6.0-36
[LibreOffice.git] / xmlsecurity / source / helper / documentsignaturemanager.cxx
blobe95b92be1e2826aafe806620a2951c099cba038f
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 .
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/beans/PropertyValue.hpp>
33 #include <com/sun/star/packages/manifest/ManifestReader.hpp>
35 #include <comphelper/storagehelper.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <sax/tools/converter.hxx>
38 #include <tools/date.hxx>
39 #include <tools/time.hxx>
40 #include <o3tl/make_unique.hxx>
42 #include <certificate.hxx>
43 #include <biginteger.hxx>
45 #include <xmlsec/xmlsec_init.hxx>
47 using namespace css;
49 DocumentSignatureManager::DocumentSignatureManager(const uno::Reference<uno::XComponentContext>& xContext, DocumentSignatureMode eMode)
50 : mxContext(xContext),
51 maSignatureHelper(xContext),
52 meSignatureMode(eMode)
56 DocumentSignatureManager::~DocumentSignatureManager()
58 deInitXmlSec();
61 bool DocumentSignatureManager::init()
63 SAL_WARN_IF(mxSEInitializer.is(), "xmlsecurity.helper", "DocumentSignatureManager::Init - mxSEInitializer already set!");
64 SAL_WARN_IF(mxSecurityContext.is(), "xmlsecurity.helper", "DocumentSignatureManager::Init - mxSecurityContext already set!");
65 SAL_WARN_IF(mxGpgSEInitializer.is(), "xmlsecurity.helper", "DocumentSignatureManager::Init - mxGpgSEInitializer already set!");
67 // xmlsec is needed by both services, so init before those
68 initXmlSec();
70 mxSEInitializer = xml::crypto::SEInitializer::create(mxContext);
71 #if HAVE_FEATURE_GPGME
72 mxGpgSEInitializer.set(new SEInitializerGpg());
73 #endif
75 if (mxSEInitializer.is())
76 mxSecurityContext = mxSEInitializer->createSecurityContext(OUString());
78 #if HAVE_FEATURE_GPGME
79 if (mxGpgSEInitializer.is())
80 mxGpgSecurityContext = mxGpgSEInitializer->createSecurityContext(OUString());
82 return mxSecurityContext.is() || mxGpgSecurityContext.is();
83 #else
84 return mxSecurityContext.is();
85 #endif
88 PDFSignatureHelper& DocumentSignatureManager::getPDFSignatureHelper()
90 bool bInit = true;
91 if (!mxSecurityContext.is())
92 bInit = init();
94 SAL_WARN_IF(!bInit, "xmlsecurity.comp", "Error initializing security context!");
96 if (!mpPDFSignatureHelper)
97 mpPDFSignatureHelper = o3tl::make_unique<PDFSignatureHelper>();
99 return *mpPDFSignatureHelper;
102 #if 0 // For some reason does not work
103 bool DocumentSignatureManager::IsXAdESRelevant()
105 if (mxStore.is())
107 // ZIP-based: ODF or OOXML.
108 maSignatureHelper.StartMission();
110 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(embed::ElementModes::READ, /*bUseTempStream=*/true);
111 if (aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML)
113 maSignatureHelper.EndMission();
114 return false;
116 // FIXME: How to figure out if it is ODF 1.2?
117 maSignatureHelper.EndMission();
118 return true;
120 return false;
122 #endif
124 bool DocumentSignatureManager::readManifest()
126 // Check if manifest was already read
127 if (m_manifest.getLength() > 0)
128 return true;
130 if (!mxContext.is())
131 return false;
133 if (!mxStore.is())
134 return false;
136 uno::Reference<packages::manifest::XManifestReader> xReader
137 = packages::manifest::ManifestReader::create(mxContext);
139 uno::Reference<container::XNameAccess> xNameAccess(mxStore, uno::UNO_QUERY);
140 if (!xNameAccess.is())
141 return false;
143 if (xNameAccess->hasByName("META-INF"))
145 //Get the manifest.xml
146 uno::Reference<embed::XStorage> xSubStore(
147 mxStore->openStorageElement("META-INF", embed::ElementModes::READ), uno::UNO_QUERY_THROW);
149 uno::Reference<io::XInputStream> xStream(
150 xSubStore->openStreamElement("manifest.xml", css::embed::ElementModes::READ),
151 uno::UNO_QUERY_THROW);
153 m_manifest = xReader->readManifestSequence(xStream);
155 return true;
158 /* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
159 We use the manifest to find out if a file is xml and if it is encrypted.
160 The parameter is an encoded uri. However, the manifest contains paths. Therefore
161 the path is encoded as uri, so they can be compared.
163 bool DocumentSignatureManager::isXML(const OUString& rURI)
165 SAL_WARN_IF(!mxStore.is(), "xmlsecurity.helper", "empty storage reference");
167 bool bIsXML = false;
168 bool bPropsAvailable = false;
169 const OUString sPropFullPath("FullPath");
170 const OUString sPropMediaType("MediaType");
171 const OUString sPropDigest("Digest");
173 if (readManifest())
175 for (int i = 0; i < m_manifest.getLength(); i++)
177 const uno::Sequence<beans::PropertyValue>& entry = m_manifest[i];
178 OUString sPath, sMediaType;
179 bool bEncrypted = false;
180 for (int j = 0; j < entry.getLength(); j++)
182 const beans::PropertyValue& prop = entry[j];
184 if (prop.Name == sPropFullPath)
185 prop.Value >>= sPath;
186 else if (prop.Name == sPropMediaType)
187 prop.Value >>= sMediaType;
188 else if (prop.Name == sPropDigest)
189 bEncrypted = true;
191 if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI, sPath))
193 bIsXML = sMediaType == "text/xml" && !bEncrypted;
194 bPropsAvailable = true;
195 break;
199 if (!bPropsAvailable)
201 //This would be the case for at least mimetype, META-INF/manifest.xml
202 //META-INF/macrosignatures.xml.
203 //Files can only be encrypted if they are in the manifest.xml.
204 //That is, the current file cannot be encrypted, otherwise bPropsAvailable
205 //would be true.
206 sal_Int32 nSep = rURI.lastIndexOf('.');
207 if (nSep != -1)
209 OUString aExt = rURI.copy(nSep+1);
210 if (aExt.equalsIgnoreAsciiCase("XML"))
211 bIsXML = true;
214 return bIsXML;
217 //If bTempStream is true, then a temporary stream is return. If it is false then, the actual
218 //signature stream is used.
219 //Every time the user presses Add a new temporary stream is created.
220 //We keep the temporary stream as member because ImplGetSignatureInformations
221 //will later access the stream to create DocumentSignatureInformation objects
222 //which are stored in maCurrentSignatureInformations.
223 SignatureStreamHelper DocumentSignatureManager::ImplOpenSignatureStream(sal_Int32 nStreamOpenMode, bool bTempStream)
225 SignatureStreamHelper aHelper;
226 if (mxStore.is())
228 uno::Reference<container::XNameAccess> xNameAccess(mxStore, uno::UNO_QUERY);
229 if (xNameAccess.is() && xNameAccess->hasByName("[Content_Types].xml"))
230 aHelper.nStorageFormat = embed::StorageFormats::OFOPXML;
233 if (bTempStream)
235 if (nStreamOpenMode & embed::ElementModes::TRUNCATE)
237 //We write always into a new temporary stream.
238 mxTempSignatureStream.set(io::TempFile::create(mxContext), uno::UNO_QUERY_THROW);
239 if (aHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
240 aHelper.xSignatureStream = mxTempSignatureStream;
241 else
243 mxTempSignatureStorage = comphelper::OStorageHelper::GetStorageOfFormatFromStream(ZIP_STORAGE_FORMAT_STRING, mxTempSignatureStream);
244 aHelper.xSignatureStorage = mxTempSignatureStorage;
247 else
249 //When we read from the temp stream, then we must have previously
250 //created one.
251 SAL_WARN_IF(!mxTempSignatureStream.is(), "xmlsecurity.helper", "empty temp. signature stream reference");
253 aHelper.xSignatureStream = mxTempSignatureStream;
254 if (aHelper.nStorageFormat == embed::StorageFormats::OFOPXML)
255 aHelper.xSignatureStorage = mxTempSignatureStorage;
257 else
259 //No temporary stream
260 if (!mxSignatureStream.is())
262 //We may not have a dedicated stream for writing the signature
263 //So we take one directly from the storage
264 //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
265 //in which case Add/Remove is not allowed. This is done, for example, if the
266 //document is readonly
267 aHelper = DocumentSignatureHelper::OpenSignatureStream(mxStore, nStreamOpenMode, meSignatureMode);
269 else
271 aHelper.xSignatureStream = mxSignatureStream;
275 if (nStreamOpenMode & embed::ElementModes::TRUNCATE)
277 if (aHelper.xSignatureStream.is() && aHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
279 uno::Reference<io::XTruncate> xTruncate(aHelper.xSignatureStream, uno::UNO_QUERY_THROW);
280 xTruncate->truncate();
283 else if (bTempStream || mxSignatureStream.is())
285 //In case we read the signature stream from the storage directly,
286 //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
287 //then XSeakable is not supported
288 uno::Reference<io::XSeekable> xSeek(aHelper.xSignatureStream, uno::UNO_QUERY_THROW);
289 xSeek->seek(0);
292 return aHelper;
295 bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>& xCert,
296 const uno::Reference<xml::crypto::XXMLSecurityContext>& xSecurityContext,
297 const OUString& rDescription,
298 sal_Int32& nSecurityId,
299 bool bAdESCompliant,
300 const OUString& rSignatureLineId)
302 if (!xCert.is())
304 SAL_WARN("xmlsecurity.helper", "no certificate selected");
305 return false;
308 // GPG or X509 key?
309 uno::Reference< lang::XServiceInfo > xServiceInfo(xSecurityContext, uno::UNO_QUERY);
310 if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
312 // GPG keys only really have PGPKeyId and PGPKeyPacket
313 if (!mxStore.is())
315 SAL_WARN("xmlsecurity.helper", "cannot sign pdfs with GPG keys");
316 return false;
319 maSignatureHelper.StartMission(xSecurityContext);
321 nSecurityId = maSignatureHelper.GetNewSecurityId();
323 OUStringBuffer aStrBuffer;
324 sax::Converter::encodeBase64(aStrBuffer, xCert->getEncoded());
326 OUString aKeyId;
327 if (auto pCertificate = dynamic_cast<xmlsecurity::Certificate*>(xCert.get()))
329 OUStringBuffer aBuffer;
330 sax::Converter::encodeBase64(aBuffer, pCertificate->getSHA256Thumbprint());
331 aKeyId = aBuffer.makeStringAndClear();
333 else
334 SAL_WARN("xmlsecurity.helper", "XCertificate implementation without an xmlsecurity::Certificate one");
336 maSignatureHelper.SetGpgCertificate(nSecurityId, aKeyId, aStrBuffer.makeStringAndClear(), xCert->getIssuerName());
338 else
340 OUString aCertSerial = xmlsecurity::bigIntegerToNumericString(xCert->getSerialNumber());
341 if (aCertSerial.isEmpty())
343 SAL_WARN("xmlsecurity.helper", "Error in Certificate, problem with serial number!");
344 return false;
347 if (!mxStore.is())
349 // Something not ZIP based, try PDF.
350 nSecurityId = getPDFSignatureHelper().GetNewSecurityId();
351 getPDFSignatureHelper().SetX509Certificate(xCert);
352 getPDFSignatureHelper().SetDescription(rDescription);
353 uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
354 if (!getPDFSignatureHelper().Sign(xInputStream, bAdESCompliant))
356 SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::Sign() failed");
357 return false;
359 return true;
362 maSignatureHelper.StartMission(xSecurityContext);
364 nSecurityId = maSignatureHelper.GetNewSecurityId();
366 OUStringBuffer aStrBuffer;
367 sax::Converter::encodeBase64(aStrBuffer, xCert->getEncoded());
369 OUString aCertDigest;
370 if (auto pCertificate = dynamic_cast<xmlsecurity::Certificate*>(xCert.get()))
372 OUStringBuffer aBuffer;
373 sax::Converter::encodeBase64(aBuffer, pCertificate->getSHA256Thumbprint());
374 aCertDigest = aBuffer.makeStringAndClear();
376 else
377 SAL_WARN("xmlsecurity.helper", "XCertificate implementation without an xmlsecurity::Certificate one");
379 maSignatureHelper.SetX509Certificate(nSecurityId, xCert->getIssuerName(), aCertSerial, aStrBuffer.makeStringAndClear(), aCertDigest);
383 uno::Sequence< uno::Reference< security::XCertificate > > aCertPath = xSecurityContext->getSecurityEnvironment()->buildCertificatePath(xCert);
385 OUStringBuffer aStrBuffer;
386 for (uno::Reference<security::XCertificate> const& rxCertificate : aCertPath)
388 sax::Converter::encodeBase64(aStrBuffer, rxCertificate->getEncoded());
389 OUString aString = aStrBuffer.makeStringAndClear();
390 maSignatureHelper.AddEncapsulatedX509Certificate(aString);
394 std::vector< OUString > aElements = DocumentSignatureHelper::CreateElementList(mxStore, meSignatureMode, DocumentSignatureAlgorithm::OOo3_2);
395 DocumentSignatureHelper::AppendContentTypes(mxStore, aElements);
397 for (OUString const& rUri : aElements)
399 bool bBinaryMode = !isXML(rUri);
400 maSignatureHelper.AddForSigning(nSecurityId, rUri, bBinaryMode, bAdESCompliant);
403 maSignatureHelper.SetDateTime(nSecurityId, Date(Date::SYSTEM), tools::Time(tools::Time::SYSTEM));
404 maSignatureHelper.SetDescription(nSecurityId, rDescription);
406 if (!rSignatureLineId.isEmpty())
407 maSignatureHelper.SetSignatureLineId(nSecurityId, rSignatureLineId);
409 // We open a signature stream in which the existing and the new
410 //signature is written. ImplGetSignatureInformation (later in this function) will
411 //then read the stream an will fill maCurrentSignatureInformations. The final signature
412 //is written when the user presses OK. Then only maCurrentSignatureInformation and
413 //a sax writer are used to write the information.
414 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, true);
416 if (aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
418 uno::Reference<io::XOutputStream> xOutputStream(aStreamHelper.xSignatureStream, uno::UNO_QUERY_THROW);
419 uno::Reference<xml::sax::XWriter> xSaxWriter = maSignatureHelper.CreateDocumentHandlerWithHeader(xOutputStream);
421 // Export old signatures...
422 uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY_THROW);
423 std::size_t nInfos = maCurrentSignatureInformations.size();
424 for (std::size_t n = 0; n < nInfos; n++)
425 XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n], bAdESCompliant);
427 // Create a new one...
428 maSignatureHelper.CreateAndWriteSignature(xDocumentHandler, bAdESCompliant);
430 // That's it...
431 XMLSignatureHelper::CloseDocumentHandler(xDocumentHandler);
433 else
435 // OOXML
437 // Handle relations.
438 maSignatureHelper.EnsureSignaturesRelation(mxStore, /*bAdd=*/true);
439 // Old signatures + the new one.
440 int nSignatureCount = maCurrentSignatureInformations.size() + 1;
441 maSignatureHelper.ExportSignatureRelations(aStreamHelper.xSignatureStorage, nSignatureCount);
443 // Export old signatures.
444 for (std::size_t i = 0; i < maCurrentSignatureInformations.size(); ++i)
445 maSignatureHelper.ExportOOXMLSignature(mxStore, aStreamHelper.xSignatureStorage, maCurrentSignatureInformations[i], i + 1);
447 // Create a new signature.
448 maSignatureHelper.CreateAndWriteOOXMLSignature(mxStore, aStreamHelper.xSignatureStorage, nSignatureCount);
450 // Flush objects.
451 uno::Reference<embed::XTransactedObject> xTransact(aStreamHelper.xSignatureStorage, uno::UNO_QUERY);
452 xTransact->commit();
453 uno::Reference<io::XOutputStream> xOutputStream(aStreamHelper.xSignatureStream, uno::UNO_QUERY);
454 xOutputStream->closeOutput();
456 uno::Reference<io::XTempFile> xTempFile(aStreamHelper.xSignatureStream, uno::UNO_QUERY);
457 SAL_INFO("xmlsecurity.helper", "DocumentSignatureManager::add temporary storage at " << xTempFile->getUri());
460 maSignatureHelper.EndMission();
461 return true;
464 void DocumentSignatureManager::remove(sal_uInt16 nPosition)
466 if (!mxStore.is())
468 // Something not ZIP based, try PDF.
469 uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
470 if (!PDFSignatureHelper::RemoveSignature(xInputStream, nPosition))
472 SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::RemoveSignature() failed");
473 return;
476 // Only erase when the removal was successful, it may fail for PDF.
477 // Also, erase the requested and all following signatures, as PDF signatures are always chained.
478 maCurrentSignatureInformations.erase(maCurrentSignatureInformations.begin() + nPosition, maCurrentSignatureInformations.end());
479 return;
482 maCurrentSignatureInformations.erase(maCurrentSignatureInformations.begin() + nPosition);
484 // Export all other signatures...
485 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, /*bTempStream=*/true);
487 if (aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
489 uno::Reference<io::XOutputStream> xOutputStream(aStreamHelper.xSignatureStream, uno::UNO_QUERY_THROW);
490 uno::Reference<xml::sax::XWriter> xSaxWriter = maSignatureHelper.CreateDocumentHandlerWithHeader(xOutputStream);
492 uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY_THROW);
493 std::size_t nInfos = maCurrentSignatureInformations.size();
494 for (std::size_t n = 0 ; n < nInfos ; ++n)
495 XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n], false /* ??? */);
497 XMLSignatureHelper::CloseDocumentHandler(xDocumentHandler);
499 else
501 // OOXML
503 // Handle relations.
504 int nSignatureCount = maCurrentSignatureInformations.size();
505 maSignatureHelper.ExportSignatureRelations(aStreamHelper.xSignatureStorage, nSignatureCount);
507 // Export old signatures.
508 for (std::size_t i = 0; i < maCurrentSignatureInformations.size(); ++i)
509 maSignatureHelper.ExportOOXMLSignature(mxStore, aStreamHelper.xSignatureStorage, maCurrentSignatureInformations[i], i + 1);
511 // Flush objects.
512 uno::Reference<embed::XTransactedObject> xTransact(aStreamHelper.xSignatureStorage, uno::UNO_QUERY);
513 xTransact->commit();
514 uno::Reference<io::XOutputStream> xOutputStream(aStreamHelper.xSignatureStream, uno::UNO_QUERY);
515 xOutputStream->closeOutput();
517 uno::Reference<io::XTempFile> xTempFile(aStreamHelper.xSignatureStream, uno::UNO_QUERY);
518 SAL_INFO("xmlsecurity.helper", "DocumentSignatureManager::remove: temporary storage is at " << xTempFile->getUri());
522 void DocumentSignatureManager::read(bool bUseTempStream, bool bCacheLastSignature)
524 maCurrentSignatureInformations.clear();
526 if (mxStore.is())
528 // ZIP-based: ODF or OOXML.
529 maSignatureHelper.StartMission(mxSecurityContext);
531 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(embed::ElementModes::READ, bUseTempStream);
532 if (aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML && aStreamHelper.xSignatureStream.is())
534 uno::Reference< io::XInputStream > xInputStream(aStreamHelper.xSignatureStream, uno::UNO_QUERY);
535 maSignatureHelper.ReadAndVerifySignature(xInputStream);
537 else if (aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML && aStreamHelper.xSignatureStorage.is())
538 maSignatureHelper.ReadAndVerifySignatureStorage(aStreamHelper.xSignatureStorage, bCacheLastSignature);
539 maSignatureHelper.EndMission();
541 maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations();
543 else
545 // Something not ZIP based, try PDF.
546 uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
547 if (getPDFSignatureHelper().ReadAndVerifySignature(xInputStream))
548 maCurrentSignatureInformations = getPDFSignatureHelper().GetSignatureInformations();
552 void DocumentSignatureManager::write(bool bXAdESCompliantIfODF)
554 if (!mxStore.is())
556 // Something not ZIP based, assume PDF, which is written directly in add() already.
557 return;
560 // Export all other signatures...
561 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(embed::ElementModes::WRITE|embed::ElementModes::TRUNCATE, false);
563 if (aStreamHelper.xSignatureStream.is() && aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
565 // ODF
566 uno::Reference< io::XOutputStream > xOutputStream(aStreamHelper.xSignatureStream, uno::UNO_QUERY);
567 uno::Reference<xml::sax::XWriter> xSaxWriter = maSignatureHelper.CreateDocumentHandlerWithHeader(xOutputStream);
569 uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, uno::UNO_QUERY_THROW);
570 std::size_t nInfos = maCurrentSignatureInformations.size();
571 for (std::size_t n = 0 ; n < nInfos ; ++n)
572 XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n], bXAdESCompliantIfODF);
574 XMLSignatureHelper::CloseDocumentHandler(xDocumentHandler);
577 else if (aStreamHelper.xSignatureStorage.is() && aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML)
579 // OOXML
580 std::size_t nSignatureCount = maCurrentSignatureInformations.size();
581 maSignatureHelper.ExportSignatureContentTypes(mxStore, nSignatureCount);
582 if (nSignatureCount > 0)
583 maSignatureHelper.ExportSignatureRelations(aStreamHelper.xSignatureStorage, nSignatureCount);
584 else
586 // Removing all signatures: then need to remove the signature relation as well.
587 maSignatureHelper.EnsureSignaturesRelation(mxStore, /*bAdd=*/false);
588 // Also remove the whole signature sub-storage: release our read-write reference + remove the element.
589 aStreamHelper = SignatureStreamHelper();
590 mxStore->removeElement("_xmlsignatures");
593 for (std::size_t i = 0; i < nSignatureCount; ++i)
594 maSignatureHelper.ExportOOXMLSignature(mxStore, aStreamHelper.xSignatureStorage, maCurrentSignatureInformations[i], i + 1);
597 // If stream was not provided, we are responsible for committing it....
598 if (!mxSignatureStream.is() && aStreamHelper.xSignatureStorage.is())
600 uno::Reference<embed::XTransactedObject> xTrans(aStreamHelper.xSignatureStorage, uno::UNO_QUERY);
601 xTrans->commit();
605 uno::Reference<xml::crypto::XSecurityEnvironment> DocumentSignatureManager::getSecurityEnvironment()
607 return mxSecurityContext.is() ? mxSecurityContext->getSecurityEnvironment() : uno::Reference<xml::crypto::XSecurityEnvironment>();
610 uno::Reference<xml::crypto::XSecurityEnvironment> DocumentSignatureManager::getGpgSecurityEnvironment()
612 return mxGpgSecurityContext.is() ? mxGpgSecurityContext->getSecurityEnvironment() : uno::Reference<xml::crypto::XSecurityEnvironment>();
615 uno::Reference<xml::crypto::XXMLSecurityContext> DocumentSignatureManager::getSecurityContext()
617 return mxSecurityContext;
620 uno::Reference<xml::crypto::XXMLSecurityContext> DocumentSignatureManager::getGpgSecurityContext()
622 return mxGpgSecurityContext;
626 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */