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 "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>
54 using namespace css::uno
;
55 using namespace css::lang
;
56 using namespace css::xml::crypto
;
58 DocumentDigitalSignatures::DocumentDigitalSignatures( const Reference
< XComponentContext
>& rxCtx
):
60 m_sODFVersion(ODFVER_012_TEXT
),
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())
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();
148 xSecurityContext
= aSignatureManager
.getSecurityContext();
150 sal_Int32 nSecurityId
;
151 OUString
aDescription("");
152 bool bSuccess
= aSignatureManager
.add(xCertificate
, xSecurityContext
, aDescription
, nSecurityId
,
153 true, aSignatureLineId
);
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
);
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!" );
279 // Something ZIP based: ODF or OOXML.
280 aSignaturesDialog
->SetStorage( rxStorage
);
282 aSignaturesDialog
->SetSignatureStream( xSignStream
);
283 if ( aSignaturesDialog
->Execute() )
285 if ( aSignaturesDialog
->SignaturesChanged() )
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
);
299 ScopedVclPtrInstance
< MessageDialog
> aBox(nullptr, XsResId(RID_XMLSECWB_NO_MOZILLA_PROFILE
), VclMessageType::Warning
);
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!");
318 return uno::Sequence
<security::DocumentSignatureInformation
>(0);
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();
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.
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;
442 rSigInfo
.PartialDocumentSignature
= !DocumentSignatureHelper::isOOo3_2_Signature(aSignInfos
[n
]);
451 void DocumentDigitalSignatures::manageTrustedSources( )
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
);
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!" );
479 ScopedVclPtrInstance
<CertificateViewer
> aViewer(nullptr, aSignatureManager
.getSecurityEnvironment(), Certificate
, false);
485 sal_Bool
DocumentDigitalSignatures::isAuthorTrusted(
486 const Reference
< css::security::XCertificate
>& Author
)
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
) )
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
)
526 xCerts
= aChooser
->GetSelectedCertificates();
527 rProperties
["Description"] = aChooser
->GetDescription();
528 rProperties
["Usage"] = aChooser
->GetUsageText();
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"];
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
> >();
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
);
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" };
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())
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);
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();
666 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */