LibreOffice Module xmlsecurity (master) 1
documentsignaturemanager.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21#include <config_gpgme.h>
22
23#include <gpg/SEInitializer.hxx>
24
25#include <com/sun/star/embed/StorageFormats.hpp>
26#include <com/sun/star/embed/ElementModes.hpp>
27#include <com/sun/star/embed/XStorage.hpp>
28#include <com/sun/star/io/XTempFile.hpp>
29#include <com/sun/star/io/XTruncate.hpp>
30#include <com/sun/star/embed/XTransactedObject.hpp>
31#include <com/sun/star/xml/crypto/SEInitializer.hpp>
32#include <com/sun/star/lang/XServiceInfo.hpp>
33#include <com/sun/star/beans/PropertyValue.hpp>
34#include <com/sun/star/packages/manifest/ManifestReader.hpp>
35#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
36#include <com/sun/star/xml/sax/XWriter.hpp>
37#include <com/sun/star/frame/XModel.hpp>
38
39#include <comphelper/base64.hxx>
41#include <rtl/ustrbuf.hxx>
42#include <sal/log.hxx>
43#include <tools/datetime.hxx>
44#include <o3tl/string_view.hxx>
45
46#include <certificate.hxx>
47#include <biginteger.hxx>
48
50
52
53#include <memory>
54
55using namespace css;
56using namespace css::graphic;
57using namespace css::uno;
58
60 const uno::Reference<uno::XComponentContext>& xContext, DocumentSignatureMode eMode)
61 : mxContext(xContext)
62 , maSignatureHelper(xContext)
63 , meSignatureMode(eMode)
64{
65}
66
68
70{
71 SAL_WARN_IF(mxSEInitializer.is(), "xmlsecurity.helper",
72 "DocumentSignatureManager::Init - mxSEInitializer already set!");
73 SAL_WARN_IF(mxSecurityContext.is(), "xmlsecurity.helper",
74 "DocumentSignatureManager::Init - mxSecurityContext already set!");
75 SAL_WARN_IF(mxGpgSEInitializer.is(), "xmlsecurity.helper",
76 "DocumentSignatureManager::Init - mxGpgSEInitializer already set!");
77
78 // xmlsec is needed by both services, so init before those
79 initXmlSec();
80
81 mxSEInitializer = xml::crypto::SEInitializer::create(mxContext);
82#if HAVE_FEATURE_GPGME
84#endif
85
86 if (mxSEInitializer.is())
87 mxSecurityContext = mxSEInitializer->createSecurityContext(OUString());
88
89#if HAVE_FEATURE_GPGME
90 if (mxGpgSEInitializer.is())
91 mxGpgSecurityContext = mxGpgSEInitializer->createSecurityContext(OUString());
92
93 return mxSecurityContext.is() || mxGpgSecurityContext.is();
94#else
95 return mxSecurityContext.is();
96#endif
97}
98
100{
101 bool bInit = true;
102 if (!mxSecurityContext.is())
103 bInit = init();
104
105 SAL_WARN_IF(!bInit, "xmlsecurity.comp", "Error initializing security context!");
106
108 mpPDFSignatureHelper = std::make_unique<PDFSignatureHelper>();
109
110 return *mpPDFSignatureHelper;
111}
112
113#if 0 // For some reason does not work
114bool DocumentSignatureManager::IsXAdESRelevant()
115{
116 if (mxStore.is())
117 {
118 // ZIP-based: ODF or OOXML.
120
121 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(embed::ElementModes::READ, /*bUseTempStream=*/true);
122 if (aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML)
123 {
125 return false;
126 }
127 // FIXME: How to figure out if it is ODF 1.2?
129 return true;
130 }
131 return false;
132}
133#endif
134
136{
137 // Check if manifest was already read
138 if (m_manifest.hasElements())
139 return true;
140
141 if (!mxContext.is())
142 return false;
143
144 if (!mxStore.is())
145 return false;
146
147 uno::Reference<packages::manifest::XManifestReader> xReader
148 = packages::manifest::ManifestReader::create(mxContext);
149
150 if (mxStore->hasByName("META-INF"))
151 {
152 //Get the manifest.xml
153 uno::Reference<embed::XStorage> xSubStore(
154 mxStore->openStorageElement("META-INF", embed::ElementModes::READ), UNO_SET_THROW);
155
156 uno::Reference<io::XInputStream> xStream(
157 xSubStore->openStreamElement("manifest.xml", css::embed::ElementModes::READ),
158 UNO_QUERY_THROW);
159
160 m_manifest = xReader->readManifestSequence(xStream);
161 }
162 return true;
163}
164
165/* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
166 We use the manifest to find out if a file is xml and if it is encrypted.
167 The parameter is an encoded uri. However, the manifest contains paths. Therefore
168 the path is encoded as uri, so they can be compared.
169*/
170bool DocumentSignatureManager::isXML(std::u16string_view rURI)
171{
172 SAL_WARN_IF(!mxStore.is(), "xmlsecurity.helper", "empty storage reference");
173
174 bool bIsXML = false;
175 bool bPropsAvailable = false;
176 static constexpr OUStringLiteral sPropFullPath(u"FullPath");
177 static constexpr OUStringLiteral sPropMediaType(u"MediaType");
178 static constexpr OUStringLiteral sPropDigest(u"Digest");
179
180 if (readManifest())
181 {
182 for (const uno::Sequence<beans::PropertyValue>& entry : std::as_const(m_manifest))
183 {
184 OUString sPath;
185 OUString sMediaType;
186 bool bEncrypted = false;
187 for (const beans::PropertyValue& prop : entry)
188 {
189 if (prop.Name == sPropFullPath)
190 prop.Value >>= sPath;
191 else if (prop.Name == sPropMediaType)
192 prop.Value >>= sMediaType;
193 else if (prop.Name == sPropDigest)
194 bEncrypted = true;
195 }
197 {
198 bIsXML = sMediaType == "text/xml" && !bEncrypted;
199 bPropsAvailable = true;
200 break;
201 }
202 }
203 }
204 if (!bPropsAvailable)
205 {
206 //This would be the case for at least mimetype, META-INF/manifest.xml
207 //META-INF/macrosignatures.xml.
208 //Files can only be encrypted if they are in the manifest.xml.
209 //That is, the current file cannot be encrypted, otherwise bPropsAvailable
210 //would be true.
211 size_t nSep = rURI.rfind('.');
212 if (nSep != std::u16string_view::npos)
213 {
214 std::u16string_view aExt = rURI.substr(nSep + 1);
215 if (o3tl::equalsIgnoreAsciiCase(aExt, u"XML"))
216 bIsXML = true;
217 }
218 }
219 return bIsXML;
220}
221
222//If bTempStream is true, then a temporary stream is return. If it is false then, the actual
223//signature stream is used.
224//Every time the user presses Add a new temporary stream is created.
225//We keep the temporary stream as member because ImplGetSignatureInformations
226//will later access the stream to create DocumentSignatureInformation objects
227//which are stored in maCurrentSignatureInformations.
229 bool bTempStream)
230{
232 if (mxStore.is() && mxStore->hasByName("[Content_Types].xml"))
233 aHelper.nStorageFormat = embed::StorageFormats::OFOPXML;
234
235 if (bTempStream)
236 {
237 if (nStreamOpenMode & embed::ElementModes::TRUNCATE)
238 {
239 //We write always into a new temporary stream.
241 if (aHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
242 aHelper.xSignatureStream = mxTempSignatureStream;
243 else
244 {
247 aHelper.xSignatureStorage = mxTempSignatureStorage;
248 }
249 }
250 else
251 {
252 //When we read from the temp stream, then we must have previously
253 //created one.
254 SAL_WARN_IF(!mxTempSignatureStream.is(), "xmlsecurity.helper",
255 "empty temp. signature stream reference");
256 }
257 aHelper.xSignatureStream = mxTempSignatureStream;
258 if (aHelper.nStorageFormat == embed::StorageFormats::OFOPXML)
259 aHelper.xSignatureStorage = mxTempSignatureStorage;
260 }
261 else
262 {
263 //No temporary stream
264 if (!mxSignatureStream.is())
265 {
266 //We may not have a dedicated stream for writing the signature
267 //So we take one directly from the storage
268 //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
269 //in which case Add/Remove is not allowed. This is done, for example, if the
270 //document is readonly
273 }
274 else
275 {
276 aHelper.xSignatureStream = mxSignatureStream;
277 }
278 }
279
280 if (nStreamOpenMode & embed::ElementModes::TRUNCATE)
281 {
282 if (aHelper.xSignatureStream.is()
283 && aHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
284 {
285 uno::Reference<io::XTruncate> xTruncate(aHelper.xSignatureStream, uno::UNO_QUERY_THROW);
286 xTruncate->truncate();
287 }
288 }
289 else if (bTempStream || mxSignatureStream.is())
290 {
291 //In case we read the signature stream from the storage directly,
292 //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
293 //then XSeakable is not supported
294 uno::Reference<io::XSeekable> xSeek(aHelper.xSignatureStream, uno::UNO_QUERY_THROW);
295 xSeek->seek(0);
296 }
297
298 return aHelper;
299}
300
302 const uno::Reference<security::XCertificate>& xCert,
303 const uno::Reference<xml::crypto::XXMLSecurityContext>& xSecurityContext,
304 const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant,
305 const OUString& rSignatureLineId, const Reference<XGraphic>& xValidGraphic,
306 const Reference<XGraphic>& xInvalidGraphic)
307{
308 if (!xCert.is())
309 {
310 SAL_WARN("xmlsecurity.helper", "no certificate selected");
311 return false;
312 }
313
314 // GPG or X509 key?
315 uno::Reference<lang::XServiceInfo> xServiceInfo(xSecurityContext, uno::UNO_QUERY);
316 if (xServiceInfo->getImplementationName()
317 == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
318 {
319 // GPG keys only really have PGPKeyId and PGPKeyPacket
320 if (!mxStore.is())
321 {
322 SAL_WARN("xmlsecurity.helper", "cannot sign pdfs with GPG keys");
323 return false;
324 }
325
326 maSignatureHelper.StartMission(xSecurityContext);
327
328 nSecurityId = maSignatureHelper.GetNewSecurityId();
329
330 OUStringBuffer aStrBuffer;
331 comphelper::Base64::encode(aStrBuffer, xCert->getEncoded());
332
333 OUString aKeyId;
334 if (auto pCertificate = dynamic_cast<xmlsecurity::Certificate*>(xCert.get()))
335 {
336 OUStringBuffer aBuffer;
337 comphelper::Base64::encode(aBuffer, pCertificate->getSHA256Thumbprint());
338 aKeyId = aBuffer.makeStringAndClear();
339 }
340 else
341 SAL_WARN("xmlsecurity.helper",
342 "XCertificate implementation without an xmlsecurity::Certificate one");
343
344 maSignatureHelper.SetGpgCertificate(nSecurityId, aKeyId, aStrBuffer.makeStringAndClear(),
345 xCert->getIssuerName());
346 }
347 else
348 {
349 OUString aCertSerial = xmlsecurity::bigIntegerToNumericString(xCert->getSerialNumber());
350 if (aCertSerial.isEmpty())
351 {
352 SAL_WARN("xmlsecurity.helper", "Error in Certificate, problem with serial number!");
353 return false;
354 }
355
356 if (!mxStore.is())
357 {
358 // Something not ZIP based, try PDF.
359 nSecurityId = getPDFSignatureHelper().GetNewSecurityId();
362 uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
363 if (!getPDFSignatureHelper().Sign(mxModel, xInputStream, bAdESCompliant))
364 {
365 SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::Sign() failed");
366 return false;
367 }
368 return true;
369 }
370
371 maSignatureHelper.StartMission(xSecurityContext);
372
373 nSecurityId = maSignatureHelper.GetNewSecurityId();
374
375 OUStringBuffer aStrBuffer;
376 comphelper::Base64::encode(aStrBuffer, xCert->getEncoded());
377
378 OUString aCertDigest;
381 if (auto pCertificate = dynamic_cast<xmlsecurity::Certificate*>(xCert.get()))
382 {
383 OUStringBuffer aBuffer;
384 comphelper::Base64::encode(aBuffer, pCertificate->getSHA256Thumbprint());
385 aCertDigest = aBuffer.makeStringAndClear();
386
387 eAlgorithmID = pCertificate->getSignatureMethodAlgorithm();
388 }
389 else
390 SAL_WARN("xmlsecurity.helper",
391 "XCertificate implementation without an xmlsecurity::Certificate one");
392
393 maSignatureHelper.SetX509Certificate(nSecurityId, xCert->getIssuerName(), aCertSerial,
394 aStrBuffer.makeStringAndClear(), aCertDigest,
395 eAlgorithmID);
396 }
397
398 const uno::Sequence<uno::Reference<security::XCertificate>> aCertPath
399 = xSecurityContext->getSecurityEnvironment()->buildCertificatePath(xCert);
400
401 OUStringBuffer aStrBuffer;
402 for (uno::Reference<security::XCertificate> const& rxCertificate : aCertPath)
403 {
404 comphelper::Base64::encode(aStrBuffer, rxCertificate->getEncoded());
405 OUString aString = aStrBuffer.makeStringAndClear();
407 }
408
409 std::vector<OUString> aElements = DocumentSignatureHelper::CreateElementList(
412
413 for (OUString const& rUri : aElements)
414 {
415 bool bBinaryMode = !isXML(rUri);
416 maSignatureHelper.AddForSigning(nSecurityId, rUri, bBinaryMode, bAdESCompliant);
417 }
418
420 maSignatureHelper.SetDescription(nSecurityId, rDescription);
421
422 if (!rSignatureLineId.isEmpty())
423 maSignatureHelper.SetSignatureLineId(nSecurityId, rSignatureLineId);
424
425 if (xValidGraphic.is())
426 maSignatureHelper.SetSignatureLineValidGraphic(nSecurityId, xValidGraphic);
427
428 if (xInvalidGraphic.is())
429 maSignatureHelper.SetSignatureLineInvalidGraphic(nSecurityId, xInvalidGraphic);
430
431 // We open a signature stream in which the existing and the new
432 //signature is written. ImplGetSignatureInformation (later in this function) will
433 //then read the stream and fill maCurrentSignatureInformations. The final signature
434 //is written when the user presses OK. Then only maCurrentSignatureInformation and
435 //a sax writer are used to write the information.
436 SignatureStreamHelper aStreamHelper
437 = ImplOpenSignatureStream(embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, true);
438
439 if (aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
440 {
441 uno::Reference<io::XOutputStream> xOutputStream(aStreamHelper.xSignatureStream,
442 uno::UNO_QUERY_THROW);
443 uno::Reference<xml::sax::XWriter> xSaxWriter
445
446 // Export old signatures...
447 uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter,
448 uno::UNO_QUERY_THROW);
449 std::size_t nInfos = maCurrentSignatureInformations.size();
450 for (std::size_t n = 0; n < nInfos; n++)
452 bAdESCompliant);
453
454 // Create a new one...
455 maSignatureHelper.CreateAndWriteSignature(xDocumentHandler, bAdESCompliant);
456
457 // That's it...
459 }
460 else
461 {
462 // OOXML
463
464 // Handle relations.
466 // Old signatures + the new one.
467 int nSignatureCount = maCurrentSignatureInformations.size() + 1;
469 nSignatureCount);
470
471 // Export old signatures.
472 for (std::size_t i = 0; i < maCurrentSignatureInformations.size(); ++i)
475
476 // Create a new signature.
478 nSignatureCount);
479
480 // Flush objects.
481 uno::Reference<embed::XTransactedObject> xTransact(aStreamHelper.xSignatureStorage,
482 uno::UNO_QUERY);
483 xTransact->commit();
484 uno::Reference<io::XOutputStream> xOutputStream(aStreamHelper.xSignatureStream,
485 uno::UNO_QUERY);
486 xOutputStream->closeOutput();
487
488 uno::Reference<io::XTempFile> xTempFile(aStreamHelper.xSignatureStream, uno::UNO_QUERY);
489 SAL_INFO("xmlsecurity.helper",
490 "DocumentSignatureManager::add temporary storage at " << xTempFile->getUri());
491 }
492
494 return true;
495}
496
497void DocumentSignatureManager::remove(sal_uInt16 nPosition)
498{
499 if (!mxStore.is())
500 {
501 // Something not ZIP based, try PDF.
502 uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
503 if (!PDFSignatureHelper::RemoveSignature(xInputStream, nPosition))
504 {
505 SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::RemoveSignature() failed");
506 return;
507 }
508
509 // Only erase when the removal was successful, it may fail for PDF.
510 // Also, erase the requested and all following signatures, as PDF signatures are always chained.
513 return;
514 }
515
517
518 // Export all other signatures...
520 embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, /*bTempStream=*/true);
521
522 if (aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
523 {
524 uno::Reference<io::XOutputStream> xOutputStream(aStreamHelper.xSignatureStream,
525 uno::UNO_QUERY_THROW);
526 uno::Reference<xml::sax::XWriter> xSaxWriter
528
529 uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter,
530 uno::UNO_QUERY_THROW);
531 std::size_t nInfos = maCurrentSignatureInformations.size();
532 for (std::size_t n = 0; n < nInfos; ++n)
534 false /* ??? */);
535
537 }
538 else
539 {
540 // OOXML
541
542 // Handle relations.
543 int nSignatureCount = maCurrentSignatureInformations.size();
545 nSignatureCount);
546
547 // Export old signatures.
548 for (std::size_t i = 0; i < maCurrentSignatureInformations.size(); ++i)
551
552 // Flush objects.
553 uno::Reference<embed::XTransactedObject> xTransact(aStreamHelper.xSignatureStorage,
554 uno::UNO_QUERY);
555 xTransact->commit();
556 uno::Reference<io::XOutputStream> xOutputStream(aStreamHelper.xSignatureStream,
557 uno::UNO_QUERY);
558 xOutputStream->closeOutput();
559
560 uno::Reference<io::XTempFile> xTempFile(aStreamHelper.xSignatureStream, uno::UNO_QUERY);
561 SAL_INFO("xmlsecurity.helper", "DocumentSignatureManager::remove: temporary storage is at "
562 << xTempFile->getUri());
563 }
564}
565
566void DocumentSignatureManager::read(bool bUseTempStream, bool bCacheLastSignature)
567{
569
570 if (mxStore.is())
571 {
572 // ZIP-based: ODF or OOXML.
574
575 SignatureStreamHelper aStreamHelper
576 = ImplOpenSignatureStream(embed::ElementModes::READ, bUseTempStream);
577 if (aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML
578 && aStreamHelper.xSignatureStream.is())
579 {
580 uno::Reference<io::XInputStream> xInputStream(aStreamHelper.xSignatureStream,
581 uno::UNO_QUERY);
583 }
584 else if (aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML
585 && aStreamHelper.xSignatureStorage.is())
587 bCacheLastSignature);
589
590 // this parses the XML independently from ImplVerifySignatures() - check
591 // certificates here too ...
592 for (auto const& it : maSignatureHelper.GetSignatureInformations())
593 {
594 if (!it.X509Datas.empty())
595 {
596 uno::Reference<xml::crypto::XSecurityEnvironment> const xSecEnv(
599 }
600 }
601
603 }
604 else
605 {
606 // Something not ZIP based, try PDF.
607 uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
608 if (getPDFSignatureHelper().ReadAndVerifySignature(xInputStream))
610 }
611}
612
613void DocumentSignatureManager::write(bool bXAdESCompliantIfODF)
614{
615 if (!mxStore.is())
616 {
617 // Something not ZIP based, assume PDF, which is written directly in add() already.
618 return;
619 }
620
621 // Export all other signatures...
623 embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, false);
624
625 if (aStreamHelper.xSignatureStream.is()
626 && aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
627 {
628 // ODF
629 uno::Reference<io::XOutputStream> xOutputStream(aStreamHelper.xSignatureStream,
630 uno::UNO_QUERY);
631 uno::Reference<xml::sax::XWriter> xSaxWriter
633
634 uno::Reference<xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter,
635 uno::UNO_QUERY_THROW);
636 std::size_t nInfos = maCurrentSignatureInformations.size();
637 for (std::size_t n = 0; n < nInfos; ++n)
639 bXAdESCompliantIfODF);
640
642 }
643 else if (aStreamHelper.xSignatureStorage.is()
644 && aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML)
645 {
646 // OOXML
647 std::size_t nSignatureCount = maCurrentSignatureInformations.size();
649 if (nSignatureCount > 0)
651 nSignatureCount);
652 else
653 {
654 // Removing all signatures: then need to remove the signature relation as well.
656 // Also remove the whole signature sub-storage: release our read-write reference + remove the element.
657 aStreamHelper = SignatureStreamHelper();
658 mxStore->removeElement("_xmlsignatures");
659 }
660
661 for (std::size_t i = 0; i < nSignatureCount; ++i)
664 }
665
666 // If stream was not provided, we are responsible for committing it...
667 if (!mxSignatureStream.is() && aStreamHelper.xSignatureStorage.is())
668 {
669 uno::Reference<embed::XTransactedObject> xTrans(aStreamHelper.xSignatureStorage,
670 uno::UNO_QUERY);
671 xTrans->commit();
672 }
673}
674
675uno::Reference<xml::crypto::XSecurityEnvironment> DocumentSignatureManager::getSecurityEnvironment()
676{
677 return mxSecurityContext.is() ? mxSecurityContext->getSecurityEnvironment()
678 : uno::Reference<xml::crypto::XSecurityEnvironment>();
679}
680
681uno::Reference<xml::crypto::XSecurityEnvironment>
683{
684 return mxGpgSecurityContext.is() ? mxGpgSecurityContext->getSecurityEnvironment()
685 : uno::Reference<xml::crypto::XSecurityEnvironment>();
686}
687
688uno::Reference<xml::crypto::XXMLSecurityContext> const&
690{
691 return mxSecurityContext;
692}
693
694uno::Reference<xml::crypto::XXMLSecurityContext> const&
696{
698}
699
700void DocumentSignatureManager::setModel(const uno::Reference<frame::XModel>& xModel)
701{
702 mxModel = xModel;
703}
704
705/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInputStream > xStream
constexpr OUStringLiteral sMediaType
css::uno::Reference< css::xml::crypto::XXMLSecurityContext > const & getGpgSecurityContext() const
void setModel(const css::uno::Reference< css::frame::XModel > &xModel)
bool init()
Attempts to initialize the platform-specific crypto.
css::uno::Reference< css::xml::crypto::XXMLSecurityContext > mxSecurityContext
css::uno::Reference< css::xml::crypto::XSecurityEnvironment > getGpgSecurityEnvironment()
rtl::Reference< utl::TempFileFastService > mxTempSignatureStream
css::uno::Reference< css::xml::crypto::XXMLSecurityContext > mxGpgSecurityContext
void remove(sal_uInt16 nPosition)
Remove signature at nPosition.
std::unique_ptr< PDFSignatureHelper > mpPDFSignatureHelper
css::uno::Reference< css::uno::XComponentContext > mxContext
css::uno::Reference< css::embed::XStorage > mxTempSignatureStorage
Storage containing all OOXML signatures, unused for ODF.
XMLSignatureHelper & getSignatureHelper()
css::uno::Reference< css::io::XStream > mxSignatureStream
PDFSignatureHelper & getPDFSignatureHelper()
Lazy creation of PDF helper.
void write(bool bXAdESCompliantIfODF)
Write signatures back to the persistent storage.
css::uno::Reference< css::xml::crypto::XXMLSecurityContext > const & getSecurityContext() const
SignatureStreamHelper ImplOpenSignatureStream(sal_Int32 nStreamOpenMode, bool bTempStream)
SignatureInformations maCurrentSignatureInformations
css::uno::Reference< css::frame::XModel > mxModel
DocumentSignatureManager(const css::uno::Reference< css::uno::XComponentContext > &xContext, DocumentSignatureMode eMode)
css::uno::Reference< css::xml::crypto::XSEInitializer > mxSEInitializer
bool isXML(std::u16string_view rURI)
Checks if a particular stream is a valid xml stream.
css::uno::Reference< css::embed::XStorage > mxStore
void read(bool bUseTempStream, bool bCacheLastSignature=true)
Read signatures from either a temp stream or the real storage.
DocumentSignatureMode const meSignatureMode
css::uno::Reference< css::xml::crypto::XSecurityEnvironment > getSecurityEnvironment()
Get the security environment.
css::uno::Reference< css::xml::crypto::XSEInitializer > mxGpgSEInitializer
css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > m_manifest
bool add(const css::uno::Reference< css::security::XCertificate > &xCert, const css::uno::Reference< css::xml::crypto::XXMLSecurityContext > &xSecurityContext, const OUString &rDescription, sal_Int32 &nSecurityId, bool bAdESCompliant, const OUString &rSignatureLineId=OUString(), const css::uno::Reference< css::graphic::XGraphic > &xValidGraphic=css::uno::Reference< css::graphic::XGraphic >(), const css::uno::Reference< css::graphic::XGraphic > &xInvalidGraphic=css::uno::Reference< css::graphic::XGraphic >())
Add a new signature, using xCert as a signing certificate, and rDescription as description.
Handles signatures of a PDF file.
static bool RemoveSignature(const css::uno::Reference< css::io::XInputStream > &xInputStream, sal_uInt16 nPosition)
Remove the signature at nPosition (and all dependent signatures) from xInputStream.
void SetDescription(const OUString &rDescription)
Comment / reason to be used next time signing is performed.
SignatureInformations const & GetSignatureInformations() const
sal_Int32 GetNewSecurityId() const
Return the ID of the next created signature.
void SetX509Certificate(const css::uno::Reference< css::security::XCertificate > &xCertificate)
Certificate to be used next time signing is performed.
bool ReadAndVerifySignatureStorage(const css::uno::Reference< css::embed::XStorage > &xStorage, bool bCacheLastSignature=true)
Read and verify OOXML signatures.
void SetGpgCertificate(sal_Int32 nSecurityId, const OUString &ouGpgCertDigest, const OUString &ouGpgCert, const OUString &ouGpgOwner)
void AddEncapsulatedX509Certificate(const OUString &ouEncapsulatedX509Certificate)
SignatureInformations GetSignatureInformations() const
bool ReadAndVerifySignature(const css::uno::Reference< css::io::XInputStream > &xInputStream)
void StartMission(const css::uno::Reference< css::xml::crypto::XXMLSecurityContext > &xSecurityContext)
void SetSignatureLineInvalidGraphic(sal_Int32 nSecurityId, const css::uno::Reference< css::graphic::XGraphic > &xInvalidGraphic)
void SetX509Certificate(sal_Int32 nSecurityId, const OUString &ouX509IssuerName, const OUString &ouX509SerialNumber, const OUString &ouX509Cert, const OUString &ouX509CertDigest, svl::crypto::SignatureMethodAlgorithm eAlgorithmID)
sets data that describes the certificate.
void CreateAndWriteOOXMLSignature(const css::uno::Reference< css::embed::XStorage > &xRootStorage, const css::uno::Reference< css::embed::XStorage > &xSignatureStorage, int nSignatureIndex)
Given that xSignatureStorage is an OOXML _xmlsignatures storage, create and write a new signature.
void ExportSignatureContentTypes(const css::uno::Reference< css::embed::XStorage > &xStorage, int nSignatureCount)
Given that xStorage is an OOXML root storage, advertise signatures in its [Content_Types]....
void SetSignatureLineValidGraphic(sal_Int32 nSecurityId, const css::uno::Reference< css::graphic::XGraphic > &xValidGraphic)
std::vector< css::uno::Reference< css::security::XCertificate > > CheckAndUpdateSignatureInformation(css::uno::Reference< css::xml::crypto::XSecurityEnvironment > const &xSecEnv, SignatureInformation const &rInfo)
ImplVerifySignature calls this to figure out which X509Data is the signing certificate and update the...
void SetDescription(sal_Int32 nSecurityId, const OUString &rDescription)
static void ExportSignature(const css::uno::Reference< css::xml::sax::XDocumentHandler > &xDocumentHandler, const SignatureInformation &signatureInfo, bool bXAdESCompliantIfODF)
void SetSignatureLineId(sal_Int32 nSecurityId, const OUString &rSignatureLineId)
void CreateAndWriteSignature(const css::uno::Reference< css::xml::sax::XDocumentHandler > &xDocumentHandler, bool bXAdESCompliantIfODF)
static void CloseDocumentHandler(const css::uno::Reference< css::xml::sax::XDocumentHandler > &xDocumentHandler)
void ExportOOXMLSignature(const css::uno::Reference< css::embed::XStorage > &xRootStorage, const css::uno::Reference< css::embed::XStorage > &xSignatureStorage, const SignatureInformation &rInformation, int nSignatureIndex)
Similar to CreateAndWriteOOXMLSignature(), but used to write the signature to the persistent storage,...
void AddForSigning(sal_Int32 securityId, const OUString &uri, bool bBinary, bool bXAdESCompliantIfODF)
void ExportSignatureRelations(const css::uno::Reference< css::embed::XStorage > &xStorage, int nSignatureCount)
Given that xStorage is an OOXML _xmlsignatures storage, create origin.sigs and its relations.
css::uno::Reference< css::xml::sax::XWriter > CreateDocumentHandlerWithHeader(const css::uno::Reference< css::io::XOutputStream > &xOutputStream)
void EnsureSignaturesRelation(const css::uno::Reference< css::embed::XStorage > &xStorage, bool bAdd)
Adds or removes an OOXML digital signature relation to _rels/.rels if there wasn't any before.
void SetDateTime(sal_Int32 nSecurityId, const DateTime &rDateTime)
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
static css::uno::Reference< css::embed::XStorage > GetStorageOfFormatFromStream(const OUString &aFormat, const css::uno::Reference< css::io::XStream > &xStream, sal_Int32 nStorageMode=css::embed::ElementModes::READWRITE, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >(), bool bRepairStorage=false)
uno::Reference< uno::XComponentContext > mxContext
float u
Any aHelper
Mode eMode
sal_Int64 n
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
void AppendContentTypes(const css::uno::Reference< css::embed::XStorage > &xStorage, std::vector< OUString > &rElements)
In case the storage is OOXML, prepend a leading '/' and append content type to the element URIs.
SignatureStreamHelper OpenSignatureStream(const css::uno::Reference< css::embed::XStorage > &rxStore, sal_Int32 nOpenMode, DocumentSignatureMode eDocSigMode)
bool equalsReferenceUriManifestPath(std::u16string_view rUri, std::u16string_view rPath)
std::vector< OUString > CreateElementList(const css::uno::Reference< css::embed::XStorage > &rxStore, DocumentSignatureMode eMode, const DocumentSignatureAlgorithm mode)
int i
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
OUString bigIntegerToNumericString(const Sequence< sal_Int8 > &integer)
Definition: biginteger.cxx:74
constexpr OUStringLiteral ZIP_STORAGE_FORMAT_STRING
css::uno::Reference< css::io::XStream > xSignatureStream
css::uno::Reference< css::embed::XStorage > xSignatureStorage
sal_Int32 nStorageFormat
If this is embed::StorageFormats::OFOPXML, then it's expected that xSignatureStream is an empty refer...
Reference< XModel > xModel
std::unique_ptr< char[]> aBuffer
XSECXMLSEC_DLLPUBLIC void deInitXmlSec()
Definition: xmlsec_init.cxx:61
XSECXMLSEC_DLLPUBLIC void initXmlSec()
Definition: xmlsec_init.cxx:27