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/msgbox.hxx> // Until encrypted docs work...
58 #include <unotools/configitem.hxx>
59 #include <comphelper/componentcontext.hxx>
62 /* HACK: disable some warnings for MS-C */
64 #pragma warning (disable : 4355) // 4355: this used in initializer-list
67 using namespace ::com::sun::star::security
;
68 using namespace ::com::sun::star::uno
;
69 using namespace ::com::sun::star
;
73 class SaveODFItem
: public utl::ConfigItem
77 virtual void Commit();
78 virtual void Notify( const ::com::sun::star::uno::Sequence
< OUString
>& aPropertyNames
);
80 //See group ODF in Common.xcs
87 void SaveODFItem::Commit() {}
88 void SaveODFItem::Notify( const ::com::sun::star::uno::Sequence
< OUString
>& ) {}
90 SaveODFItem::SaveODFItem(): utl::ConfigItem(OUString(
91 "Office.Common/Save")), m_nODF(0)
93 OUString
sDef("ODF/DefaultVersion");
94 Sequence
< css::uno::Any
> aValues
= GetProperties( Sequence
<OUString
>(&sDef
,1) );
95 if ( aValues
.getLength() == 1)
98 if ( aValues
[0] >>= nTmp
)
101 throw uno::RuntimeException(
102 OUString("[xmlsecurity]SaveODFItem::SaveODFItem(): Wrong Type!"),
107 throw uno::RuntimeException(
108 OUString("[xmlsecurity] Could not open property Office.Common/Save/ODF/DefaultVersion"),
113 /* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
114 We use the manifest to find out if a file is xml and if it is encrypted.
115 The parameter is an encoded uri. However, the manifest contains paths. Therefore
116 the path is encoded as uri, so they can be compared.
118 bool DigitalSignaturesDialog::isXML(const OUString
& rURI
)
120 OSL_ASSERT(mxStore
.is());
123 bool bPropsAvailable
= false;
124 const OUString
sPropFullPath("FullPath");
125 const OUString
sPropMediaType("MediaType");
126 const OUString
sPropDigest("Digest");
128 for (int i
= 0; i
< m_manifest
.getLength(); i
++)
131 const Sequence
< css::beans::PropertyValue
>& entry
= m_manifest
[i
];
132 OUString sPath
, sMediaType
;
133 bool bEncrypted
= false;
134 for (int j
= 0; j
< entry
.getLength(); j
++)
136 const css::beans::PropertyValue
& prop
= entry
[j
];
138 if (prop
.Name
.equals( sPropFullPath
) )
139 prop
.Value
>>= sPath
;
140 else if (prop
.Name
.equals( sPropMediaType
) )
141 prop
.Value
>>= sMediaType
;
142 else if (prop
.Name
.equals( sPropDigest
) )
145 if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI
, sPath
))
147 bIsXML
= sMediaType
.equals("text/xml") && ! bEncrypted
;
148 bPropsAvailable
= true;
152 if (!bPropsAvailable
)
154 //This would be the case for at least mimetype, META-INF/manifest.xml
155 //META-INF/macrosignatures.xml.
156 //Files can only be encrypted if they are in the manifest.xml.
157 //That is, the current file cannot be encrypted, otherwise bPropsAvailable
159 OUString
aXMLExt( "XML" );
160 sal_Int32 nSep
= rURI
.lastIndexOf( '.' );
163 OUString aExt
= rURI
.copy( nSep
+1 );
164 if (aExt
.equalsIgnoreAsciiCase(aXMLExt
))
171 DigitalSignaturesDialog::DigitalSignaturesDialog(
173 uno::Reference
< uno::XComponentContext
>& rxCtx
, DocumentSignatureMode eMode
,
174 sal_Bool bReadOnly
, const OUString
& sODFVersion
, bool bHasDocumentSignature
)
175 : ModalDialog(pParent
, "DigitalSignaturesDialog", "xmlsec/ui/digitalsignaturesdialog.ui")
177 , maSignatureHelper(rxCtx
)
178 , meSignatureMode(eMode
)
179 , m_sODFVersion (sODFVersion
)
180 , m_bHasDocumentSignature(bHasDocumentSignature
)
181 , m_bWarningShowSignMacro(false)
183 get(m_pHintDocFT
, "dochint");
184 get(m_pHintBasicFT
, "macrohint");
185 get(m_pHintPackageFT
, "packagehint");
186 get(m_pViewBtn
, "view");
187 get(m_pAddBtn
, "sign");
188 get(m_pRemoveBtn
, "remove");
189 get(m_pCloseBtn
, "close");
190 get(m_pSigsValidImg
, "validimg");
191 get(m_pSigsValidFI
, "validft");
192 get(m_pSigsInvalidImg
, "invalidimg");
193 get(m_pSigsInvalidFI
, "invalidft");
194 get(m_pSigsNotvalidatedImg
, "notvalidatedimg");
195 get(m_pSigsNotvalidatedFI
, "notvalidatedft");
196 get(m_pSigsOldSignatureImg
, "oldsignatureimg");
197 get(m_pSigsOldSignatureFI
, "oldsignatureft");
199 Size
aControlSize(275, 109);
200 const long nControlWidth
= aControlSize
.Width();
201 aControlSize
= LogicToPixel(aControlSize
, MAP_APPFONT
);
202 SvxSimpleTableContainer
*pSignatures
= get
<SvxSimpleTableContainer
>("signatures");
203 pSignatures
->set_width_request(aControlSize
.Width());
204 pSignatures
->set_height_request(aControlSize
.Height());
206 m_pSignaturesLB
= new SvxSimpleTable(*pSignatures
);
207 // #i48253# the tablistbox needs its own unique id
208 m_pSignaturesLB
->Window::SetUniqueId( HID_XMLSEC_TREE_SIGNATURESDLG
);
209 static long aTabs
[] = { 4, 0, 6*nControlWidth
/100, 36*nControlWidth
/100, 74*nControlWidth
/100 };
210 m_pSignaturesLB
->SetTabs(aTabs
);
212 OUStringBuffer sHeader
;
213 sHeader
.append("\t").append(get
<FixedText
>("signed")->GetText())
214 .append("\t").append(get
<FixedText
>("issued")->GetText())
215 .append("\t").append(get
<FixedText
>("date")->GetText());
216 m_pSignaturesLB
->InsertHeaderEntry(sHeader
.makeStringAndClear());
218 mbVerifySignatures
= true;
219 mbSignaturesChanged
= false;
221 m_pSignaturesLB
->SetSelectHdl( LINK( this, DigitalSignaturesDialog
, SignatureHighlightHdl
) );
222 m_pSignaturesLB
->SetDoubleClickHdl( LINK( this, DigitalSignaturesDialog
, SignatureSelectHdl
) );
224 m_pViewBtn
->SetClickHdl( LINK( this, DigitalSignaturesDialog
, ViewButtonHdl
) );
225 m_pViewBtn
->Disable();
227 m_pAddBtn
->SetClickHdl( LINK( this, DigitalSignaturesDialog
, AddButtonHdl
) );
229 m_pAddBtn
->Disable();
231 m_pRemoveBtn
->SetClickHdl( LINK( this, DigitalSignaturesDialog
, RemoveButtonHdl
) );
232 m_pRemoveBtn
->Disable();
234 m_pCloseBtn
->SetClickHdl( LINK( this, DigitalSignaturesDialog
, OKButtonHdl
) );
236 switch( meSignatureMode
)
238 case SignatureModeDocumentContent
: m_pHintDocFT
->Show(); break;
239 case SignatureModeMacros
: m_pHintBasicFT
->Show(); break;
240 case SignatureModePackage
: m_pHintPackageFT
->Show(); break;
244 DigitalSignaturesDialog::~DigitalSignaturesDialog()
246 delete m_pSignaturesLB
;
249 sal_Bool
DigitalSignaturesDialog::Init()
251 bool bInit
= maSignatureHelper
.Init();
253 DBG_ASSERT( bInit
, "Error initializing security context!" );
257 maSignatureHelper
.SetStartVerifySignatureHdl( LINK( this, DigitalSignaturesDialog
, StartVerifySignatureHdl
) );
263 void DigitalSignaturesDialog::SetStorage( const com::sun::star::uno::Reference
< com::sun::star::embed::XStorage
>& rxStore
)
266 maSignatureHelper
.SetStorage( mxStore
, m_sODFVersion
);
268 Reference
< css::packages::manifest::XManifestReader
> xReader
=
269 css::packages::manifest::ManifestReader::create(mxCtx
);
271 //Get the manifest.xml
272 Reference
< css::embed::XStorage
> xSubStore(rxStore
->openStorageElement(
273 "META-INF", css::embed::ElementModes::READ
), UNO_QUERY_THROW
);
275 Reference
< css::io::XInputStream
> xStream(
276 xSubStore
->openStreamElement("manifest.xml", css::embed::ElementModes::READ
),
279 m_manifest
= xReader
->readManifestSequence(xStream
);
282 void DigitalSignaturesDialog::SetSignatureStream( const css::uno::Reference
< css::io::XStream
>& rxStream
)
284 mxSignatureStream
= rxStream
;
287 bool DigitalSignaturesDialog::canAddRemove()
291 OSL_ASSERT(mxStore
.is());
292 bool bDoc1_1
= DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion
);
294 bool bSave1_1
= item
.isLessODF1_2();
297 //cvs: specs/www/appwide/security/Electronic_Signatures_and_Security.sxw
298 //Paragraph 'Behavior with regard to ODF 1.2'
299 //For both, macro and document
300 if ( (!bSave1_1
&& bDoc1_1
) || (bSave1_1
&& bDoc1_1
) )
303 ErrorBox
err(NULL
, XMLSEC_RES(RID_XMLSECDLG_OLD_ODF_FORMAT
));
308 //As of OOo 3.2 the document signature includes in macrosignatures.xml. That is
309 //adding a macro signature will break an existing document signature.
310 //The sfx2 will remove the documentsignature when the user adds a macro signature
311 if (meSignatureMode
== SignatureModeMacros
314 if (m_bHasDocumentSignature
&& !m_bWarningShowSignMacro
)
316 //The warning says that the document signatures will be removed if the user
317 //continues. He can then either press 'OK' or 'NO'
318 //It the user presses 'Add' or 'Remove' several times then, then the warning
319 //is shown every time until the user presses 'OK'. From then on, the warning
320 //is not displayed anymore as long as the signatures dialog is alive.
322 NULL
, XMLSEC_RES(MSG_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN
)).Execute() == RET_NO
)
325 m_bWarningShowSignMacro
= true;
332 bool DigitalSignaturesDialog::canAdd()
339 bool DigitalSignaturesDialog::canRemove()
346 short DigitalSignaturesDialog::Execute()
348 // Verify Signatures and add certificates to ListBox...
349 mbVerifySignatures
= true;
350 ImplGetSignatureInformations(false);
351 ImplFillSignaturesBox();
353 // Only verify once, content will not change.
354 // But for refreshing signature information, StartVerifySignatureHdl will be called after each add/remove
355 mbVerifySignatures
= false;
357 return Dialog::Execute();
360 IMPL_LINK_NOARG(DigitalSignaturesDialog
, SignatureHighlightHdl
)
362 bool bSel
= m_pSignaturesLB
->FirstSelected() ? true : false;
363 m_pViewBtn
->Enable( bSel
);
364 if ( m_pAddBtn
->IsEnabled() ) // not read only
365 m_pRemoveBtn
->Enable( bSel
);
370 IMPL_LINK_NOARG(DigitalSignaturesDialog
, OKButtonHdl
)
372 // Export all other signatures...
373 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
374 embed::ElementModes::WRITE
|embed::ElementModes::TRUNCATE
, false );
375 uno::Reference
< io::XOutputStream
> xOutputStream(
376 aStreamHelper
.xSignatureStream
, uno::UNO_QUERY
);
377 uno::Reference
< com::sun::star::xml::sax::XWriter
> xSaxWriter
=
378 maSignatureHelper
.CreateDocumentHandlerWithHeader( xOutputStream
);
380 uno::Reference
< xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
, UNO_QUERY_THROW
);
381 size_t nInfos
= maCurrentSignatureInformations
.size();
382 for( size_t n
= 0 ; n
< nInfos
; ++n
)
383 maSignatureHelper
.ExportSignature(
384 xDocumentHandler
, maCurrentSignatureInformations
[ n
] );
386 maSignatureHelper
.CloseDocumentHandler( xDocumentHandler
);
388 // If stream was not provided, we are responsible for committing it....
389 if ( !mxSignatureStream
.is() )
391 uno::Reference
< embed::XTransactedObject
> xTrans(
392 aStreamHelper
.xSignatureStorage
, uno::UNO_QUERY
);
400 IMPL_LINK_NOARG(DigitalSignaturesDialog
, SignatureSelectHdl
)
402 ImplShowSignaturesDetails();
406 IMPL_LINK_NOARG(DigitalSignaturesDialog
, ViewButtonHdl
)
408 ImplShowSignaturesDetails();
412 IMPL_LINK_NOARG(DigitalSignaturesDialog
, AddButtonHdl
)
418 uno::Reference
<com::sun::star::xml::crypto::XSecurityEnvironment
> xSecEnv
= maSignatureHelper
.GetSecurityEnvironment();
420 uno::Reference
<com::sun::star::security::XSerialNumberAdapter
> xSerialNumberAdapter
=
421 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx
);
422 CertificateChooser
aChooser( this, mxCtx
, xSecEnv
, maCurrentSignatureInformations
);
423 if ( aChooser
.Execute() == RET_OK
)
425 uno::Reference
< ::com::sun::star::security::XCertificate
> xCert
= aChooser
.GetSelectedCertificate();
428 SAL_WARN( "xmlsecurity.dialogs", "no certificate selected" );
431 OUString aCertSerial
= xSerialNumberAdapter
->toString( xCert
->getSerialNumber() );
432 if ( aCertSerial
.isEmpty() )
434 OSL_FAIL( "Error in Certificate, problem with serial number!" );
438 maSignatureHelper
.StartMission();
440 sal_Int32 nSecurityId
= maSignatureHelper
.GetNewSecurityId();
442 OUStringBuffer aStrBuffer
;
443 ::sax::Converter::encodeBase64(aStrBuffer
, xCert
->getEncoded());
445 maSignatureHelper
.SetX509Certificate( nSecurityId
,
446 xCert
->getIssuerName(), aCertSerial
,
447 aStrBuffer
.makeStringAndClear());
449 std::vector
< OUString
> aElements
=
450 DocumentSignatureHelper::CreateElementList(
451 mxStore
, OUString(), meSignatureMode
, OOo3_2Document
);
453 sal_Int32 nElements
= aElements
.size();
454 for ( sal_Int32 n
= 0; n
< nElements
; n
++ )
456 bool bBinaryMode
= !isXML(aElements
[n
]);
457 maSignatureHelper
.AddForSigning( nSecurityId
, aElements
[n
], aElements
[n
], bBinaryMode
);
460 maSignatureHelper
.SetDateTime( nSecurityId
, Date( Date::SYSTEM
), Time( Time::SYSTEM
) );
462 // We open a signature stream in which the existing and the new
463 //signature is written. ImplGetSignatureInformation (later in this function) will
464 //then read the stream an will fill maCurrentSignatureInformations. The final signature
465 //is written when the user presses OK. Then only maCurrentSignatureInformation and
466 //a sax writer are used to write the information.
467 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
468 css::embed::ElementModes::WRITE
|css::embed::ElementModes::TRUNCATE
, true);
469 Reference
< css::io::XOutputStream
> xOutputStream(
470 aStreamHelper
.xSignatureStream
, UNO_QUERY_THROW
);
471 Reference
< css::xml::sax::XWriter
> xSaxWriter
=
472 maSignatureHelper
.CreateDocumentHandlerWithHeader( xOutputStream
);
474 // Export old signatures...
475 uno::Reference
< xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
, UNO_QUERY_THROW
);
476 size_t nInfos
= maCurrentSignatureInformations
.size();
477 for ( size_t n
= 0; n
< nInfos
; n
++ )
478 maSignatureHelper
.ExportSignature( xDocumentHandler
, maCurrentSignatureInformations
[n
]);
480 // Create a new one...
481 maSignatureHelper
.CreateAndWriteSignature( xDocumentHandler
);
484 maSignatureHelper
.CloseDocumentHandler( xDocumentHandler
);
486 maSignatureHelper
.EndMission();
488 aStreamHelper
= SignatureStreamHelper(); // release objects...
490 mbSignaturesChanged
= true;
492 sal_Int32 nStatus
= maSignatureHelper
.GetSignatureInformation( nSecurityId
).nStatus
;
494 if ( nStatus
== ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
)
496 mbSignaturesChanged
= true;
498 // Can't simply remember current information, need parsing for getting full information :(
499 // We need to verify the signatures again, otherwise the status in the signature information
501 // SecurityOperationStatus_OPERATION_SUCCEEDED
502 mbVerifySignatures
= true;
503 ImplGetSignatureInformations(true);
504 ImplFillSignaturesBox();
508 catch ( uno::Exception
& )
510 OSL_FAIL( "Exception while adding a signature!" );
511 // Don't keep invalid entries...
512 ImplGetSignatureInformations(true);
513 ImplFillSignaturesBox();
519 IMPL_LINK_NOARG(DigitalSignaturesDialog
, RemoveButtonHdl
)
523 if( m_pSignaturesLB
->FirstSelected() )
527 sal_uInt16 nSelected
= (sal_uInt16
) (sal_uIntPtr
) m_pSignaturesLB
->FirstSelected()->GetUserData();
528 maCurrentSignatureInformations
.erase( maCurrentSignatureInformations
.begin()+nSelected
);
530 // Export all other signatures...
531 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
532 css::embed::ElementModes::WRITE
| css::embed::ElementModes::TRUNCATE
, true);
533 Reference
< css::io::XOutputStream
> xOutputStream(
534 aStreamHelper
.xSignatureStream
, UNO_QUERY_THROW
);
535 Reference
< css::xml::sax::XWriter
> xSaxWriter
=
536 maSignatureHelper
.CreateDocumentHandlerWithHeader( xOutputStream
);
538 uno::Reference
< xml::sax::XDocumentHandler
> xDocumentHandler(xSaxWriter
, UNO_QUERY_THROW
);
539 size_t nInfos
= maCurrentSignatureInformations
.size();
540 for( size_t n
= 0 ; n
< nInfos
; ++n
)
541 maSignatureHelper
.ExportSignature( xDocumentHandler
, maCurrentSignatureInformations
[ n
] );
543 maSignatureHelper
.CloseDocumentHandler( xDocumentHandler
);
545 mbSignaturesChanged
= true;
547 aStreamHelper
= SignatureStreamHelper(); // release objects...
549 ImplFillSignaturesBox();
551 catch ( uno::Exception
& )
553 OSL_FAIL( "Exception while removing a signature!" );
554 // Don't keep invalid entries...
555 ImplGetSignatureInformations(true);
556 ImplFillSignaturesBox();
563 IMPL_LINK_NOARG(DigitalSignaturesDialog
, StartVerifySignatureHdl
)
565 return mbVerifySignatures
? 1 : 0;
568 void DigitalSignaturesDialog::ImplFillSignaturesBox()
570 m_pSignaturesLB
->Clear();
572 uno::Reference
< ::com::sun::star::xml::crypto::XSecurityEnvironment
> xSecEnv
= maSignatureHelper
.GetSecurityEnvironment();
573 uno::Reference
<com::sun::star::security::XSerialNumberAdapter
> xSerialNumberAdapter
=
574 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx
);
576 uno::Reference
< ::com::sun::star::security::XCertificate
> xCert
;
578 size_t nInfos
= maCurrentSignatureInformations
.size();
579 size_t nValidSigs
= 0, nValidCerts
= 0;
580 bool bAllNewSignatures
= true;
584 for( size_t n
= 0; n
< nInfos
; ++n
)
586 DocumentSignatureAlgorithm mode
= DocumentSignatureHelper::getDocumentAlgorithm(
587 m_sODFVersion
, maCurrentSignatureInformations
[n
]);
588 std::vector
< OUString
> aElementsToBeVerified
=
589 DocumentSignatureHelper::CreateElementList(
590 mxStore
, OUString(), meSignatureMode
, mode
);
592 const SignatureInformation
& rInfo
= maCurrentSignatureInformations
[n
];
593 //First we try to get the certificate which is embedded in the XML Signature
594 if (!rInfo
.ouX509Certificate
.isEmpty())
595 xCert
= xSecEnv
->createCertificateFromAscii(rInfo
.ouX509Certificate
);
597 //There must be an embedded certificate because we use it to get the
598 //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
599 //because it could be modified by an attacker. The issuer is displayed
600 //in the digital signature dialog.
601 //Comparing the X509IssuerName with the one from the X509Certificate in order
602 //to find out if the X509IssuerName was modified does not work. See #i62684
603 DBG_ASSERT(sal_False
, "Could not find embedded certificate!");
606 //In case there is no embedded certificate we try to get it from a local store
607 //Todo: This probably could be removed, see above.
609 xCert
= xSecEnv
->getCertificate( rInfo
.ouX509IssuerName
, xSerialNumberAdapter
->toSequence( rInfo
.ouX509SerialNumber
) );
611 DBG_ASSERT( xCert
.is(), "Certificate not found and can't be created!" );
615 OUString aDateTimeStr
;
617 bool bSigValid
= false;
618 bool bCertValid
= false;
621 //check the validity of the cert
623 sal_Int32 certResult
= xSecEnv
->verifyCertificate(xCert
,
624 Sequence
<css::uno::Reference
<css::security::XCertificate
> >());
626 bCertValid
= certResult
== css::security::CertificateValidity::VALID
? true : false;
630 } catch (css::uno::SecurityException
& ) {
631 OSL_FAIL("Verification of certificate failed");
635 aSubject
= XmlSec::GetContentPart( xCert
->getSubjectName() );
636 aIssuer
= XmlSec::GetContentPart( xCert
->getIssuerName() );
637 // String with date and time information (#i20172#)
638 aDateTimeStr
= XmlSec::GetDateTimeString( rInfo
.stDateTime
);
640 bSigValid
= ( rInfo
.nStatus
== ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED
);
644 bSigValid
= DocumentSignatureHelper::checkIfAllFilesAreSigned(
645 aElementsToBeVerified
, rInfo
, mode
);
654 aImage
= m_pSigsInvalidImg
->GetImage();
656 else if (bSigValid
&& !bCertValid
)
658 aImage
= m_pSigsNotvalidatedImg
->GetImage();
660 //Check if the signature is a "old" document signature, that is, which was created
661 //by an version of OOo previous to 3.2
662 else if (meSignatureMode
== SignatureModeDocumentContent
663 && bSigValid
&& bCertValid
&& !DocumentSignatureHelper::isOOo3_2_Signature(
664 maCurrentSignatureInformations
[n
]))
666 aImage
= m_pSigsNotvalidatedImg
->GetImage();
667 bAllNewSignatures
&= false;
669 else if (meSignatureMode
== SignatureModeDocumentContent
670 && bSigValid
&& bCertValid
&& DocumentSignatureHelper::isOOo3_2_Signature(
671 maCurrentSignatureInformations
[n
]))
673 aImage
= m_pSigsValidImg
->GetImage();
675 else if (meSignatureMode
== SignatureModeMacros
676 && bSigValid
&& bCertValid
)
678 aImage
= m_pSigsValidImg
->GetImage();
681 SvTreeListEntry
* pEntry
= m_pSignaturesLB
->InsertEntry( OUString(), aImage
, aImage
);
682 m_pSignaturesLB
->SetEntryText( aSubject
, pEntry
, 1 );
683 m_pSignaturesLB
->SetEntryText( aIssuer
, pEntry
, 2 );
684 m_pSignaturesLB
->SetEntryText( aDateTimeStr
, pEntry
, 3 );
685 pEntry
->SetUserData( ( void* ) n
); // missuse user data as index
689 bool bAllSigsValid
= (nValidSigs
== nInfos
);
690 bool bAllCertsValid
= (nValidCerts
== nInfos
);
691 bool bShowValidState
= nInfos
&& (bAllSigsValid
&& bAllCertsValid
&& bAllNewSignatures
);
693 m_pSigsValidImg
->Show( bShowValidState
);
694 m_pSigsValidFI
->Show( bShowValidState
);
696 bool bShowInvalidState
= nInfos
&& !bAllSigsValid
;
698 m_pSigsInvalidImg
->Show( bShowInvalidState
);
699 m_pSigsInvalidFI
->Show( bShowInvalidState
);
701 bool bShowNotValidatedState
= nInfos
&& bAllSigsValid
&& !bAllCertsValid
;
703 m_pSigsNotvalidatedImg
->Show(bShowNotValidatedState
);
704 m_pSigsNotvalidatedFI
->Show(bShowNotValidatedState
);
706 //bAllNewSignatures is always true if we are not in document mode
707 bool bShowOldSignature
= nInfos
&& bAllSigsValid
&& bAllCertsValid
&& !bAllNewSignatures
;
708 m_pSigsOldSignatureImg
->Show(bShowOldSignature
);
709 m_pSigsOldSignatureFI
->Show(bShowOldSignature
);
711 SignatureHighlightHdl( NULL
);
714 //If bUseTempStream is true then the temporary signature stream is used.
715 //Otherwise the real signature stream is used.
716 void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream
)
718 maCurrentSignatureInformations
.clear();
720 maSignatureHelper
.StartMission();
722 SignatureStreamHelper aStreamHelper
= ImplOpenSignatureStream(
723 css::embed::ElementModes::READ
, bUseTempStream
);
724 if ( aStreamHelper
.xSignatureStream
.is() )
726 uno::Reference
< io::XInputStream
> xInputStream( aStreamHelper
.xSignatureStream
, uno::UNO_QUERY
);
727 maSignatureHelper
.ReadAndVerifySignature( xInputStream
);
729 maSignatureHelper
.EndMission();
731 maCurrentSignatureInformations
= maSignatureHelper
.GetSignatureInformations();
733 mbVerifySignatures
= false;
736 void DigitalSignaturesDialog::ImplShowSignaturesDetails()
738 if( m_pSignaturesLB
->FirstSelected() )
740 sal_uInt16 nSelected
= (sal_uInt16
) (sal_uIntPtr
) m_pSignaturesLB
->FirstSelected()->GetUserData();
741 const SignatureInformation
& rInfo
= maCurrentSignatureInformations
[ nSelected
];
742 css::uno::Reference
<css::xml::crypto::XSecurityEnvironment
> xSecEnv
=
743 maSignatureHelper
.GetSecurityEnvironment();
744 css::uno::Reference
<com::sun::star::security::XSerialNumberAdapter
> xSerialNumberAdapter
=
745 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx
);
746 // Use Certificate from doc, not from key store
747 uno::Reference
< css::security::XCertificate
> xCert
;
748 if (!rInfo
.ouX509Certificate
.isEmpty())
749 xCert
= xSecEnv
->createCertificateFromAscii(rInfo
.ouX509Certificate
);
750 //fallback if no certificate is embedded, get if from store
752 xCert
= xSecEnv
->getCertificate( rInfo
.ouX509IssuerName
, xSerialNumberAdapter
->toSequence( rInfo
.ouX509SerialNumber
) );
754 DBG_ASSERT( xCert
.is(), "Error getting cCertificate!" );
757 CertificateViewer
aViewer( this, maSignatureHelper
.GetSecurityEnvironment(), xCert
, false );
763 //If bTempStream is true, then a temporary stream is return. If it is false then, the actual
764 //signature stream is used.
765 //Everytime the user presses Add a new temporary stream is created.
766 //We keep the temporary stream as member because ImplGetSignatureInformations
767 //will later access the stream to create DocumentSignatureInformation objects
768 //which are stored in maCurrentSignatureInformations.
769 SignatureStreamHelper
DigitalSignaturesDialog::ImplOpenSignatureStream(
770 sal_Int32 nStreamOpenMode
, bool bTempStream
)
772 SignatureStreamHelper aHelper
;
775 if (nStreamOpenMode
& css::embed::ElementModes::TRUNCATE
)
777 //We write always into a new temporary stream.
778 mxTempSignatureStream
= Reference
< css::io::XStream
>(css::io::TempFile::create(mxCtx
), UNO_QUERY_THROW
);
779 aHelper
.xSignatureStream
= mxTempSignatureStream
;
783 //When we read from the temp stream, then we must have previously
785 OSL_ASSERT(mxTempSignatureStream
.is());
787 aHelper
.xSignatureStream
= mxTempSignatureStream
;
791 //No temporary stream
792 if (!mxSignatureStream
.is())
794 //We may not have a dedicated stream for writing the signature
795 //So we take one directly from the storage
796 //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
797 //in which case Add/Remove is not allowed. This is done, for example, if the
798 //document is readonly
799 aHelper
= DocumentSignatureHelper::OpenSignatureStream(
800 mxStore
, nStreamOpenMode
, meSignatureMode
);
804 aHelper
.xSignatureStream
= mxSignatureStream
;
808 if (nStreamOpenMode
& css::embed::ElementModes::TRUNCATE
)
810 css::uno::Reference
< css::io::XTruncate
> xTruncate(
811 aHelper
.xSignatureStream
, UNO_QUERY_THROW
);
812 DBG_ASSERT( xTruncate
.is(), "ImplOpenSignatureStream - Stream does not support xTruncate!" );
813 xTruncate
->truncate();
815 else if ( bTempStream
|| mxSignatureStream
.is())
817 //In case we read the signature stream from the storage directly,
818 //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
819 //then XSeakable is not supported
820 css::uno::Reference
< css::io::XSeekable
> xSeek(
821 aHelper
.xSignatureStream
, UNO_QUERY_THROW
);
822 DBG_ASSERT( xSeek
.is(), "ImplOpenSignatureStream - Stream does not support xSeekable!" );
829 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */