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 <certificatechooser.hxx>
21 #include <certificateviewer.hxx>
22 #include <com/sun/star/security/XCertificate.hpp>
24 #include <com/sun/star/security/CertificateCharacters.hpp>
25 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
26 #include <com/sun/star/security/CertificateValidity.hpp>
28 #include <unotools/localedatawrapper.hxx>
29 #include <unotools/datetime.hxx>
30 #include <svtools/treelistentry.hxx>
32 #include "dialogs.hrc"
33 #include "resourcemanager.hxx"
34 #include "bitmaps.hlst"
36 #include <vcl/settings.hxx>
38 using namespace ::com::sun::star
;
39 using namespace ::com::sun::star::uno
;
41 CertificateViewer::CertificateViewer(
42 vcl::Window
* _pParent
,
43 const css::uno::Reference
< css::xml::crypto::XSecurityEnvironment
>& _rxSecurityEnvironment
,
44 const css::uno::Reference
< css::security::XCertificate
>& _rXCert
, bool bCheckForPrivateKey
)
45 : TabDialog(_pParent
, "ViewCertDialog", "xmlsec/ui/viewcertdialog.ui" )
47 get(mpTabCtrl
, "tabcontrol");
49 mbCheckForPrivateKey
= bCheckForPrivateKey
;
51 mxSecurityEnvironment
= _rxSecurityEnvironment
;
54 mnGeneralId
= mpTabCtrl
->GetPageId("general");
55 mnDetailsId
= mpTabCtrl
->GetPageId("details");
56 mnPathId
= mpTabCtrl
->GetPageId("path");
58 mpTabCtrl
->SetTabPage(mnGeneralId
, VclPtr
<CertificateViewerGeneralTP
>::Create( mpTabCtrl
, this));
59 mpTabCtrl
->SetTabPage(mnDetailsId
, VclPtr
<CertificateViewerDetailsTP
>::Create( mpTabCtrl
, this));
60 if (mxSecurityEnvironment
->buildCertificatePath(mxCert
).getLength() == 0)
61 mpTabCtrl
->RemovePage(mnPathId
);
63 mpTabCtrl
->SetTabPage(mnPathId
, VclPtr
<CertificateViewerCertPathTP
>::Create( mpTabCtrl
, this));
64 mpTabCtrl
->SetCurPageId(mnGeneralId
);
67 CertificateViewer::~CertificateViewer()
72 void CertificateViewer::dispose()
74 mpTabCtrl
->GetTabPage(mnGeneralId
)->disposeOnce();
75 mpTabCtrl
->GetTabPage(mnDetailsId
)->disposeOnce();
76 if (mpTabCtrl
->GetTabPage(mnPathId
))
77 mpTabCtrl
->GetTabPage(mnPathId
)->disposeOnce();
82 CertificateViewerTP::CertificateViewerTP( vcl::Window
* _pParent
, const OString
& rID
,
83 const OUString
& rUIXMLDescription
, CertificateViewer
* _pDlg
)
84 : TabPage(_pParent
, rID
, rUIXMLDescription
)
89 CertificateViewerTP::~CertificateViewerTP()
94 void CertificateViewerTP::dispose()
101 CertificateViewerGeneralTP::CertificateViewerGeneralTP( vcl::Window
* _pParent
, CertificateViewer
* _pDlg
)
102 :CertificateViewerTP ( _pParent
, "CertGeneral", "xmlsec/ui/certgeneral.ui", _pDlg
)
104 get( m_pCertImg
, "certimage" );
105 get( m_pHintNotTrustedFT
, "hintnotrust" );
106 get( m_pIssuedToLabelFT
, "issued_to" );
107 get( m_pIssuedToFT
, "issued_to_value" );
108 get( m_pIssuedByLabelFT
, "issued_by");
109 get( m_pIssuedByFT
, "issued_by_value" );
110 get( m_pValidFromDateFT
, "valid_from_value" );
111 get( m_pValidToDateFT
, "valid_to_value" );
112 get( m_pKeyImg
, "keyimage" );
113 get( m_pHintCorrespPrivKeyFT
, "privatekey" );
115 //Verify the certificate
116 sal_Int32 certStatus
= mpDlg
->mxSecurityEnvironment
->verifyCertificate(mpDlg
->mxCert
,
117 Sequence
<Reference
<css::security::XCertificate
> >());
119 bool bCertValid
= certStatus
== css::security::CertificateValidity::VALID
;
123 m_pCertImg
->SetImage(Image(BitmapEx(BMP_STATE_NOT_VALIDATED
)));
124 m_pHintNotTrustedFT
->SetText( XsResId( STR_CERTIFICATE_NOT_VALIDATED
) );
128 css::uno::Reference
< css::security::XCertificate
> xCert
= mpDlg
->mxCert
;
130 OUString
sSubjectName(XmlSec::GetContentPart(xCert
->getSubjectName()));
131 if (!sSubjectName
.isEmpty())
132 m_pIssuedToFT
->SetText(sSubjectName
);
134 m_pIssuedToLabelFT
->Hide();
135 OUString
sIssuerName(XmlSec::GetContentPart(xCert
->getIssuerName()));
136 if (!sIssuerName
.isEmpty())
137 m_pIssuedByFT
->SetText(sIssuerName
);
139 m_pIssuedByLabelFT
->Hide();
141 DateTime
aDateTimeStart( DateTime::EMPTY
);
142 DateTime
aDateTimeEnd( DateTime::EMPTY
);
143 utl::typeConvert( xCert
->getNotValidBefore(), aDateTimeStart
);
144 utl::typeConvert( xCert
->getNotValidAfter(), aDateTimeEnd
);
146 OUString sValidFromDate
= GetSettings().GetUILocaleDataWrapper().getDate( Date( aDateTimeStart
.GetDate()));
147 OUString sValidToDate
= GetSettings().GetUILocaleDataWrapper().getDate( Date( aDateTimeEnd
.GetDate()));
149 m_pValidFromDateFT
->SetText(sValidFromDate
);
150 m_pValidToDateFT
->SetText(sValidToDate
);
152 // Check if we have the private key...
153 bool bHasPrivateKey
= false;
154 // #i41270# Check only if we have that certificate in our security environment
155 if ( _pDlg
->mbCheckForPrivateKey
)
157 long nCertificateCharacters
= _pDlg
->mxSecurityEnvironment
->getCertificateCharacters( xCert
);
158 bHasPrivateKey
= ( nCertificateCharacters
& security::CertificateCharacters::HAS_PRIVATE_KEY
);
160 if ( !bHasPrivateKey
)
163 m_pHintCorrespPrivKeyFT
->Hide();
167 CertificateViewerGeneralTP::~CertificateViewerGeneralTP()
172 void CertificateViewerGeneralTP::dispose()
175 m_pHintNotTrustedFT
.clear();
176 m_pIssuedToLabelFT
.clear();
177 m_pIssuedToFT
.clear();
178 m_pIssuedByLabelFT
.clear();
179 m_pIssuedByFT
.clear();
180 m_pValidFromDateFT
.clear();
181 m_pValidToDateFT
.clear();
183 m_pHintCorrespPrivKeyFT
.clear();
184 CertificateViewerTP::dispose();
187 void CertificateViewerGeneralTP::ActivatePage()
193 struct Details_UserDatat
196 bool mbFixedWidthFont
;
198 inline Details_UserDatat( const OUString
& _rTxt
, bool _bFixedWidthFont
);
201 inline Details_UserDatat::Details_UserDatat( const OUString
& _rTxt
, bool _bFixedWidthFont
)
203 ,mbFixedWidthFont ( _bFixedWidthFont
)
208 void CertificateViewerDetailsTP::Clear()
210 m_pValueDetails
->SetText( OUString() );
212 SvTreeListEntry
* pEntry
= m_pElementsLB
->GetEntry( i
);
215 delete static_cast<Details_UserDatat
*>(pEntry
->GetUserData());
217 pEntry
= m_pElementsLB
->GetEntry( i
);
220 m_pElementsLB
->Clear();
223 void CertificateViewerDetailsTP::InsertElement( const OUString
& _rField
, const OUString
& _rValue
,
224 const OUString
& _rDetails
, bool _bFixedWidthFont
)
226 SvTreeListEntry
* pEntry
= m_pElementsLB
->InsertEntry( _rField
);
227 m_pElementsLB
->SetEntryText( _rValue
, pEntry
, 1 );
228 pEntry
->SetUserData( static_cast<void*>(new Details_UserDatat( _rDetails
, _bFixedWidthFont
)) );
231 CertificateViewerDetailsTP::CertificateViewerDetailsTP( vcl::Window
* _pParent
, CertificateViewer
* _pDlg
)
232 :CertificateViewerTP ( _pParent
, "CertDetails", "xmlsec/ui/certdetails.ui", _pDlg
)
233 ,m_aFixedWidthFont( OutputDevice::GetDefaultFont( DefaultFontType::UI_FIXED
, LANGUAGE_DONTKNOW
, GetDefaultFontFlags::OnlyOne
, this ) )
235 get( m_pValueDetails
, "valuedetails" );
236 WinBits nStyle
= m_pValueDetails
->GetStyle();
237 nStyle
|= WB_AUTOVSCROLL
;
238 m_pValueDetails
->SetStyle(nStyle
);
239 get( m_pElementsLBContainer
, "tablecontainer" );
240 m_pElementsLB
= VclPtr
<SvSimpleTable
>::Create( *m_pElementsLBContainer
);
242 m_aStdFont
= m_pValueDetails
->GetControlFont();
243 nStyle
= m_pElementsLB
->GetStyle();
244 nStyle
&= ~WB_HSCROLL
;
245 m_pElementsLB
->SetStyle( nStyle
);
247 m_aFixedWidthFont
.SetFontHeight( m_aStdFont
.GetFontHeight() );
249 constexpr int DLGS_WIDTH
= 287;
250 constexpr int CS_LB_WIDTH
= (DLGS_WIDTH
- RSC_SP_DLG_INNERBORDER_RIGHT
) - RSC_SP_DLG_INNERBORDER_LEFT
;
251 static long nTabs
[] = { 2, 0, 30*CS_LB_WIDTH
/100 };
252 m_pElementsLB
->SetTabs( &nTabs
[ 0 ] );
253 m_pElementsLB
->InsertHeaderEntry( XsResId( STR_HEADERBAR
) );
256 Reference
< security::XCertificate
> xCert
= mpDlg
->mxCert
;
257 sal_uInt16 nLineBreak
= 16;
258 const char* const pHexSep
= " ";
261 // Certificate Versions are reported wrong (#i35107#) - 0 == "V1", 1 == "V2", ..., n = "V(n+1)"
262 aLBEntry
= "V" + OUString::number( xCert
->getVersion() + 1 );
263 InsertElement( XsResId( STR_VERSION
), aLBEntry
, aLBEntry
);
264 Sequence
< sal_Int8
> aSeq
= xCert
->getSerialNumber();
265 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
266 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
267 InsertElement( XsResId( STR_SERIALNUM
), aLBEntry
, aDetails
, true );
269 std::pair
< OUString
, OUString
> pairIssuer
=
270 XmlSec::GetDNForCertDetailsView(xCert
->getIssuerName());
271 aLBEntry
= pairIssuer
.first
;
272 aDetails
= pairIssuer
.second
;
273 InsertElement( XsResId( STR_ISSUER
), aLBEntry
, aDetails
);
275 DateTime
aDateTime( DateTime::EMPTY
);
276 utl::typeConvert( xCert
->getNotValidBefore(), aDateTime
);
277 aLBEntry
= GetSettings().GetUILocaleDataWrapper().getDate( Date( aDateTime
.GetDate()) );
279 aLBEntry
+= GetSettings().GetUILocaleDataWrapper().getTime( aDateTime
.GetTime() );
280 InsertElement( XsResId( STR_VALIDFROM
), aLBEntry
, aLBEntry
);
281 utl::typeConvert( xCert
->getNotValidAfter(), aDateTime
);
282 aLBEntry
= GetSettings().GetUILocaleDataWrapper().getDate( Date( aDateTime
.GetDate()) );
284 aLBEntry
+= GetSettings().GetUILocaleDataWrapper().getTime( aDateTime
.GetTime() );
285 InsertElement( XsResId( STR_VALIDTO
), aLBEntry
, aLBEntry
);
287 std::pair
< OUString
, OUString
> pairSubject
=
288 XmlSec::GetDNForCertDetailsView(xCert
->getSubjectName());
289 aLBEntry
= pairSubject
.first
;
290 aDetails
= pairSubject
.second
;
291 InsertElement( XsResId( STR_SUBJECT
), aLBEntry
, aDetails
);
293 aLBEntry
= aDetails
= xCert
->getSubjectPublicKeyAlgorithm();
294 InsertElement( XsResId( STR_SUBJECT_PUBKEY_ALGO
), aLBEntry
, aDetails
);
295 aSeq
= xCert
->getSubjectPublicKeyValue();
296 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
297 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
298 InsertElement( XsResId( STR_SUBJECT_PUBKEY_VAL
), aLBEntry
, aDetails
, true );
300 aLBEntry
= aDetails
= xCert
->getSignatureAlgorithm();
301 InsertElement( XsResId( STR_SIGNATURE_ALGO
), aLBEntry
, aDetails
);
303 CertificateChooser
* pChooser
= dynamic_cast<CertificateChooser
*>(mpDlg
->GetParent());
306 aLBEntry
= pChooser
->UsageInClearText( mpDlg
->mxCert
->getCertificateUsage() );
307 InsertElement( XsResId( STR_USE
), aLBEntry
, aLBEntry
);
310 aSeq
= xCert
->getSHA1Thumbprint();
311 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
312 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
313 InsertElement( XsResId( STR_THUMBPRINT_SHA1
), aLBEntry
, aDetails
, true );
315 aSeq
= xCert
->getMD5Thumbprint();
316 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
317 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
318 InsertElement( XsResId( STR_THUMBPRINT_MD5
), aLBEntry
, aDetails
, true );
320 m_pElementsLB
->SetSelectHdl( LINK( this, CertificateViewerDetailsTP
, ElementSelectHdl
) );
323 CertificateViewerDetailsTP::~CertificateViewerDetailsTP()
328 void CertificateViewerDetailsTP::dispose()
331 m_pElementsLB
.disposeAndClear();
332 m_pElementsLBContainer
.clear();
333 m_pValueDetails
.clear();
334 CertificateViewerTP::dispose();
337 void CertificateViewerDetailsTP::ActivatePage()
341 IMPL_LINK_NOARG(CertificateViewerDetailsTP
, ElementSelectHdl
, SvTreeListBox
*, void)
343 SvTreeListEntry
* pEntry
= m_pElementsLB
->FirstSelected();
344 OUString aElementText
;
345 bool bFixedWidthFont
;
348 const Details_UserDatat
* p
= static_cast<Details_UserDatat
*>(pEntry
->GetUserData());
349 aElementText
= p
->maTxt
;
350 bFixedWidthFont
= p
->mbFixedWidthFont
;
353 bFixedWidthFont
= false;
355 m_pValueDetails
->SetFont( bFixedWidthFont
? m_aFixedWidthFont
: m_aStdFont
);
356 m_pValueDetails
->SetControlFont( bFixedWidthFont
? m_aFixedWidthFont
: m_aStdFont
);
357 m_pValueDetails
->SetText( aElementText
);
360 struct CertPath_UserData
362 css::uno::Reference
< css::security::XCertificate
> mxCert
;
365 CertPath_UserData( css::uno::Reference
< css::security::XCertificate
> const & xCert
, bool bValid
):
373 CertificateViewerCertPathTP::CertificateViewerCertPathTP( vcl::Window
* _pParent
, CertificateViewer
* _pDlg
)
374 : CertificateViewerTP(_pParent
, "CertPage", "xmlsec/ui/certpage.ui", _pDlg
)
376 , mbFirstActivateDone(false)
378 get(mpCertPathLB
, "signatures");
379 get(mpViewCertPB
, "viewcert");
380 get(mpCertStatusML
, "status");
382 msCertOK
= get
<FixedText
>("certok")->GetText();
383 msCertNotValidated
= get
<FixedText
>("certnotok")->GetText();
384 maCertImage
= get
<FixedImage
>("imgok")->GetImage();
385 maCertNotValidatedImage
= get
<FixedImage
>("imgnotok")->GetImage();
387 Size
aControlSize(LogicToPixel(Size(251, 45), MapUnit::MapAppFont
));
388 mpCertPathLB
->set_width_request(aControlSize
.Width());
389 mpCertPathLB
->set_height_request(aControlSize
.Height());
390 mpCertStatusML
->set_width_request(aControlSize
.Width());
391 mpCertStatusML
->set_height_request(aControlSize
.Height());
393 mpCertPathLB
->SetNodeDefaultImages();
394 mpCertPathLB
->SetSublistOpenWithLeftRight();
395 mpCertPathLB
->SetSelectHdl( LINK( this, CertificateViewerCertPathTP
, CertSelectHdl
) );
396 mpViewCertPB
->SetClickHdl( LINK( this, CertificateViewerCertPathTP
, ViewCertHdl
) );
399 CertificateViewerCertPathTP::~CertificateViewerCertPathTP()
404 void CertificateViewerCertPathTP::dispose()
407 mpCertPathLB
.clear();
408 mpViewCertPB
.clear();
409 mpCertStatusML
.clear();
411 CertificateViewerTP::dispose();
414 void CertificateViewerCertPathTP::ActivatePage()
416 if ( !mbFirstActivateDone
)
418 mbFirstActivateDone
= true;
419 Sequence
< Reference
< security::XCertificate
> > aCertPath
=
420 mpParent
->mxSecurityEnvironment
->buildCertificatePath( mpParent
->mxCert
);
421 const Reference
< security::XCertificate
>* pCertPath
= aCertPath
.getConstArray();
423 sal_Int32 i
, nCnt
= aCertPath
.getLength();
424 SvTreeListEntry
* pParent
= nullptr;
425 for (i
= nCnt
-1; i
>= 0; i
--)
427 const Reference
< security::XCertificate
> rCert
= pCertPath
[ i
];
428 OUString sName
= XmlSec::GetContentPart( rCert
->getSubjectName() );
429 //Verify the certificate
430 sal_Int32 certStatus
= mpDlg
->mxSecurityEnvironment
->verifyCertificate(rCert
,
431 Sequence
<Reference
<css::security::XCertificate
> >());
432 bool bCertValid
= certStatus
== css::security::CertificateValidity::VALID
;
433 pParent
= InsertCert( pParent
, sName
, rCert
, bCertValid
);
437 mpCertPathLB
->Select( pParent
);
438 mpViewCertPB
->Disable(); // Own certificate selected
442 mpCertPathLB
->Expand( pParent
);
443 pParent
= mpCertPathLB
->GetParent( pParent
);
446 CertSelectHdl( nullptr );
450 IMPL_LINK_NOARG(CertificateViewerCertPathTP
, ViewCertHdl
, Button
*, void)
452 SvTreeListEntry
* pEntry
= mpCertPathLB
->FirstSelected();
455 ScopedVclPtrInstance
< CertificateViewer
> aViewer(
456 this, mpDlg
->mxSecurityEnvironment
,
457 static_cast<CertPath_UserData
*>(pEntry
->GetUserData())->mxCert
,
463 IMPL_LINK_NOARG(CertificateViewerCertPathTP
, CertSelectHdl
, SvTreeListBox
*, void)
466 SvTreeListEntry
* pEntry
= mpCertPathLB
->FirstSelected();
469 CertPath_UserData
* pData
= static_cast<CertPath_UserData
*>(pEntry
->GetUserData());
471 sStatus
= pData
->mbValid
? msCertOK
: msCertNotValidated
;
474 mpCertStatusML
->SetText( sStatus
);
475 mpViewCertPB
->Enable( pEntry
&& ( pEntry
!= mpCertPathLB
->Last() ) );
478 void CertificateViewerCertPathTP::Clear()
480 mpCertStatusML
->SetText( OUString() );
482 SvTreeListEntry
* pEntry
= mpCertPathLB
->GetEntry( i
);
485 delete static_cast<CertPath_UserData
*>(pEntry
->GetUserData());
487 pEntry
= mpCertPathLB
->GetEntry( i
);
490 mpCertPathLB
->Clear();
493 SvTreeListEntry
* CertificateViewerCertPathTP::InsertCert(
494 SvTreeListEntry
* _pParent
, const OUString
& _rName
, const css::uno::Reference
< css::security::XCertificate
>& rxCert
,
497 Image aImage
= bValid
? maCertImage
: maCertNotValidatedImage
;
498 SvTreeListEntry
* pEntry
= mpCertPathLB
->InsertEntry( _rName
, aImage
, aImage
, _pParent
);
499 pEntry
->SetUserData( static_cast<void*>(new CertPath_UserData( rxCert
, bValid
)) );
504 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */