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 <xmlsecurity/digitalsignaturesdialog.hxx>
21 #include <xmlsecurity/certificatechooser.hxx>
22 #include <xmlsecurity/certificateviewer.hxx>
23 #include <xmlsecurity/biginteger.hxx>
24 #include <sax/tools/converter.hxx>
26 #include <com/sun/star/embed/XStorage.hpp>
27 #include <com/sun/star/embed/ElementModes.hpp>
28 #include <com/sun/star/io/XSeekable.hpp>
29 #include <com/sun/star/io/XTruncate.hpp>
30 #include <com/sun/star/io/TempFile.hpp>
31 #include <com/sun/star/embed/XTransactedObject.hpp>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/lang/XComponent.hpp>
34 #include <com/sun/star/security/NoPasswordException.hpp>
35 #include <com/sun/star/lang/DisposedException.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/security/CertificateValidity.hpp>
38 #include <com/sun/star/packages/WrongPasswordException.hpp>
39 #include <com/sun/star/security/SerialNumberAdapter.hpp>
40 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
41 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
42 #include <com/sun/star/packages/manifest/ManifestReader.hpp>
45 #include <rtl/ustrbuf.hxx>
46 #include <rtl/uri.hxx>
48 #include <tools/date.hxx>
49 #include <tools/time.hxx>
50 #include <svtools/treelistentry.hxx>
52 #include "dialogs.hrc"
53 #include "digitalsignaturesdialog.hrc"
54 #include "helpids.hrc"
55 #include "resourcemanager.hxx"
57 #include <vcl/layout.hxx>
58 #include <unotools/configitem.hxx>
60 using namespace css::security
;
61 using namespace css::uno
;
66 class SaveODFItem
: public utl::ConfigItem
71 virtual void ImplCommit() SAL_OVERRIDE
;
74 virtual void Notify( const ::com::sun::star::uno::Sequence
< OUString
>& aPropertyNames
) SAL_OVERRIDE
;
76 //See group ODF in Common.xcs
83 void SaveODFItem::ImplCommit() {}
84 void SaveODFItem::Notify( const ::com::sun::star::uno::Sequence
< OUString
>& ) {}
86 SaveODFItem::SaveODFItem(): utl::ConfigItem(OUString(
87 "Office.Common/Save")), m_nODF(0)
89 OUString
sDef("ODF/DefaultVersion");
90 Sequence
< css::uno::Any
> aValues
= GetProperties( Sequence
<OUString
>(&sDef
,1) );
91 if ( aValues
.getLength() == 1)
94 if ( aValues
[0] >>= nTmp
)
97 throw uno::RuntimeException(
98 OUString("[xmlsecurity]SaveODFItem::SaveODFItem(): Wrong Type!"),
103 throw uno::RuntimeException(
104 OUString("[xmlsecurity] Could not open property Office.Common/Save/ODF/DefaultVersion"),
109 /* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
110 We use the manifest to find out if a file is xml and if it is encrypted.
111 The parameter is an encoded uri. However, the manifest contains paths. Therefore
112 the path is encoded as uri, so they can be compared.
114 bool DigitalSignaturesDialog::isXML(const OUString
& rURI
)
116 OSL_ASSERT(mxStore
.is());
119 bool bPropsAvailable
= false;
120 const OUString
sPropFullPath("FullPath");
121 const OUString
sPropMediaType("MediaType");
122 const OUString
sPropDigest("Digest");
124 for (int i
= 0; i
< m_manifest
.getLength(); i
++)
126 const Sequence
< css::beans::PropertyValue
>& entry
= m_manifest
[i
];
127 OUString sPath
, sMediaType
;
128 bool bEncrypted
= false;
129 for (int j
= 0; j
< entry
.getLength(); j
++)
131 const css::beans::PropertyValue
& prop
= entry
[j
];
133 if (prop
.Name
.equals( sPropFullPath
) )
134 prop
.Value
>>= sPath
;
135 else if (prop
.Name
.equals( sPropMediaType
) )
136 prop
.Value
>>= sMediaType
;
137 else if (prop
.Name
.equals( sPropDigest
) )
140 if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI
, sPath
))
142 bIsXML
= sMediaType
== "text/xml" && ! bEncrypted
;
143 bPropsAvailable
= true;
147 if (!bPropsAvailable
)
149 //This would be the case for at least mimetype, META-INF/manifest.xml
150 //META-INF/macrosignatures.xml.
151 //Files can only be encrypted if they are in the manifest.xml.
152 //That is, the current file cannot be encrypted, otherwise bPropsAvailable
154 OUString
aXMLExt( "XML" );
155 sal_Int32 nSep
= rURI
.lastIndexOf( '.' );
158 OUString aExt
= rURI
.copy( nSep
+1 );
159 if (aExt
.equalsIgnoreAsciiCase(aXMLExt
))
166 DigitalSignaturesDialog::DigitalSignaturesDialog(
167 vcl::Window
* pParent
,
168 uno::Reference
< uno::XComponentContext
>& rxCtx
, DocumentSignatureMode eMode
,
169 bool bReadOnly
, const OUString
& sODFVersion
, bool bHasDocumentSignature
)
170 : ModalDialog(pParent
, "DigitalSignaturesDialog", "xmlsec/ui/digitalsignaturesdialog.ui")
172 , maSignatureHelper(rxCtx
)
173 , meSignatureMode(eMode
)
174 , m_sODFVersion (sODFVersion
)
175 , m_bHasDocumentSignature(bHasDocumentSignature
)
176 , m_bWarningShowSignMacro(false)
178 get(m_pHintDocFT
, "dochint");
179 get(m_pHintBasicFT
, "macrohint");
180 get(m_pHintPackageFT
, "packagehint");
181 get(m_pViewBtn
, "view");
182 get(m_pAddBtn
, "sign");
183 get(m_pRemoveBtn
, "remove");
184 get(m_pCloseBtn
, "close");
185 get(m_pSigsValidImg
, "validimg");
186 get(m_pSigsValidFI
, "validft");
187 get(m_pSigsInvalidImg
, "invalidimg");
188 get(m_pSigsInvalidFI
, "invalidft");
189 get(m_pSigsNotvalidatedImg
, "notvalidatedimg");
190 get(m_pSigsNotvalidatedFI
, "notvalidatedft");
191 get(m_pSigsOldSignatureImg
, "oldsignatureimg");
192 get(m_pSigsOldSignatureFI
, "oldsignatureft");
194 Size
aControlSize(275, 109);
195 const long nControlWidth
= aControlSize
.Width();
196 aControlSize
= LogicToPixel(aControlSize
, MAP_APPFONT
);
197 SvSimpleTableContainer
*pSignatures
= get
<SvSimpleTableContainer
>("signatures");
198 pSignatures
->set_width_request(aControlSize
.Width());
199 pSignatures
->set_height_request(aControlSize
.Height());
201 m_pSignaturesLB
= VclPtr
<SvSimpleTable
>::Create(*pSignatures
);
202 // #i48253# the tablistbox needs its own unique id
203 m_pSignaturesLB
->Window::SetUniqueId( HID_XMLSEC_TREE_SIGNATURESDLG
);
204 static long aTabs
[] = { 4, 0, 6*nControlWidth
/100, 36*nControlWidth
/100, 74*nControlWidth
/100 };
205 m_pSignaturesLB
->SetTabs(aTabs
);
207 m_pSignaturesLB
->InsertHeaderEntry("\t" + get
<FixedText
>("signed")->GetText() + "\t"
208 + get
<FixedText
>("issued")->GetText() + "\t" + get
<FixedText
>("date")->GetText());
210 mbVerifySignatures
= true;
211 mbSignaturesChanged
= false;
213 m_pSignaturesLB
->SetSelectHdl( LINK( this, DigitalSignaturesDialog
, SignatureHighlightHdl
) );
214 m_pSignaturesLB
->SetDoubleClickHdl( LINK( this, DigitalSignaturesDialog
, SignatureSelectHdl
) );
216 m_pViewBtn
->SetClickHdl( LINK( this, DigitalSignaturesDialog
, ViewButtonHdl
) );
217 m_pViewBtn
->Disable();
219 m_pAddBtn
->SetClickHdl( LINK( this, DigitalSignaturesDialog
, AddButtonHdl
) );
221 m_pAddBtn
->Disable();
223 m_pRemoveBtn
->SetClickHdl( LINK( this, DigitalSignaturesDialog
, RemoveButtonHdl
) );
224 m_pRemoveBtn
->Disable();
226 m_pCloseBtn
->SetClickHdl( LINK( this, DigitalSignaturesDialog
, OKButtonHdl
) );
228 switch( meSignatureMode
)
230 case SignatureModeDocumentContent
: m_pHintDocFT
->Show(); break;
231 case SignatureModeMacros
: m_pHintBasicFT
->Show(); break;
232 case SignatureModePackage
: m_pHintPackageFT
->Show(); break;
236 DigitalSignaturesDialog::~DigitalSignaturesDialog()
241 void DigitalSignaturesDialog::dispose()
243 m_pSignaturesLB
.disposeAndClear();
244 m_pHintDocFT
.clear();
245 m_pHintBasicFT
.clear();
246 m_pHintPackageFT
.clear();
247 m_pSigsValidImg
.clear();
248 m_pSigsValidFI
.clear();
249 m_pSigsInvalidImg
.clear();
250 m_pSigsInvalidFI
.clear();
251 m_pSigsNotvalidatedImg
.clear();
252 m_pSigsNotvalidatedFI
.clear();
253 m_pSigsOldSignatureImg
.clear();
254 m_pSigsOldSignatureFI
.clear();
257 m_pRemoveBtn
.clear();
259 ModalDialog::dispose();
262 bool DigitalSignaturesDialog::Init()
264 bool bInit
= maSignatureHelper
.Init();
266 DBG_ASSERT( bInit
, "Error initializing security context!" );
270 maSignatureHelper
.SetStartVerifySignatureHdl( LINK( this, DigitalSignaturesDialog
, StartVerifySignatureHdl
) );
276 void DigitalSignaturesDialog::SetStorage( const com::sun::star::uno::Reference
< com::sun::star::embed::XStorage
>& rxStore
)
279 maSignatureHelper
.SetStorage( mxStore
, m_sODFVersion
);
281 Reference
< css::packages::manifest::XManifestReader
> xReader
=
282 css::packages::manifest::ManifestReader::create(mxCtx
);
284 //Get the manifest.xml
285 Reference
< css::embed::XStorage
> xSubStore(rxStore
->openStorageElement(
286 "META-INF", css::embed::ElementModes::READ
), UNO_QUERY_THROW
);
288 Reference
< css::io::XInputStream
> xStream(
289 xSubStore
->openStreamElement("manifest.xml", css::embed::ElementModes::READ
),
292 m_manifest
= xReader
->readManifestSequence(xStream
);
295 void DigitalSignaturesDialog::SetSignatureStream( const css::uno::Reference
< css::io::XStream
>& rxStream
)
297 mxSignatureStream
= rxStream
;
300 bool DigitalSignaturesDialog::canAddRemove()
304 OSL_ASSERT(mxStore
.is());
305 bool bDoc1_1
= DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion
);
307 bool bSave1_1
= item
.isLessODF1_2();
310 //cvs: specs/www/appwide/security/Electronic_Signatures_and_Security.sxw
311 //Paragraph 'Behavior with regard to ODF 1.2'
312 //For both, macro and document
313 if ( (!bSave1_1
&& bDoc1_1
) || (bSave1_1
&& bDoc1_1
) )
316 ScopedVclPtrInstance
< MessageDialog
> err(nullptr, XMLSEC_RES(STR_XMLSECDLG_OLD_ODF_FORMAT
));
321 //As of OOo 3.2 the document signature includes in macrosignatures.xml. That is
322 //adding a macro signature will break an existing document signature.
323 //The sfx2 will remove the documentsignature when the user adds a macro signature
324 if (meSignatureMode
== SignatureModeMacros
327 if (m_bHasDocumentSignature
&& !m_bWarningShowSignMacro
)
329 //The warning says that the document signatures will be removed if the user
330 //continues. He can then either press 'OK' or 'NO'
331 //It the user presses 'Add' or 'Remove' several times then, then the warning
332 //is shown every time until the user presses 'OK'. From then on, the warning
333 //is not displayed anymore as long as the signatures dialog is alive.
334 if (ScopedVclPtr
<MessageDialog
>::Create(
335 nullptr, XMLSEC_RES(STR_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN
), VCL_MESSAGE_QUESTION
, VCL_BUTTONS_YES_NO
)->Execute() == RET_NO
)
338 m_bWarningShowSignMacro
= true;
345 bool DigitalSignaturesDialog::canAdd()
352 bool DigitalSignaturesDialog::canRemove()
359 short DigitalSignaturesDialog::Execute()
361 // Verify Signatures and add certificates to ListBox...
362 mbVerifySignatures
= true;
363 ImplGetSignatureInformations(false);
364 ImplFillSignaturesBox();
366 // Only verify once, content will not change.
367 // But for refreshing signature information, StartVerifySignatureHdl will be called after each add/remove
368 mbVerifySignatures
= false;
370 return Dialog::Execute();
373 IMPL_LINK_NOARG(DigitalSignaturesDialog
, SignatureHighlightHdl
)
375 bool bSel
= m_pSignaturesLB
->FirstSelected();
376 m_pViewBtn
->Enable( bSel
);
377 if ( m_pAddBtn
->IsEnabled() ) // not read only
378 m_pRemoveBtn
->Enable( bSel
);
383 IMPL_LINK_NOARG(DigitalSignaturesDialog
, OKButtonHdl
)
385 // Export all other signatures...
386 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
387 embed::ElementModes::WRITE
|embed::ElementModes::TRUNCATE
, false );
388 uno::Reference
< io::XOutputStream
> xOutputStream(
389 aStreamHelper
.xSignatureStream
, uno::UNO_QUERY
);
390 uno::Reference
< com::sun::star::xml::sax::XWriter
> xSaxWriter
=
391 maSignatureHelper
.CreateDocumentHandlerWithHeader( xOutputStream
);
393 uno::Reference
< xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
, UNO_QUERY_THROW
);
394 size_t nInfos
= maCurrentSignatureInformations
.size();
395 for( size_t n
= 0 ; n
< nInfos
; ++n
)
396 XMLSignatureHelper::ExportSignature(
397 xDocumentHandler
, maCurrentSignatureInformations
[ n
] );
399 XMLSignatureHelper::CloseDocumentHandler( xDocumentHandler
);
401 // If stream was not provided, we are responsible for committing it....
402 if ( !mxSignatureStream
.is() )
404 uno::Reference
< embed::XTransactedObject
> xTrans(
405 aStreamHelper
.xSignatureStorage
, uno::UNO_QUERY
);
413 IMPL_LINK_NOARG(DigitalSignaturesDialog
, SignatureSelectHdl
)
415 ImplShowSignaturesDetails();
419 IMPL_LINK_NOARG(DigitalSignaturesDialog
, ViewButtonHdl
)
421 ImplShowSignaturesDetails();
425 IMPL_LINK_NOARG(DigitalSignaturesDialog
, AddButtonHdl
)
431 uno::Reference
<com::sun::star::xml::crypto::XSecurityEnvironment
> xSecEnv
= maSignatureHelper
.GetSecurityEnvironment();
433 uno::Reference
<com::sun::star::security::XSerialNumberAdapter
> xSerialNumberAdapter
=
434 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx
);
435 ScopedVclPtrInstance
< CertificateChooser
> aChooser( this, mxCtx
, xSecEnv
, maCurrentSignatureInformations
);
436 if ( aChooser
->Execute() == RET_OK
)
438 uno::Reference
< ::com::sun::star::security::XCertificate
> xCert
= aChooser
->GetSelectedCertificate();
441 SAL_WARN( "xmlsecurity.dialogs", "no certificate selected" );
444 OUString aCertSerial
= xSerialNumberAdapter
->toString( xCert
->getSerialNumber() );
445 if ( aCertSerial
.isEmpty() )
447 OSL_FAIL( "Error in Certificate, problem with serial number!" );
451 maSignatureHelper
.StartMission();
453 sal_Int32 nSecurityId
= maSignatureHelper
.GetNewSecurityId();
455 OUStringBuffer aStrBuffer
;
456 ::sax::Converter::encodeBase64(aStrBuffer
, xCert
->getEncoded());
458 maSignatureHelper
.SetX509Certificate( nSecurityId
,
459 xCert
->getIssuerName(), aCertSerial
,
460 aStrBuffer
.makeStringAndClear());
462 std::vector
< OUString
> aElements
=
463 DocumentSignatureHelper::CreateElementList(
464 mxStore
, meSignatureMode
, OOo3_2Document
);
466 sal_Int32 nElements
= aElements
.size();
467 for ( sal_Int32 n
= 0; n
< nElements
; n
++ )
469 bool bBinaryMode
= !isXML(aElements
[n
]);
470 maSignatureHelper
.AddForSigning( nSecurityId
, aElements
[n
], aElements
[n
], bBinaryMode
);
473 maSignatureHelper
.SetDateTime( nSecurityId
, Date( Date::SYSTEM
), tools::Time( tools::Time::SYSTEM
) );
475 // We open a signature stream in which the existing and the new
476 //signature is written. ImplGetSignatureInformation (later in this function) will
477 //then read the stream an will fill maCurrentSignatureInformations. The final signature
478 //is written when the user presses OK. Then only maCurrentSignatureInformation and
479 //a sax writer are used to write the information.
480 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
481 css::embed::ElementModes::WRITE
|css::embed::ElementModes::TRUNCATE
, true);
482 Reference
< css::io::XOutputStream
> xOutputStream(
483 aStreamHelper
.xSignatureStream
, UNO_QUERY_THROW
);
484 Reference
< css::xml::sax::XWriter
> xSaxWriter
=
485 maSignatureHelper
.CreateDocumentHandlerWithHeader( xOutputStream
);
487 // Export old signatures...
488 uno::Reference
< xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
, UNO_QUERY_THROW
);
489 size_t nInfos
= maCurrentSignatureInformations
.size();
490 for ( size_t n
= 0; n
< nInfos
; n
++ )
491 XMLSignatureHelper::ExportSignature( xDocumentHandler
, maCurrentSignatureInformations
[n
]);
493 // Create a new one...
494 maSignatureHelper
.CreateAndWriteSignature( xDocumentHandler
);
497 XMLSignatureHelper::CloseDocumentHandler( xDocumentHandler
);
499 maSignatureHelper
.EndMission();
501 aStreamHelper
= SignatureStreamHelper(); // release objects...
503 mbSignaturesChanged
= true;
505 sal_Int32 nStatus
= maSignatureHelper
.GetSignatureInformation( nSecurityId
).nStatus
;
507 if ( nStatus
== ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
)
509 mbSignaturesChanged
= true;
511 // Can't simply remember current information, need parsing for getting full information :(
512 // We need to verify the signatures again, otherwise the status in the signature information
514 // SecurityOperationStatus_OPERATION_SUCCEEDED
515 mbVerifySignatures
= true;
516 ImplGetSignatureInformations(true);
517 ImplFillSignaturesBox();
521 catch ( uno::Exception
& )
523 OSL_FAIL( "Exception while adding a signature!" );
524 // Don't keep invalid entries...
525 ImplGetSignatureInformations(true);
526 ImplFillSignaturesBox();
532 IMPL_LINK_NOARG(DigitalSignaturesDialog
, RemoveButtonHdl
)
536 if( m_pSignaturesLB
->FirstSelected() )
540 sal_uInt16 nSelected
= (sal_uInt16
) reinterpret_cast<sal_uIntPtr
>( m_pSignaturesLB
->FirstSelected()->GetUserData() );
541 maCurrentSignatureInformations
.erase( maCurrentSignatureInformations
.begin()+nSelected
);
543 // Export all other signatures...
544 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
545 css::embed::ElementModes::WRITE
| css::embed::ElementModes::TRUNCATE
, true);
546 Reference
< css::io::XOutputStream
> xOutputStream(
547 aStreamHelper
.xSignatureStream
, UNO_QUERY_THROW
);
548 Reference
< css::xml::sax::XWriter
> xSaxWriter
=
549 maSignatureHelper
.CreateDocumentHandlerWithHeader( xOutputStream
);
551 uno::Reference
< xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
, UNO_QUERY_THROW
);
552 size_t nInfos
= maCurrentSignatureInformations
.size();
553 for( size_t n
= 0 ; n
< nInfos
; ++n
)
554 XMLSignatureHelper::ExportSignature( xDocumentHandler
, maCurrentSignatureInformations
[ n
] );
556 XMLSignatureHelper::CloseDocumentHandler( xDocumentHandler
);
558 mbSignaturesChanged
= true;
560 aStreamHelper
= SignatureStreamHelper(); // release objects...
562 ImplFillSignaturesBox();
564 catch ( uno::Exception
& )
566 OSL_FAIL( "Exception while removing a signature!" );
567 // Don't keep invalid entries...
568 ImplGetSignatureInformations(true);
569 ImplFillSignaturesBox();
576 IMPL_LINK_NOARG(DigitalSignaturesDialog
, StartVerifySignatureHdl
)
578 return mbVerifySignatures
? 1 : 0;
581 void DigitalSignaturesDialog::ImplFillSignaturesBox()
583 m_pSignaturesLB
->Clear();
585 uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
> xSecEnv
= maSignatureHelper
.GetSecurityEnvironment();
586 uno::Reference
<com::sun::star::security::XSerialNumberAdapter
> xSerialNumberAdapter
=
587 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx
);
589 uno::Reference
< ::com::sun::star::security::XCertificate
> xCert
;
591 size_t nInfos
= maCurrentSignatureInformations
.size();
592 size_t nValidSigs
= 0, nValidCerts
= 0;
593 bool bAllNewSignatures
= true;
597 for( size_t n
= 0; n
< nInfos
; ++n
)
599 DocumentSignatureAlgorithm mode
= DocumentSignatureHelper::getDocumentAlgorithm(
600 m_sODFVersion
, maCurrentSignatureInformations
[n
]);
601 std::vector
< OUString
> aElementsToBeVerified
=
602 DocumentSignatureHelper::CreateElementList(
603 mxStore
, meSignatureMode
, mode
);
605 const SignatureInformation
& rInfo
= maCurrentSignatureInformations
[n
];
606 //First we try to get the certificate which is embedded in the XML Signature
607 if (!rInfo
.ouX509Certificate
.isEmpty())
608 xCert
= xSecEnv
->createCertificateFromAscii(rInfo
.ouX509Certificate
);
610 //There must be an embedded certificate because we use it to get the
611 //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
612 //because it could be modified by an attacker. The issuer is displayed
613 //in the digital signature dialog.
614 //Comparing the X509IssuerName with the one from the X509Certificate in order
615 //to find out if the X509IssuerName was modified does not work. See #i62684
616 DBG_ASSERT(false, "Could not find embedded certificate!");
619 //In case there is no embedded certificate we try to get it from a local store
620 //Todo: This probably could be removed, see above.
622 xCert
= xSecEnv
->getCertificate( rInfo
.ouX509IssuerName
, xSerialNumberAdapter
->toSequence( rInfo
.ouX509SerialNumber
) );
624 DBG_ASSERT( xCert
.is(), "Certificate not found and can't be created!" );
628 OUString aDateTimeStr
;
630 bool bSigValid
= false;
631 bool bCertValid
= false;
634 //check the validity of the cert
636 sal_Int32 certResult
= xSecEnv
->verifyCertificate(xCert
,
637 Sequence
<css::uno::Reference
<css::security::XCertificate
> >());
639 bCertValid
= certResult
== css::security::CertificateValidity::VALID
;
643 } catch (css::uno::SecurityException
& ) {
644 OSL_FAIL("Verification of certificate failed");
648 aSubject
= XmlSec::GetContentPart( xCert
->getSubjectName() );
649 aIssuer
= XmlSec::GetContentPart( xCert
->getIssuerName() );
650 // String with date and time information (#i20172#)
651 aDateTimeStr
= XmlSec::GetDateTimeString( rInfo
.stDateTime
);
653 bSigValid
= ( rInfo
.nStatus
== ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
);
657 bSigValid
= DocumentSignatureHelper::checkIfAllFilesAreSigned(
658 aElementsToBeVerified
, rInfo
, mode
);
667 aImage
= m_pSigsInvalidImg
->GetImage();
669 else if (bSigValid
&& !bCertValid
)
671 aImage
= m_pSigsNotvalidatedImg
->GetImage();
673 //Check if the signature is a "old" document signature, that is, which was created
674 //by an version of OOo previous to 3.2
675 else if (meSignatureMode
== SignatureModeDocumentContent
676 && bSigValid
&& bCertValid
&& !DocumentSignatureHelper::isOOo3_2_Signature(
677 maCurrentSignatureInformations
[n
]))
679 aImage
= m_pSigsNotvalidatedImg
->GetImage();
680 bAllNewSignatures
&= false;
682 else if (meSignatureMode
== SignatureModeDocumentContent
683 && bSigValid
&& bCertValid
&& DocumentSignatureHelper::isOOo3_2_Signature(
684 maCurrentSignatureInformations
[n
]))
686 aImage
= m_pSigsValidImg
->GetImage();
688 else if (meSignatureMode
== SignatureModeMacros
689 && bSigValid
&& bCertValid
)
691 aImage
= m_pSigsValidImg
->GetImage();
694 SvTreeListEntry
* pEntry
= m_pSignaturesLB
->InsertEntry( OUString(), aImage
, aImage
);
695 m_pSignaturesLB
->SetEntryText( aSubject
, pEntry
, 1 );
696 m_pSignaturesLB
->SetEntryText( aIssuer
, pEntry
, 2 );
697 m_pSignaturesLB
->SetEntryText( aDateTimeStr
, pEntry
, 3 );
698 pEntry
->SetUserData( reinterpret_cast<void*>(n
) ); // missuse user data as index
702 bool bAllSigsValid
= (nValidSigs
== nInfos
);
703 bool bAllCertsValid
= (nValidCerts
== nInfos
);
704 bool bShowValidState
= nInfos
&& (bAllSigsValid
&& bAllCertsValid
&& bAllNewSignatures
);
706 m_pSigsValidImg
->Show( bShowValidState
);
707 m_pSigsValidFI
->Show( bShowValidState
);
709 bool bShowInvalidState
= nInfos
&& !bAllSigsValid
;
711 m_pSigsInvalidImg
->Show( bShowInvalidState
);
712 m_pSigsInvalidFI
->Show( bShowInvalidState
);
714 bool bShowNotValidatedState
= nInfos
&& bAllSigsValid
&& !bAllCertsValid
;
716 m_pSigsNotvalidatedImg
->Show(bShowNotValidatedState
);
717 m_pSigsNotvalidatedFI
->Show(bShowNotValidatedState
);
719 //bAllNewSignatures is always true if we are not in document mode
720 bool bShowOldSignature
= nInfos
&& bAllSigsValid
&& bAllCertsValid
&& !bAllNewSignatures
;
721 m_pSigsOldSignatureImg
->Show(bShowOldSignature
);
722 m_pSigsOldSignatureFI
->Show(bShowOldSignature
);
724 SignatureHighlightHdl( NULL
);
727 //If bUseTempStream is true then the temporary signature stream is used.
728 //Otherwise the real signature stream is used.
729 void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream
)
731 maCurrentSignatureInformations
.clear();
733 maSignatureHelper
.StartMission();
735 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
736 css::embed::ElementModes::READ
, bUseTempStream
);
737 if ( aStreamHelper
.xSignatureStream
.is() )
739 uno::Reference
< io::XInputStream
> xInputStream( aStreamHelper
.xSignatureStream
, uno::UNO_QUERY
);
740 maSignatureHelper
.ReadAndVerifySignature( xInputStream
);
742 maSignatureHelper
.EndMission();
744 maCurrentSignatureInformations
= maSignatureHelper
.GetSignatureInformations();
746 mbVerifySignatures
= false;
749 void DigitalSignaturesDialog::ImplShowSignaturesDetails()
751 if( m_pSignaturesLB
->FirstSelected() )
753 sal_uInt16 nSelected
= (sal_uInt16
) reinterpret_cast<sal_uIntPtr
>( m_pSignaturesLB
->FirstSelected()->GetUserData() );
754 const SignatureInformation
& rInfo
= maCurrentSignatureInformations
[ nSelected
];
755 css::uno::Reference
<css::xml::crypto::XSecurityEnvironment
> xSecEnv
=
756 maSignatureHelper
.GetSecurityEnvironment();
757 css::uno::Reference
<com::sun::star::security::XSerialNumberAdapter
> xSerialNumberAdapter
=
758 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx
);
759 // Use Certificate from doc, not from key store
760 uno::Reference
< css::security::XCertificate
> xCert
;
761 if (!rInfo
.ouX509Certificate
.isEmpty())
762 xCert
= xSecEnv
->createCertificateFromAscii(rInfo
.ouX509Certificate
);
763 //fallback if no certificate is embedded, get if from store
765 xCert
= xSecEnv
->getCertificate( rInfo
.ouX509IssuerName
, xSerialNumberAdapter
->toSequence( rInfo
.ouX509SerialNumber
) );
767 DBG_ASSERT( xCert
.is(), "Error getting cCertificate!" );
770 ScopedVclPtrInstance
< CertificateViewer
> aViewer( this, maSignatureHelper
.GetSecurityEnvironment(), xCert
, false );
776 //If bTempStream is true, then a temporary stream is return. If it is false then, the actual
777 //signature stream is used.
778 //Every time the user presses Add a new temporary stream is created.
779 //We keep the temporary stream as member because ImplGetSignatureInformations
780 //will later access the stream to create DocumentSignatureInformation objects
781 //which are stored in maCurrentSignatureInformations.
782 SignatureStreamHelper
DigitalSignaturesDialog::ImplOpenSignatureStream(
783 sal_Int32 nStreamOpenMode
, bool bTempStream
)
785 SignatureStreamHelper aHelper
;
788 if (nStreamOpenMode
& css::embed::ElementModes::TRUNCATE
)
790 //We write always into a new temporary stream.
791 mxTempSignatureStream
= Reference
< css::io::XStream
>(css::io::TempFile::create(mxCtx
), UNO_QUERY_THROW
);
792 aHelper
.xSignatureStream
= mxTempSignatureStream
;
796 //When we read from the temp stream, then we must have previously
798 OSL_ASSERT(mxTempSignatureStream
.is());
800 aHelper
.xSignatureStream
= mxTempSignatureStream
;
804 //No temporary stream
805 if (!mxSignatureStream
.is())
807 //We may not have a dedicated stream for writing the signature
808 //So we take one directly from the storage
809 //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
810 //in which case Add/Remove is not allowed. This is done, for example, if the
811 //document is readonly
812 aHelper
= DocumentSignatureHelper::OpenSignatureStream(
813 mxStore
, nStreamOpenMode
, meSignatureMode
);
817 aHelper
.xSignatureStream
= mxSignatureStream
;
821 if (nStreamOpenMode
& css::embed::ElementModes::TRUNCATE
)
823 css::uno::Reference
< css::io::XTruncate
> xTruncate(
824 aHelper
.xSignatureStream
, UNO_QUERY_THROW
);
825 DBG_ASSERT( xTruncate
.is(), "ImplOpenSignatureStream - Stream does not support xTruncate!" );
826 xTruncate
->truncate();
828 else if ( bTempStream
|| mxSignatureStream
.is())
830 //In case we read the signature stream from the storage directly,
831 //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
832 //then XSeakable is not supported
833 css::uno::Reference
< css::io::XSeekable
> xSeek(
834 aHelper
.xSignatureStream
, UNO_QUERY_THROW
);
835 DBG_ASSERT( xSeek
.is(), "ImplOpenSignatureStream - Stream does not support xSeekable!" );
842 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */