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/certificateviewer.hxx>
21 #include <com/sun/star/security/XCertificate.hpp>
23 #include <com/sun/star/security/CertificateCharacters.hpp>
24 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
25 #include <com/sun/star/security/CertificateValidity.hpp>
27 #include <unotools/localedatawrapper.hxx>
28 #include <unotools/datetime.hxx>
29 #include <svtools/treelistentry.hxx>
31 #include "dialogs.hrc"
32 #include "resourcemanager.hxx"
34 #include <vcl/settings.hxx>
36 using namespace ::com::sun::star
;
37 using namespace ::com::sun::star::uno
;
39 CertificateViewer::CertificateViewer(
40 vcl::Window
* _pParent
,
41 const css::uno::Reference
< css::xml::crypto::XSecurityEnvironment
>& _rxSecurityEnvironment
,
42 const css::uno::Reference
< css::security::XCertificate
>& _rXCert
, bool bCheckForPrivateKey
)
43 : TabDialog(_pParent
, "ViewCertDialog", "xmlsec/ui/viewcertdialog.ui" )
45 get(mpTabCtrl
, "tabcontrol");
47 mbCheckForPrivateKey
= bCheckForPrivateKey
;
49 mxSecurityEnvironment
= _rxSecurityEnvironment
;
52 mnGeneralId
= mpTabCtrl
->GetPageId("general");
53 mnDetailsId
= mpTabCtrl
->GetPageId("details");
54 mnPathId
= mpTabCtrl
->GetPageId("path");
56 mpTabCtrl
->SetTabPage(mnGeneralId
, VclPtr
<CertificateViewerGeneralTP
>::Create( mpTabCtrl
, this));
57 mpTabCtrl
->SetTabPage(mnDetailsId
, VclPtr
<CertificateViewerDetailsTP
>::Create( mpTabCtrl
, this));
58 mpTabCtrl
->SetTabPage(mnPathId
, VclPtr
<CertificateViewerCertPathTP
>::Create( mpTabCtrl
, this));
59 mpTabCtrl
->SetCurPageId(mnGeneralId
);
62 CertificateViewer::~CertificateViewer()
67 void CertificateViewer::dispose()
69 mpTabCtrl
->GetTabPage(mnGeneralId
)->disposeOnce();
70 mpTabCtrl
->GetTabPage(mnDetailsId
)->disposeOnce();
71 mpTabCtrl
->GetTabPage(mnPathId
)->disposeOnce();
76 CertificateViewerTP::CertificateViewerTP( vcl::Window
* _pParent
, const OString
& rID
,
77 const OUString
& rUIXMLDescription
, CertificateViewer
* _pDlg
)
78 : TabPage(_pParent
, rID
, rUIXMLDescription
)
83 CertificateViewerTP::~CertificateViewerTP()
88 void CertificateViewerTP::dispose()
95 CertificateViewerGeneralTP::CertificateViewerGeneralTP( vcl::Window
* _pParent
, CertificateViewer
* _pDlg
)
96 :CertificateViewerTP ( _pParent
, "CertGeneral", "xmlsec/ui/certgeneral.ui", _pDlg
)
98 get( m_pCertImg
, "certimage" );
99 get( m_pHintNotTrustedFI
, "hintnotrust" );
100 get( m_pIssuedToFI
, "issued_to_value" );
101 get( m_pIssuedByFI
, "issued_by_value" );
102 get( m_pValidFromDateFI
, "valid_from_value" );
103 get( m_pValidToDateFI
, "valid_to_value" );
104 get( m_pKeyImg
, "keyimage" );
105 get( m_pHintCorrespPrivKeyFI
, "privatekey" );
107 //Verify the certificate
108 sal_Int32 certStatus
= mpDlg
->mxSecurityEnvironment
->verifyCertificate(mpDlg
->mxCert
,
109 Sequence
<Reference
<css::security::XCertificate
> >());
111 bool bCertValid
= certStatus
== css::security::CertificateValidity::VALID
;
115 m_pCertImg
->SetImage(
116 Image( XMLSEC_RES( IMG_STATE_NOT_VALIDATED
) ) );
117 m_pHintNotTrustedFI
->SetText( XMLSEC_RES( STR_CERTIFICATE_NOT_VALIDATED
) );
121 css::uno::Reference
< css::security::XCertificate
> xCert
= mpDlg
->mxCert
;
123 m_pIssuedToFI
->SetText( XmlSec::GetContentPart( xCert
->getSubjectName() ) );
124 m_pIssuedByFI
->SetText( XmlSec::GetContentPart( xCert
->getIssuerName() ) );
126 DateTime
aDateTimeStart( DateTime::EMPTY
);
127 DateTime
aDateTimeEnd( DateTime::EMPTY
);
128 utl::typeConvert( xCert
->getNotValidBefore(), aDateTimeStart
);
129 utl::typeConvert( xCert
->getNotValidAfter(), aDateTimeEnd
);
131 OUString sValidFromDate
= GetSettings().GetUILocaleDataWrapper().getDate( aDateTimeStart
.GetDate() );
132 OUString sValidToDate
= GetSettings().GetUILocaleDataWrapper().getDate( aDateTimeEnd
.GetDate() );
134 m_pValidFromDateFI
->SetText(sValidFromDate
);
135 m_pValidToDateFI
->SetText(sValidToDate
);
137 // Check if we have the private key...
138 bool bHasPrivateKey
= false;
139 // #i41270# Check only if we have that certificate in our security environment
140 if ( _pDlg
->mbCheckForPrivateKey
)
142 long nCertificateCharacters
= _pDlg
->mxSecurityEnvironment
->getCertificateCharacters( xCert
);
143 bHasPrivateKey
= ( nCertificateCharacters
& security::CertificateCharacters::HAS_PRIVATE_KEY
);
145 if ( !bHasPrivateKey
)
148 m_pHintCorrespPrivKeyFI
->Hide();
152 CertificateViewerGeneralTP::~CertificateViewerGeneralTP()
157 void CertificateViewerGeneralTP::dispose()
160 m_pHintNotTrustedFI
.clear();
161 m_pIssuedToFI
.clear();
162 m_pIssuedByFI
.clear();
163 m_pValidFromDateFI
.clear();
164 m_pValidToDateFI
.clear();
166 m_pHintCorrespPrivKeyFI
.clear();
167 CertificateViewerTP::dispose();
170 void CertificateViewerGeneralTP::ActivatePage()
176 struct Details_UserDatat
179 bool mbFixedWidthFont
;
181 inline Details_UserDatat( const OUString
& _rTxt
, bool _bFixedWidthFont
);
184 inline Details_UserDatat::Details_UserDatat( const OUString
& _rTxt
, bool _bFixedWidthFont
)
186 ,mbFixedWidthFont ( _bFixedWidthFont
)
191 void CertificateViewerDetailsTP::Clear()
193 m_pValueDetails
->SetText( OUString() );
195 SvTreeListEntry
* pEntry
= m_pElementsLB
->GetEntry( i
);
198 delete static_cast<Details_UserDatat
*>(pEntry
->GetUserData());
200 pEntry
= m_pElementsLB
->GetEntry( i
);
203 m_pElementsLB
->Clear();
206 void CertificateViewerDetailsTP::InsertElement( const OUString
& _rField
, const OUString
& _rValue
,
207 const OUString
& _rDetails
, bool _bFixedWidthFont
)
209 SvTreeListEntry
* pEntry
= m_pElementsLB
->InsertEntry( _rField
);
210 m_pElementsLB
->SetEntryText( _rValue
, pEntry
, 1 );
211 pEntry
->SetUserData( ( void* ) new Details_UserDatat( _rDetails
, _bFixedWidthFont
) );
214 CertificateViewerDetailsTP::CertificateViewerDetailsTP( vcl::Window
* _pParent
, CertificateViewer
* _pDlg
)
215 :CertificateViewerTP ( _pParent
, "CertDetails", "xmlsec/ui/certdetails.ui", _pDlg
)
216 ,m_aFixedWidthFont( OutputDevice::GetDefaultFont( DefaultFontType::UI_FIXED
, LANGUAGE_DONTKNOW
, GetDefaultFontFlags::OnlyOne
, this ) )
218 get( m_pValueDetails
, "valuedetails" );
219 get( m_pElementsLBContainer
, "tablecontainer" );
220 m_pElementsLB
= VclPtr
<SvSimpleTable
>::Create( *m_pElementsLBContainer
);
222 m_aStdFont
= m_pValueDetails
->GetControlFont();
223 WinBits nStyle
= m_pElementsLB
->GetStyle();
224 nStyle
&= ~WB_HSCROLL
;
225 m_pElementsLB
->SetStyle( nStyle
);
227 m_aFixedWidthFont
.SetHeight( m_aStdFont
.GetHeight() );
229 static long nTabs
[] = { 2, 0, 30*CS_LB_WIDTH
/100 };
230 m_pElementsLB
->SetTabs( &nTabs
[ 0 ] );
231 m_pElementsLB
->InsertHeaderEntry( XMLSEC_RES( STR_HEADERBAR
) );
234 Reference
< security::XCertificate
> xCert
= mpDlg
->mxCert
;
235 sal_uInt16 nLineBreak
= 16;
236 const char* pHexSep
= " ";
239 // Certificate Versions are reported wrong (#i35107#) - 0 == "V1", 1 == "V2", ..., n = "V(n+1)"
240 aLBEntry
= "V" + OUString::number( xCert
->getVersion() + 1 );
241 InsertElement( XMLSEC_RES( STR_VERSION
), aLBEntry
, aLBEntry
);
242 Sequence
< sal_Int8
> aSeq
= xCert
->getSerialNumber();
243 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
244 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
245 InsertElement( XMLSEC_RES( STR_SERIALNUM
), aLBEntry
, aDetails
, true );
247 std::pair
< OUString
, OUString
> pairIssuer
=
248 XmlSec::GetDNForCertDetailsView(xCert
->getIssuerName());
249 aLBEntry
= pairIssuer
.first
;
250 aDetails
= pairIssuer
.second
;
251 InsertElement( XMLSEC_RES( STR_ISSUER
), aLBEntry
, aDetails
);
253 DateTime
aDateTime( DateTime::EMPTY
);
254 utl::typeConvert( xCert
->getNotValidBefore(), aDateTime
);
255 aLBEntry
= GetSettings().GetUILocaleDataWrapper().getDate( aDateTime
.GetDate() );
257 aLBEntry
+= GetSettings().GetUILocaleDataWrapper().getTime( aDateTime
.GetTime() );
258 InsertElement( XMLSEC_RES( STR_VALIDFROM
), aLBEntry
, aLBEntry
);
259 utl::typeConvert( xCert
->getNotValidAfter(), aDateTime
);
260 aLBEntry
= GetSettings().GetUILocaleDataWrapper().getDate( aDateTime
.GetDate() );
262 aLBEntry
+= GetSettings().GetUILocaleDataWrapper().getTime( aDateTime
.GetTime() );
263 InsertElement( XMLSEC_RES( STR_VALIDTO
), aLBEntry
, aLBEntry
);
265 std::pair
< OUString
, OUString
> pairSubject
=
266 XmlSec::GetDNForCertDetailsView(xCert
->getSubjectName());
267 aLBEntry
= pairSubject
.first
;
268 aDetails
= pairSubject
.second
;
269 InsertElement( XMLSEC_RES( STR_SUBJECT
), aLBEntry
, aDetails
);
271 aLBEntry
= aDetails
= xCert
->getSubjectPublicKeyAlgorithm();
272 InsertElement( XMLSEC_RES( STR_SUBJECT_PUBKEY_ALGO
), aLBEntry
, aDetails
);
273 aSeq
= xCert
->getSubjectPublicKeyValue();
274 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
275 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
276 InsertElement( XMLSEC_RES( STR_SUBJECT_PUBKEY_VAL
), aLBEntry
, aDetails
, true );
278 aLBEntry
= aDetails
= xCert
->getSignatureAlgorithm();
279 InsertElement( XMLSEC_RES( STR_SIGNATURE_ALGO
), aLBEntry
, aDetails
);
281 aSeq
= xCert
->getSHA1Thumbprint();
282 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
283 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
284 InsertElement( XMLSEC_RES( STR_THUMBPRINT_SHA1
), aLBEntry
, aDetails
, true );
286 aSeq
= xCert
->getMD5Thumbprint();
287 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
288 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
289 InsertElement( XMLSEC_RES( STR_THUMBPRINT_MD5
), aLBEntry
, aDetails
, true );
291 m_pElementsLB
->SetSelectHdl( LINK( this, CertificateViewerDetailsTP
, ElementSelectHdl
) );
294 CertificateViewerDetailsTP::~CertificateViewerDetailsTP()
299 void CertificateViewerDetailsTP::dispose()
302 m_pElementsLB
.disposeAndClear();
303 m_pElementsLBContainer
.clear();
304 m_pValueDetails
.clear();
305 CertificateViewerTP::dispose();
308 void CertificateViewerDetailsTP::ActivatePage()
312 IMPL_LINK_NOARG(CertificateViewerDetailsTP
, ElementSelectHdl
)
314 SvTreeListEntry
* pEntry
= m_pElementsLB
->FirstSelected();
315 OUString aElementText
;
316 bool bFixedWidthFont
;
319 const Details_UserDatat
* p
= static_cast<Details_UserDatat
*>(pEntry
->GetUserData());
320 aElementText
= p
->maTxt
;
321 bFixedWidthFont
= p
->mbFixedWidthFont
;
324 bFixedWidthFont
= false;
326 m_pValueDetails
->SetFont( bFixedWidthFont
? m_aFixedWidthFont
: m_aStdFont
);
327 m_pValueDetails
->SetControlFont( bFixedWidthFont
? m_aFixedWidthFont
: m_aStdFont
);
328 m_pValueDetails
->SetText( aElementText
);
333 struct CertPath_UserData
335 css::uno::Reference
< css::security::XCertificate
> mxCert
;
339 CertPath_UserData( css::uno::Reference
< css::security::XCertificate
> xCert
, bool bValid
):
347 CertificateViewerCertPathTP::CertificateViewerCertPathTP( vcl::Window
* _pParent
, CertificateViewer
* _pDlg
)
348 : CertificateViewerTP(_pParent
, "CertPage", "xmlsec/ui/certpage.ui", _pDlg
)
350 , mbFirstActivateDone(false)
352 get(mpCertPathLB
, "signatures");
353 get(mpViewCertPB
, "viewcert");
354 get(mpCertStatusML
, "status");
356 msCertOK
= get
<FixedText
>("certok")->GetText();
357 msCertNotValidated
= get
<FixedText
>("certnotok")->GetText();
358 maCertImage
= get
<FixedImage
>("imgok")->GetImage();
359 maCertNotValidatedImage
= get
<FixedImage
>("imgnotok")->GetImage();
361 Size
aControlSize(LogicToPixel(Size(251, 45), MAP_APPFONT
));
362 mpCertPathLB
->set_width_request(aControlSize
.Width());
363 mpCertPathLB
->set_height_request(aControlSize
.Height());
364 mpCertStatusML
->set_width_request(aControlSize
.Width());
365 mpCertStatusML
->set_height_request(aControlSize
.Height());
367 mpCertPathLB
->SetNodeDefaultImages();
368 mpCertPathLB
->SetSublistOpenWithLeftRight();
369 mpCertPathLB
->SetSelectHdl( LINK( this, CertificateViewerCertPathTP
, CertSelectHdl
) );
370 mpViewCertPB
->SetClickHdl( LINK( this, CertificateViewerCertPathTP
, ViewCertHdl
) );
373 CertificateViewerCertPathTP::~CertificateViewerCertPathTP()
378 void CertificateViewerCertPathTP::dispose()
381 mpCertPathLB
.clear();
382 mpViewCertPB
.clear();
383 mpCertStatusML
.clear();
385 CertificateViewerTP::dispose();
388 void CertificateViewerCertPathTP::ActivatePage()
390 if ( !mbFirstActivateDone
)
392 mbFirstActivateDone
= true;
393 Sequence
< Reference
< security::XCertificate
> > aCertPath
=
394 mpParent
->mxSecurityEnvironment
->buildCertificatePath( mpParent
->mxCert
);
395 const Reference
< security::XCertificate
>* pCertPath
= aCertPath
.getConstArray();
397 sal_Int32 i
, nCnt
= aCertPath
.getLength();
398 SvTreeListEntry
* pParent
= NULL
;
401 const Reference
< security::XCertificate
> rCert
= pCertPath
[ --i
];
402 OUString sName
= XmlSec::GetContentPart( rCert
->getSubjectName() );
403 //Verify the certificate
404 sal_Int32 certStatus
= mpDlg
->mxSecurityEnvironment
->verifyCertificate(rCert
,
405 Sequence
<Reference
<css::security::XCertificate
> >());
406 bool bCertValid
= certStatus
== css::security::CertificateValidity::VALID
;
407 pParent
= InsertCert( pParent
, sName
, rCert
, bCertValid
);
410 mpCertPathLB
->Select( pParent
);
411 mpViewCertPB
->Disable(); // Own certificate selected
415 mpCertPathLB
->Expand( pParent
);
416 pParent
= mpCertPathLB
->GetParent( pParent
);
419 CertSelectHdl( NULL
);
423 IMPL_LINK_NOARG(CertificateViewerCertPathTP
, ViewCertHdl
)
425 SvTreeListEntry
* pEntry
= mpCertPathLB
->FirstSelected();
428 ScopedVclPtrInstance
< CertificateViewer
> aViewer(
429 this, mpDlg
->mxSecurityEnvironment
,
430 static_cast<CertPath_UserData
*>(pEntry
->GetUserData())->mxCert
,
438 IMPL_LINK_NOARG(CertificateViewerCertPathTP
, CertSelectHdl
)
441 SvTreeListEntry
* pEntry
= mpCertPathLB
->FirstSelected();
444 CertPath_UserData
* pData
= static_cast<CertPath_UserData
*>(pEntry
->GetUserData());
446 sStatus
= pData
->mbValid
? msCertOK
: msCertNotValidated
;
449 mpCertStatusML
->SetText( sStatus
);
450 mpViewCertPB
->Enable( pEntry
&& ( pEntry
!= mpCertPathLB
->Last() ) );
454 void CertificateViewerCertPathTP::Clear()
456 mpCertStatusML
->SetText( OUString() );
458 SvTreeListEntry
* pEntry
= mpCertPathLB
->GetEntry( i
);
461 delete static_cast<CertPath_UserData
*>(pEntry
->GetUserData());
463 pEntry
= mpCertPathLB
->GetEntry( i
);
466 mpCertPathLB
->Clear();
469 SvTreeListEntry
* CertificateViewerCertPathTP::InsertCert(
470 SvTreeListEntry
* _pParent
, const OUString
& _rName
, css::uno::Reference
< css::security::XCertificate
> rxCert
,
473 Image aImage
= bValid
? maCertImage
: maCertNotValidatedImage
;
474 SvTreeListEntry
* pEntry
= mpCertPathLB
->InsertEntry( _rName
, aImage
, aImage
, _pParent
);
475 pEntry
->SetUserData( ( void* ) new CertPath_UserData( rxCert
, bValid
) );
480 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */