Bump version to 6.0-36
[LibreOffice.git] / xmlsecurity / source / component / documentdigitalsignatures.cxx
blob5f0f2bb201f3c412c8b2b7ef57e9160eb435f3bc
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 "documentdigitalsignatures.hxx"
21 #include <resourcemanager.hxx>
23 #include <digitalsignaturesdialog.hxx>
24 #include <certificatechooser.hxx>
25 #include <certificateviewer.hxx>
26 #include <macrosecurity.hxx>
27 #include <biginteger.hxx>
28 #include <strings.hrc>
29 #include <pdfsignaturehelper.hxx>
30 #include <sax/tools/converter.hxx>
32 #include <com/sun/star/embed/XStorage.hpp>
33 #include <com/sun/star/embed/StorageFormats.hpp>
34 #include <com/sun/star/embed/XTransactedObject.hpp>
35 #include <com/sun/star/embed/ElementModes.hpp>
36 #include <com/sun/star/ucb/XContent.hpp>
37 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
38 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
39 #include <com/sun/star/ucb/XCommandProcessor.hpp>
40 #include <com/sun/star/ucb/Command.hpp>
41 #include <com/sun/star/uno/SecurityException.hpp>
42 #include <vcl/layout.hxx>
43 #include <unotools/securityoptions.hxx>
44 #include <com/sun/star/security/CertificateValidity.hpp>
45 #include <comphelper/documentconstants.hxx>
46 #include <comphelper/propertyvalue.hxx>
47 #include <comphelper/sequence.hxx>
48 #include <cppuhelper/supportsservice.hxx>
49 #include <com/sun/star/lang/IllegalArgumentException.hpp>
50 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
51 #include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
53 using namespace css;
54 using namespace css::uno;
55 using namespace css::lang;
56 using namespace css::xml::crypto;
58 DocumentDigitalSignatures::DocumentDigitalSignatures( const Reference< XComponentContext >& rxCtx ):
59 mxCtx(rxCtx),
60 m_sODFVersion(ODFVER_012_TEXT),
61 m_nArgumentsCount(0),
62 m_bHasDocumentSignature(false)
66 DocumentDigitalSignatures::~DocumentDigitalSignatures()
70 void DocumentDigitalSignatures::initialize( const Sequence< Any >& aArguments)
72 if (aArguments.getLength() > 2)
73 throw css::lang::IllegalArgumentException(
74 "DocumentDigitalSignatures::initialize requires zero, one, or two arguments",
75 static_cast<XInitialization*>(this), 0);
77 m_nArgumentsCount = aArguments.getLength();
79 if (aArguments.getLength() > 0)
81 if (!(aArguments[0] >>= m_sODFVersion))
82 throw css::lang::IllegalArgumentException(
83 "DocumentDigitalSignatures::initialize: the first arguments must be a string",
84 static_cast<XInitialization*>(this), 0);
86 if (aArguments.getLength() == 2
87 && !(aArguments[1] >>= m_bHasDocumentSignature))
88 throw css::lang::IllegalArgumentException(
89 "DocumentDigitalSignatures::initialize: the second arguments must be a bool",
90 static_cast<XInitialization*>(this), 1);
92 //the Version is supported as of ODF1.2, so for and 1.1 document or older we will receive the
93 //an empty string. In this case we set it to ODFVER_010_TEXT. Then we can later check easily
94 //if initialize was called. Only then m_sODFVersion.getLength() is greater than 0
95 if (m_sODFVersion.isEmpty())
96 m_sODFVersion = ODFVER_010_TEXT;
100 OUString DocumentDigitalSignatures::getImplementationName()
102 return GetImplementationName();
105 sal_Bool DocumentDigitalSignatures::supportsService(
106 OUString const & ServiceName)
108 return cppu::supportsService(this, ServiceName);
111 css::uno::Sequence<OUString>
112 DocumentDigitalSignatures::getSupportedServiceNames()
114 return GetSupportedServiceNames();
117 sal_Bool DocumentDigitalSignatures::signDocumentContent(
118 const Reference< css::embed::XStorage >& rxStorage,
119 const Reference< css::io::XStream >& xSignStream)
121 OSL_ENSURE(!m_sODFVersion.isEmpty(), "DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
122 return ImplViewSignatures( rxStorage, xSignStream, DocumentSignatureMode::Content, false );
125 sal_Bool DocumentDigitalSignatures::signDocumentContentWithCertificate(
126 const Reference<css::embed::XStorage>& rxStorage,
127 const Reference<css::io::XStream>& xSignStream,
128 const Reference<css::security::XCertificate>& xCertificate, const OUString& aSignatureLineId)
130 OSL_ENSURE(!m_sODFVersion.isEmpty(),
131 "DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
133 DocumentSignatureManager aSignatureManager(mxCtx, DocumentSignatureMode::Content);
135 if (!aSignatureManager.init())
136 return false;
138 aSignatureManager.mxStore = rxStorage;
139 aSignatureManager.maSignatureHelper.SetStorage(rxStorage, m_sODFVersion);
140 aSignatureManager.mxSignatureStream = xSignStream;
142 Reference<XXMLSecurityContext> xSecurityContext;
143 Reference<XServiceInfo> xServiceInfo(xCertificate, UNO_QUERY);
144 if (xServiceInfo->getImplementationName()
145 == "com.sun.star.xml.security.gpg.XCertificate_GpgImpl")
146 xSecurityContext = aSignatureManager.getGpgSecurityContext();
147 else
148 xSecurityContext = aSignatureManager.getSecurityContext();
150 sal_Int32 nSecurityId;
151 OUString aDescription("");
152 bool bSuccess = aSignatureManager.add(xCertificate, xSecurityContext, aDescription, nSecurityId,
153 true, aSignatureLineId);
154 if (!bSuccess)
155 return false;
157 // Need to have this to verify the signature
158 aSignatureManager.read(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false);
159 aSignatureManager.write(true);
161 if (rxStorage.is() && !xSignStream.is())
163 uno::Reference<embed::XTransactedObject> xTrans(rxStorage, uno::UNO_QUERY);
164 xTrans->commit();
167 return true;
170 Sequence< css::security::DocumentSignatureInformation >
171 DocumentDigitalSignatures::verifyDocumentContentSignatures(
172 const Reference< css::embed::XStorage >& rxStorage,
173 const Reference< css::io::XInputStream >& xSignInStream )
175 OSL_ENSURE(!m_sODFVersion.isEmpty(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
176 return ImplVerifySignatures( rxStorage, xSignInStream, DocumentSignatureMode::Content );
179 void DocumentDigitalSignatures::showDocumentContentSignatures(
180 const Reference< css::embed::XStorage >& rxStorage,
181 const Reference< css::io::XInputStream >& xSignInStream )
183 OSL_ENSURE(!m_sODFVersion.isEmpty(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
184 ImplViewSignatures( rxStorage, xSignInStream, DocumentSignatureMode::Content, true );
187 OUString DocumentDigitalSignatures::getDocumentContentSignatureDefaultStreamName()
189 return DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName();
192 sal_Bool DocumentDigitalSignatures::signScriptingContent(
193 const Reference< css::embed::XStorage >& rxStorage,
194 const Reference< css::io::XStream >& xSignStream )
196 OSL_ENSURE(!m_sODFVersion.isEmpty(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
197 OSL_ENSURE(m_nArgumentsCount == 2, "DocumentDigitalSignatures: Service was not initialized properly");
198 return ImplViewSignatures( rxStorage, xSignStream, DocumentSignatureMode::Macros, false );
201 Sequence< css::security::DocumentSignatureInformation >
202 DocumentDigitalSignatures::verifyScriptingContentSignatures(
203 const Reference< css::embed::XStorage >& rxStorage,
204 const Reference< css::io::XInputStream >& xSignInStream )
206 OSL_ENSURE(!m_sODFVersion.isEmpty(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
207 return ImplVerifySignatures( rxStorage, xSignInStream, DocumentSignatureMode::Macros );
210 void DocumentDigitalSignatures::showScriptingContentSignatures(
211 const Reference< css::embed::XStorage >& rxStorage,
212 const Reference< css::io::XInputStream >& xSignInStream )
214 OSL_ENSURE(!m_sODFVersion.isEmpty(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
215 ImplViewSignatures( rxStorage, xSignInStream, DocumentSignatureMode::Macros, true );
218 OUString DocumentDigitalSignatures::getScriptingContentSignatureDefaultStreamName()
220 return DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName();
224 sal_Bool DocumentDigitalSignatures::signPackage(
225 const Reference< css::embed::XStorage >& rxStorage,
226 const Reference< css::io::XStream >& xSignStream )
228 OSL_ENSURE(!m_sODFVersion.isEmpty(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
229 return ImplViewSignatures( rxStorage, xSignStream, DocumentSignatureMode::Package, false );
232 Sequence< css::security::DocumentSignatureInformation >
233 DocumentDigitalSignatures::verifyPackageSignatures(
234 const Reference< css::embed::XStorage >& rxStorage,
235 const Reference< css::io::XInputStream >& xSignInStream )
237 OSL_ENSURE(!m_sODFVersion.isEmpty(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
238 return ImplVerifySignatures( rxStorage, xSignInStream, DocumentSignatureMode::Package );
241 void DocumentDigitalSignatures::showPackageSignatures(
242 const Reference< css::embed::XStorage >& rxStorage,
243 const Reference< css::io::XInputStream >& xSignInStream )
245 OSL_ENSURE(!m_sODFVersion.isEmpty(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
246 ImplViewSignatures( rxStorage, xSignInStream, DocumentSignatureMode::Package, true );
249 OUString DocumentDigitalSignatures::getPackageSignatureDefaultStreamName( )
251 return DocumentSignatureHelper::GetPackageSignatureDefaultStreamName();
255 void DocumentDigitalSignatures::ImplViewSignatures(
256 const Reference< css::embed::XStorage >& rxStorage,
257 const Reference< css::io::XInputStream >& xSignStream,
258 DocumentSignatureMode eMode, bool bReadOnly )
260 Reference< io::XStream > xStream;
261 if ( xSignStream.is() )
262 xStream.set( xSignStream, UNO_QUERY );
263 ImplViewSignatures( rxStorage, xStream, eMode, bReadOnly );
266 bool DocumentDigitalSignatures::ImplViewSignatures(
267 const Reference< css::embed::XStorage >& rxStorage, const Reference< css::io::XStream >& xSignStream,
268 DocumentSignatureMode eMode, bool bReadOnly )
270 bool bChanges = false;
271 ScopedVclPtrInstance<DigitalSignaturesDialog> aSignaturesDialog(
272 nullptr, mxCtx, eMode, bReadOnly, m_sODFVersion,
273 m_bHasDocumentSignature);
274 bool bInit = aSignaturesDialog->Init();
275 SAL_WARN_IF( !bInit, "xmlsecurity.comp", "Error initializing security context!" );
276 if ( bInit )
278 if (rxStorage.is())
279 // Something ZIP based: ODF or OOXML.
280 aSignaturesDialog->SetStorage( rxStorage );
282 aSignaturesDialog->SetSignatureStream( xSignStream );
283 if ( aSignaturesDialog->Execute() )
285 if ( aSignaturesDialog->SignaturesChanged() )
287 bChanges = true;
288 // If we have a storage and no stream, we are responsible for commit
289 if ( rxStorage.is() && !xSignStream.is() )
291 uno::Reference< embed::XTransactedObject > xTrans( rxStorage, uno::UNO_QUERY );
292 xTrans->commit();
297 else
299 ScopedVclPtrInstance< MessageDialog > aBox(nullptr, XsResId(RID_XMLSECWB_NO_MOZILLA_PROFILE), VclMessageType::Warning);
300 aBox->Execute();
303 return bChanges;
306 Sequence< css::security::DocumentSignatureInformation >
307 DocumentDigitalSignatures::ImplVerifySignatures(
308 const Reference< css::embed::XStorage >& rxStorage,
309 const Reference< css::io::XInputStream >& xSignStream, DocumentSignatureMode eMode )
311 DocumentSignatureManager aSignatureManager(mxCtx, eMode);
313 bool bInit = aSignatureManager.init();
315 SAL_WARN_IF(!bInit, "xmlsecurity.comp", "Error initializing security context!");
317 if (!bInit)
318 return uno::Sequence<security::DocumentSignatureInformation>(0);
320 if (!rxStorage.is())
322 if (xSignStream.is())
324 // Something not ZIP-based, try PDF.
325 PDFSignatureHelper& rSignatureHelper = aSignatureManager.getPDFSignatureHelper();
326 if (rSignatureHelper.ReadAndVerifySignature(xSignStream))
327 return rSignatureHelper.GetDocumentSignatureInformations(aSignatureManager.getSecurityEnvironment());
330 SAL_WARN( "xmlsecurity.comp", "Error, no XStorage provided");
331 return Sequence<css::security::DocumentSignatureInformation>();
333 // First check for the InputStream, to avoid unnecessary initialization of the security environment...
334 SignatureStreamHelper aStreamHelper;
335 Reference< io::XInputStream > xInputStream = xSignStream;
337 if ( !xInputStream.is() )
339 aStreamHelper = DocumentSignatureHelper::OpenSignatureStream( rxStorage, embed::ElementModes::READ, eMode );
340 if ( aStreamHelper.xSignatureStream.is() )
341 xInputStream.set( aStreamHelper.xSignatureStream, UNO_QUERY );
344 if (!xInputStream.is() && aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
345 return Sequence< css::security::DocumentSignatureInformation >(0);
348 XMLSignatureHelper& rSignatureHelper = aSignatureManager.maSignatureHelper;
349 rSignatureHelper.SetStorage(rxStorage, m_sODFVersion);
351 rSignatureHelper.StartMission(aSignatureManager.mxSecurityContext);
353 if (xInputStream.is())
354 rSignatureHelper.ReadAndVerifySignature(xInputStream);
355 else if (aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML)
356 rSignatureHelper.ReadAndVerifySignatureStorage(aStreamHelper.xSignatureStorage);
358 rSignatureHelper.EndMission();
360 uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = aSignatureManager.getSecurityEnvironment();
361 uno::Reference<xml::crypto::XSecurityEnvironment> xGpgSecEnv = aSignatureManager.getGpgSecurityEnvironment();
363 SignatureInformations aSignInfos = rSignatureHelper.GetSignatureInformations();
364 int nInfos = aSignInfos.size();
365 Sequence< css::security::DocumentSignatureInformation > aInfos(nInfos);
366 css::security::DocumentSignatureInformation* arInfos = aInfos.getArray();
368 if ( nInfos )
370 for( int n = 0; n < nInfos; ++n )
372 DocumentSignatureAlgorithm mode = DocumentSignatureHelper::getDocumentAlgorithm(
373 m_sODFVersion, aSignInfos[n]);
374 const std::vector< OUString > aElementsToBeVerified =
375 DocumentSignatureHelper::CreateElementList(
376 rxStorage, eMode, mode);
378 const SignatureInformation& rInfo = aSignInfos[n];
379 css::security::DocumentSignatureInformation& rSigInfo = arInfos[n];
381 if (rInfo.ouGpgCertificate.isEmpty()) // X.509
383 if (!rInfo.ouX509Certificate.isEmpty())
384 rSigInfo.Signer = xSecEnv->createCertificateFromAscii( rInfo.ouX509Certificate ) ;
385 if (!rSigInfo.Signer.is())
386 rSigInfo.Signer = xSecEnv->getCertificate( rInfo.ouX509IssuerName,
387 xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
389 // On Windows checking the certificate path is buggy. It does name matching (issuer, subject name)
390 // to find the parent certificate. It does not take into account that there can be several certificates
391 // with the same subject name.
393 try {
394 rSigInfo.CertificateStatus = xSecEnv->verifyCertificate(rSigInfo.Signer,
395 Sequence<Reference<css::security::XCertificate> >());
396 } catch (SecurityException& ) {
397 OSL_FAIL("Verification of certificate failed");
398 rSigInfo.CertificateStatus = css::security::CertificateValidity::INVALID;
401 else if (xGpgSecEnv.is()) // GPG
403 // TODO not ideal to retrieve cert by keyID, might
404 // collide, or PGPKeyID format might change - can't we
405 // keep the xCert itself in rInfo?
406 rSigInfo.Signer = xGpgSecEnv->getCertificate( rInfo.ouGpgKeyID, xmlsecurity::numericStringToBigInteger("") );
407 rSigInfo.CertificateStatus = xGpgSecEnv->verifyCertificate(rSigInfo.Signer,
408 Sequence<Reference<css::security::XCertificate> >());
411 // Time support again (#i38744#)
412 Date aDate( rInfo.stDateTime.Day, rInfo.stDateTime.Month, rInfo.stDateTime.Year );
413 tools::Time aTime( rInfo.stDateTime.Hours, rInfo.stDateTime.Minutes,
414 rInfo.stDateTime.Seconds, rInfo.stDateTime.NanoSeconds );
415 rSigInfo.SignatureDate = aDate.GetDate();
416 rSigInfo.SignatureTime = aTime.GetTime();
418 rSigInfo.SignatureIsValid = ( rInfo.nStatus == css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED );
420 // OOXML Signature line info (ID + Images)
421 if (!rInfo.ouSignatureLineId.isEmpty())
422 rSigInfo.SignatureLineId = rInfo.ouSignatureLineId;
424 if (rInfo.aValidSignatureImage.is())
425 rSigInfo.ValidSignatureLineImage = rInfo.aValidSignatureImage;
427 if (rInfo.aInvalidSignatureImage.is())
428 rSigInfo.InvalidSignatureLineImage = rInfo.aInvalidSignatureImage;
430 // OOXML intentionally doesn't sign metadata.
431 if ( rSigInfo.SignatureIsValid && aStreamHelper.nStorageFormat != embed::StorageFormats::OFOPXML)
433 rSigInfo.SignatureIsValid =
434 DocumentSignatureHelper::checkIfAllFilesAreSigned(
435 aElementsToBeVerified, rInfo, mode);
437 if (eMode == DocumentSignatureMode::Content)
439 if (aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML)
440 rSigInfo.PartialDocumentSignature = true;
441 else
442 rSigInfo.PartialDocumentSignature = !DocumentSignatureHelper::isOOo3_2_Signature(aSignInfos[n]);
447 return aInfos;
451 void DocumentDigitalSignatures::manageTrustedSources( )
453 // MT: i45295
454 // SecEnv is only needed to display certificate information from trusted sources.
455 // Macro Security also has some options where no security environment is needed, so raise dialog anyway.
456 // Later I should change the code so the Dialog creates the SecEnv on demand...
458 Reference< css::xml::crypto::XSecurityEnvironment > xSecEnv;
460 DocumentSignatureManager aSignatureManager(mxCtx, {});
461 if (aSignatureManager.init())
462 xSecEnv = aSignatureManager.getSecurityEnvironment();
464 ScopedVclPtrInstance< MacroSecurity > aDlg( nullptr, xSecEnv );
465 aDlg->Execute();
468 void DocumentDigitalSignatures::showCertificate(
469 const Reference< css::security::XCertificate >& Certificate )
471 DocumentSignatureManager aSignatureManager(mxCtx, {});
473 bool bInit = aSignatureManager.init();
475 SAL_WARN_IF( !bInit, "xmlsecurity.comp", "Error initializing security context!" );
477 if ( bInit )
479 ScopedVclPtrInstance<CertificateViewer> aViewer(nullptr, aSignatureManager.getSecurityEnvironment(), Certificate, false);
480 aViewer->Execute();
485 sal_Bool DocumentDigitalSignatures::isAuthorTrusted(
486 const Reference< css::security::XCertificate >& Author )
488 bool bFound = false;
490 OUString sSerialNum = xmlsecurity::bigIntegerToNumericString( Author->getSerialNumber() );
492 Sequence< SvtSecurityOptions::Certificate > aTrustedAuthors = SvtSecurityOptions().GetTrustedAuthors();
493 const SvtSecurityOptions::Certificate* pAuthors = aTrustedAuthors.getConstArray();
494 const SvtSecurityOptions::Certificate* pAuthorsEnd = pAuthors + aTrustedAuthors.getLength();
495 for ( ; pAuthors != pAuthorsEnd; ++pAuthors )
497 SvtSecurityOptions::Certificate aAuthor = *pAuthors;
498 if ( ( aAuthor[0] == Author->getIssuerName() ) && ( aAuthor[1] == sSerialNum ) )
500 bFound = true;
501 break;
505 return bFound;
508 uno::Sequence< Reference< css::security::XCertificate > > DocumentDigitalSignatures::chooseCertificatesImpl(std::map<OUString, OUString>& rProperties, const UserAction eAction)
510 std::vector< Reference< css::xml::crypto::XXMLSecurityContext > > xSecContexts;
512 DocumentSignatureManager aSignatureManager(mxCtx, {});
513 if (aSignatureManager.init()) {
514 xSecContexts.push_back(aSignatureManager.getSecurityContext());
515 xSecContexts.push_back(aSignatureManager.getGpgSecurityContext());
518 ScopedVclPtrInstance< CertificateChooser > aChooser(nullptr, mxCtx, xSecContexts, eAction);
520 uno::Sequence< Reference< css::security::XCertificate > > xCerts(1);
521 xCerts[0] = Reference< css::security::XCertificate >(nullptr);
523 if (aChooser->Execute() != RET_OK)
524 return xCerts;
526 xCerts = aChooser->GetSelectedCertificates();
527 rProperties["Description"] = aChooser->GetDescription();
528 rProperties["Usage"] = aChooser->GetUsageText();
530 return xCerts;
533 Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificate(OUString& rDescription)
535 return chooseSigningCertificate( rDescription );
538 Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseSigningCertificate(OUString& rDescription)
540 std::map<OUString, OUString> aProperties;
541 Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( aProperties, UserAction::Sign )[0];
542 rDescription = aProperties["Description"];
543 return xCert;
546 css::uno::Sequence< Reference< css::security::XCertificate > > DocumentDigitalSignatures::chooseEncryptionCertificate()
548 std::map<OUString, OUString> aProperties;
549 uno::Sequence< Reference< css::security::XCertificate > > aCerts=
550 chooseCertificatesImpl( aProperties, UserAction::Encrypt );
551 if (aCerts.getLength() == 1 && !aCerts[0].is())
552 // our error case contract is: empty sequence, so map that!
553 return uno::Sequence< Reference< css::security::XCertificate > >();
554 else
555 return aCerts;
558 css::uno::Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificateWithProps(Sequence<::com::sun::star::beans::PropertyValue>& rProperties)
560 std::map<OUString, OUString> aProperties;
561 auto xCert = chooseCertificatesImpl( aProperties, UserAction::Sign )[0];
563 std::vector<css::beans::PropertyValue> vec;
564 for (const auto& pair : aProperties)
566 vec.emplace_back(comphelper::makePropertyValue(pair.first, pair.second));
569 rProperties = comphelper::containerToSequence(vec);
570 return xCert;
573 sal_Bool DocumentDigitalSignatures::isLocationTrusted( const OUString& Location )
575 return SvtSecurityOptions().isTrustedLocationUri(Location);
578 void DocumentDigitalSignatures::addAuthorToTrustedSources(
579 const Reference< css::security::XCertificate >& Author )
581 SvtSecurityOptions aSecOpts;
583 SvtSecurityOptions::Certificate aNewCert( 3 );
584 aNewCert[ 0 ] = Author->getIssuerName();
585 aNewCert[ 1 ] = xmlsecurity::bigIntegerToNumericString( Author->getSerialNumber() );
587 OUStringBuffer aStrBuffer;
588 ::sax::Converter::encodeBase64(aStrBuffer, Author->getEncoded());
589 aNewCert[ 2 ] = aStrBuffer.makeStringAndClear();
592 Sequence< SvtSecurityOptions::Certificate > aTrustedAuthors = aSecOpts.GetTrustedAuthors();
593 sal_Int32 nCnt = aTrustedAuthors.getLength();
594 aTrustedAuthors.realloc( nCnt + 1 );
595 aTrustedAuthors[ nCnt ] = aNewCert;
597 aSecOpts.SetTrustedAuthors( aTrustedAuthors );
600 void DocumentDigitalSignatures::addLocationToTrustedSources( const OUString& Location )
602 SvtSecurityOptions aSecOpt;
604 Sequence< OUString > aSecURLs = aSecOpt.GetSecureURLs();
605 sal_Int32 nCnt = aSecURLs.getLength();
606 aSecURLs.realloc( nCnt + 1 );
607 aSecURLs[ nCnt ] = Location;
609 aSecOpt.SetSecureURLs( aSecURLs );
612 OUString DocumentDigitalSignatures::GetImplementationName()
614 return OUString( "com.sun.star.security.DocumentDigitalSignatures" );
617 Sequence< OUString > DocumentDigitalSignatures::GetSupportedServiceNames()
619 Sequence<OUString> aRet { "com.sun.star.security.DocumentDigitalSignatures" };
620 return aRet;
624 Reference< XInterface > DocumentDigitalSignatures_CreateInstance(
625 const Reference< XComponentContext >& rCtx)
627 return static_cast<cppu::OWeakObject*>(new DocumentDigitalSignatures( rCtx ));
630 sal_Bool DocumentDigitalSignatures::signDocumentWithCertificate(
631 css::uno::Reference<css::security::XCertificate> const & xCertificate,
632 css::uno::Reference<css::embed::XStorage> const & xStorage,
633 css::uno::Reference<css::io::XStream> const & xStream)
635 DocumentSignatureManager aSignatureManager(mxCtx, DocumentSignatureMode::Content);
637 if (!aSignatureManager.init())
638 return false;
640 aSignatureManager.mxStore = xStorage;
641 aSignatureManager.maSignatureHelper.SetStorage(xStorage, m_sODFVersion);
642 aSignatureManager.mxSignatureStream = xStream;
644 Reference<XXMLSecurityContext> xSecurityContext;
645 Reference<XServiceInfo> xServiceInfo(xCertificate, UNO_QUERY);
646 xSecurityContext = aSignatureManager.getSecurityContext();
648 sal_Int32 nSecurityId;
650 bool bSuccess = aSignatureManager.add(xCertificate, xSecurityContext, "", nSecurityId, true);
651 if (!bSuccess)
652 return false;
654 aSignatureManager.read(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false);
655 aSignatureManager.write(true);
657 if (xStorage.is() && !xStream.is())
659 uno::Reference<embed::XTransactedObject> xTransaction(xStorage, uno::UNO_QUERY);
660 xTransaction->commit();
663 return true;
666 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */