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 /* HACK: disable some warnings for MS-C */
36 #pragma warning (disable : 4355) // 4355: this used in initializer-list
39 using namespace ::com::sun::star
;
40 using namespace ::com::sun::star::uno
;
44 void ShrinkToFit( FixedImage
& _rImg
)
46 _rImg
.SetSizePixel( _rImg
.GetImage().GetSizePixel() );
50 CertificateViewer::CertificateViewer(
52 const css::uno::Reference
< css::xml::crypto::XSecurityEnvironment
>& _rxSecurityEnvironment
,
53 const css::uno::Reference
< css::security::XCertificate
>& _rXCert
, bool bCheckForPrivateKey
)
54 :TabDialog ( _pParent
, XMLSEC_RES( RID_XMLSECDLG_CERTVIEWER
) )
55 ,maTabCtrl ( this, XMLSEC_RES( 1 ) )
56 ,maOkBtn ( this, XMLSEC_RES( BTN_OK
) )
57 ,maHelpBtn ( this, XMLSEC_RES( BTN_HELP
) )
61 mbCheckForPrivateKey
= bCheckForPrivateKey
;
63 mxSecurityEnvironment
= _rxSecurityEnvironment
;
66 maTabCtrl
.SetTabPage( RID_XMLSECTP_GENERAL
, new CertificateViewerGeneralTP( &maTabCtrl
, this ) );
67 maTabCtrl
.SetTabPage( RID_XMLSECTP_DETAILS
, new CertificateViewerDetailsTP( &maTabCtrl
, this ) );
68 maTabCtrl
.SetTabPage( RID_XMLSECTP_CERTPATH
, new CertificateViewerCertPathTP( &maTabCtrl
, this ) );
69 maTabCtrl
.SetCurPageId( RID_XMLSECTP_GENERAL
);
72 CertificateViewer::~CertificateViewer()
74 delete maTabCtrl
.GetTabPage( RID_XMLSECTP_CERTPATH
);
75 delete maTabCtrl
.GetTabPage( RID_XMLSECTP_DETAILS
);
76 delete maTabCtrl
.GetTabPage( RID_XMLSECTP_GENERAL
);
79 CertificateViewerTP::CertificateViewerTP( Window
* _pParent
, const ResId
& _rResId
, CertificateViewer
* _pDlg
)
80 :TabPage ( _pParent
, _rResId
)
86 CertificateViewerGeneralTP::CertificateViewerGeneralTP( Window
* _pParent
, CertificateViewer
* _pDlg
)
87 :CertificateViewerTP ( _pParent
, XMLSEC_RES( RID_XMLSECTP_GENERAL
), _pDlg
)
88 ,maFrameWin ( this, XMLSEC_RES( WIN_FRAME
) )
89 ,maCertImg ( this, XMLSEC_RES( IMG_CERT
) )
90 ,maCertInfoFI ( this, XMLSEC_RES( FI_CERTINFO
) )
91 ,maSep1FL ( this, XMLSEC_RES( FL_SEP1
) )
92 ,maHintNotTrustedFI ( this, XMLSEC_RES( FI_HINTNOTTRUST
) )
93 ,maSep2FL ( this, XMLSEC_RES( FL_SEP2
) )
94 ,maIssuedToLabelFI ( this, XMLSEC_RES( FI_ISSTOLABEL
) )
95 ,maIssuedToFI ( this, XMLSEC_RES( FI_ISSTO
) )
96 ,maIssuedByLabelFI ( this, XMLSEC_RES( FI_ISSBYLABEL
) )
97 ,maIssuedByFI ( this, XMLSEC_RES( FI_ISSBY
) )
98 ,maValidDateFI ( this, XMLSEC_RES( FI_VALIDDATE
) )
99 ,maKeyImg ( this, XMLSEC_RES( IMG_KEY
) )
100 ,maHintCorrespPrivKeyFI ( this, XMLSEC_RES( FI_CORRPRIVKEY
) )
102 //Verify the certificate
103 sal_Int32 certStatus
= mpDlg
->mxSecurityEnvironment
->verifyCertificate(mpDlg
->mxCert
,
104 Sequence
<Reference
<css::security::XCertificate
> >());
106 bool bCertValid
= certStatus
== css::security::CertificateValidity::VALID
? true : false;
111 Image( XMLSEC_RES( IMG_STATE_NOT_VALIDATED
) ) );
112 maHintNotTrustedFI
.SetText( XMLSEC_RES( STR_CERTIFICATE_NOT_VALIDATED
) );
117 Wallpaper
aBack( GetSettings().GetStyleSettings().GetWindowColor() );
118 maFrameWin
.SetBackground( aBack
);
119 maCertImg
.SetBackground( aBack
);
120 maCertInfoFI
.SetBackground( aBack
);
121 maSep1FL
.SetBackground( aBack
);
122 maHintNotTrustedFI
.SetBackground( aBack
);
123 maSep2FL
.SetBackground( aBack
);
124 maIssuedToLabelFI
.SetBackground( aBack
);
125 maIssuedToFI
.SetBackground( aBack
);
126 maIssuedByLabelFI
.SetBackground( aBack
);
127 maIssuedByFI
.SetBackground( aBack
);
128 maValidDateFI
.SetBackground( aBack
);
129 maKeyImg
.SetBackground( aBack
);
130 maHintCorrespPrivKeyFI
.SetBackground( aBack
);
133 Font
aFnt( maCertInfoFI
.GetFont() );
134 aFnt
.SetWeight( WEIGHT_BOLD
);
135 maCertInfoFI
.SetFont( aFnt
);
136 maHintNotTrustedFI
.SetFont( aFnt
);
137 maIssuedToLabelFI
.SetFont( aFnt
);
138 maIssuedByLabelFI
.SetFont( aFnt
);
139 maValidDateFI
.SetFont( aFnt
);
142 css::uno::Reference
< css::security::XCertificate
> xCert
= mpDlg
->mxCert
;
144 maIssuedToFI
.SetText( XmlSec::GetContentPart( xCert
->getSubjectName() ) );
145 maIssuedByFI
.SetText( XmlSec::GetContentPart( xCert
->getIssuerName() ) );
147 // dynamic length because of the different languages
148 long nWidth1
= maIssuedToLabelFI
.GetTextWidth( maIssuedToLabelFI
.GetText() );
149 long nWidth2
= maIssuedByLabelFI
.GetTextWidth( maIssuedByLabelFI
.GetText() );
150 long nNewWidth
= std::max( nWidth1
, nWidth2
) + 5;
151 Size aNewSize
= maIssuedToLabelFI
.GetSizePixel();
152 aNewSize
.Width() = nNewWidth
;
153 maIssuedToLabelFI
.SetSizePixel( aNewSize
);
154 maIssuedByLabelFI
.SetSizePixel( aNewSize
);
155 long nNewX
= maIssuedToLabelFI
.GetPosPixel().X() + nNewWidth
+ 1;
156 Point aNewPos
= maIssuedToFI
.GetPosPixel();
158 maIssuedToFI
.SetPosPixel( aNewPos
);
159 aNewPos
= maIssuedByFI
.GetPosPixel();
161 maIssuedByFI
.SetPosPixel( aNewPos
);
162 nNewWidth
= maValidDateFI
.GetSizePixel().Width() - nNewX
;
163 aNewSize
= maIssuedToFI
.GetSizePixel();
164 aNewSize
.Width() = nNewWidth
;
165 maIssuedToFI
.SetSizePixel( aNewSize
);
166 maIssuedByFI
.SetSizePixel( aNewSize
);
168 DateTime
aDateTimeStart( DateTime::EMPTY
);
169 DateTime
aDateTimeEnd( DateTime::EMPTY
);
170 utl::typeConvert( xCert
->getNotValidBefore(), aDateTimeStart
);
171 utl::typeConvert( xCert
->getNotValidAfter(), aDateTimeEnd
);
172 OUString sText
= maValidDateFI
.GetText();
173 sText
= sText
.replaceFirst( "%SDATE%",
174 GetSettings().GetUILocaleDataWrapper().getDate( aDateTimeStart
.GetDate() ) );
175 sText
= sText
.replaceFirst( "%EDATE%",
176 GetSettings().GetUILocaleDataWrapper().getDate( aDateTimeEnd
.GetDate() ) );
177 maValidDateFI
.SetText( sText
);
179 // adjust position of fixed text depending on image sizes
180 ShrinkToFit( maCertImg
);
181 ShrinkToFit( maKeyImg
);
182 XmlSec::AlignAfterImage( maCertImg
, maCertInfoFI
, 12 );
183 XmlSec::AlignAfterImage( maKeyImg
, maHintCorrespPrivKeyFI
, 12 );
185 // Check if we have the private key...
186 sal_Bool bHasPrivateKey
= sal_False
;
187 // #i41270# Check only if we have that certificate in our security environment
188 if ( _pDlg
->mbCheckForPrivateKey
)
190 long nCertificateCharacters
= _pDlg
->mxSecurityEnvironment
->getCertificateCharacters( xCert
);
191 bHasPrivateKey
= ( nCertificateCharacters
& security::CertificateCharacters::HAS_PRIVATE_KEY
) ? sal_True
: sal_False
;
193 if ( !bHasPrivateKey
)
196 maHintCorrespPrivKeyFI
.Hide();
200 void CertificateViewerGeneralTP::ActivatePage()
206 struct Details_UserDatat
209 bool mbFixedWidthFont
;
211 inline Details_UserDatat( const OUString
& _rTxt
, bool _bFixedWidthFont
);
214 inline Details_UserDatat::Details_UserDatat( const OUString
& _rTxt
, bool _bFixedWidthFont
)
216 ,mbFixedWidthFont ( _bFixedWidthFont
)
221 void CertificateViewerDetailsTP::Clear( void )
223 maElementML
.SetText( OUString() );
225 SvTreeListEntry
* pEntry
= maElementsLB
.GetEntry( i
);
228 delete ( Details_UserDatat
* ) pEntry
->GetUserData();
230 pEntry
= maElementsLB
.GetEntry( i
);
233 maElementsLB
.Clear();
236 void CertificateViewerDetailsTP::InsertElement( const OUString
& _rField
, const OUString
& _rValue
,
237 const OUString
& _rDetails
, bool _bFixedWidthFont
)
239 SvTreeListEntry
* pEntry
= maElementsLB
.InsertEntry( _rField
);
240 maElementsLB
.SetEntryText( _rValue
, pEntry
, 1 );
241 pEntry
->SetUserData( ( void* ) new Details_UserDatat( _rDetails
, _bFixedWidthFont
) );
244 CertificateViewerDetailsTP::CertificateViewerDetailsTP( Window
* _pParent
, CertificateViewer
* _pDlg
)
245 :CertificateViewerTP ( _pParent
, XMLSEC_RES( RID_XMLSECTP_DETAILS
), _pDlg
)
246 ,m_aElementsLBContainer(this, XMLSEC_RES(LB_ELEMENTS
))
247 ,maElementsLB(m_aElementsLBContainer
)
248 ,maElementML ( this, XMLSEC_RES( ML_ELEMENT
) )
249 ,maStdFont ( maElementML
.GetControlFont() )
250 ,maFixedWidthFont ( OutputDevice::GetDefaultFont( DEFAULTFONT_UI_FIXED
, LANGUAGE_DONTKNOW
, DEFAULTFONT_FLAGS_ONLYONE
, this ) )
252 WinBits nStyle
= maElementsLB
.GetStyle();
253 nStyle
&= ~WB_HSCROLL
;
254 maElementsLB
.SetStyle( nStyle
);
256 maFixedWidthFont
.SetHeight( maStdFont
.GetHeight() );
258 static long nTabs
[] = { 2, 0, 30*CS_LB_WIDTH
/100 };
259 maElementsLB
.SetTabs( &nTabs
[ 0 ] );
260 maElementsLB
.InsertHeaderEntry( XMLSEC_RES( STR_HEADERBAR
) );
263 Reference
< security::XCertificate
> xCert
= mpDlg
->mxCert
;
264 sal_uInt16 nLineBreak
= 16;
265 const char* pHexSep
= " ";
268 // Certificate Versions are reported wrong (#i35107#) - 0 == "V1", 1 == "V2", ..., n = "V(n+1)"
269 aLBEntry
= OUString( "V" );
270 aLBEntry
+= OUString::valueOf( sal_Int32( xCert
->getVersion() + 1 ) );
271 InsertElement( XMLSEC_RES( STR_VERSION
), aLBEntry
, aLBEntry
);
272 Sequence
< sal_Int8
> aSeq
= xCert
->getSerialNumber();
273 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
274 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
275 InsertElement( XMLSEC_RES( STR_SERIALNUM
), aLBEntry
, aDetails
, true );
277 std::pair
< OUString
, OUString
> pairIssuer
=
278 XmlSec::GetDNForCertDetailsView(xCert
->getIssuerName());
279 aLBEntry
= pairIssuer
.first
;
280 aDetails
= pairIssuer
.second
;
281 InsertElement( XMLSEC_RES( STR_ISSUER
), aLBEntry
, aDetails
);
283 DateTime
aDateTime( DateTime::EMPTY
);
284 utl::typeConvert( xCert
->getNotValidBefore(), aDateTime
);
285 aLBEntry
= GetSettings().GetUILocaleDataWrapper().getDate( aDateTime
.GetDate() );
286 aLBEntry
+= OUString( " " );
287 aLBEntry
+= GetSettings().GetUILocaleDataWrapper().getTime( aDateTime
.GetTime() );
288 InsertElement( XMLSEC_RES( STR_VALIDFROM
), aLBEntry
, aLBEntry
);
289 utl::typeConvert( xCert
->getNotValidAfter(), aDateTime
);
290 aLBEntry
= GetSettings().GetUILocaleDataWrapper().getDate( aDateTime
.GetDate() );
291 aLBEntry
+= OUString( " " );
292 aLBEntry
+= GetSettings().GetUILocaleDataWrapper().getTime( aDateTime
.GetTime() );
293 InsertElement( XMLSEC_RES( STR_VALIDTO
), aLBEntry
, aLBEntry
);
295 std::pair
< OUString
, OUString
> pairSubject
=
296 XmlSec::GetDNForCertDetailsView(xCert
->getSubjectName());
297 aLBEntry
= pairSubject
.first
;
298 aDetails
= pairSubject
.second
;
299 InsertElement( XMLSEC_RES( STR_SUBJECT
), aLBEntry
, aDetails
);
301 aLBEntry
= aDetails
= xCert
->getSubjectPublicKeyAlgorithm();
302 InsertElement( XMLSEC_RES( STR_SUBJECT_PUBKEY_ALGO
), aLBEntry
, aDetails
);
303 aSeq
= xCert
->getSubjectPublicKeyValue();
304 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
305 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
306 InsertElement( XMLSEC_RES( STR_SUBJECT_PUBKEY_VAL
), aLBEntry
, aDetails
, true );
308 aLBEntry
= aDetails
= xCert
->getSignatureAlgorithm();
309 InsertElement( XMLSEC_RES( STR_SIGNATURE_ALGO
), aLBEntry
, aDetails
);
311 aSeq
= xCert
->getSHA1Thumbprint();
312 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
313 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
314 InsertElement( XMLSEC_RES( STR_THUMBPRINT_SHA1
), aLBEntry
, aDetails
, true );
316 aSeq
= xCert
->getMD5Thumbprint();
317 aLBEntry
= XmlSec::GetHexString( aSeq
, pHexSep
);
318 aDetails
= XmlSec::GetHexString( aSeq
, pHexSep
, nLineBreak
);
319 InsertElement( XMLSEC_RES( STR_THUMBPRINT_MD5
), aLBEntry
, aDetails
, true );
323 maElementsLB
.SetSelectHdl( LINK( this, CertificateViewerDetailsTP
, ElementSelectHdl
) );
326 CertificateViewerDetailsTP::~CertificateViewerDetailsTP()
331 void CertificateViewerDetailsTP::ActivatePage()
335 IMPL_LINK_NOARG(CertificateViewerDetailsTP
, ElementSelectHdl
)
337 SvTreeListEntry
* pEntry
= maElementsLB
.FirstSelected();
338 OUString aElementText
;
339 bool bFixedWidthFont
;
342 const Details_UserDatat
* p
= ( Details_UserDatat
* ) pEntry
->GetUserData();
343 aElementText
= p
->maTxt
;
344 bFixedWidthFont
= p
->mbFixedWidthFont
;
347 bFixedWidthFont
= false;
349 maElementML
.SetFont( bFixedWidthFont
? maFixedWidthFont
: maStdFont
);
350 maElementML
.SetControlFont( bFixedWidthFont
? maFixedWidthFont
: maStdFont
);
351 maElementML
.SetText( aElementText
);
356 struct CertPath_UserData
358 css::uno::Reference
< css::security::XCertificate
> mxCert
;
362 CertPath_UserData( css::uno::Reference
< css::security::XCertificate
> xCert
, bool bValid
):
370 CertificateViewerCertPathTP::CertificateViewerCertPathTP( Window
* _pParent
, CertificateViewer
* _pDlg
)
371 :CertificateViewerTP ( _pParent
, XMLSEC_RES( RID_XMLSECTP_CERTPATH
), _pDlg
)
372 ,maCertPathFT ( this, XMLSEC_RES( FT_CERTPATH
) )
373 ,maCertPathLB ( this, XMLSEC_RES( LB_SIGNATURES
) )
374 ,maViewCertPB ( this, XMLSEC_RES( BTN_VIEWCERT
) )
375 ,maCertStatusFT ( this, XMLSEC_RES( FT_CERTSTATUS
) )
376 ,maCertStatusML ( this, XMLSEC_RES( ML_CERTSTATUS
) )
378 ,mbFirstActivateDone ( false )
379 ,maCertImage ( XMLSEC_RES( IMG_CERT_SMALL
) )
380 ,maCertNotValidatedImage( XMLSEC_RES( IMG_CERT_NOTVALIDATED_SMALL
) )
381 ,msCertOK ( XMLSEC_RES( STR_PATH_CERT_OK
) )
382 ,msCertNotValidated ( XMLSEC_RES( STR_PATH_CERT_NOT_VALIDATED
) )
387 maCertPathLB
.SetNodeDefaultImages();
388 maCertPathLB
.SetSublistOpenWithLeftRight();
389 maCertPathLB
.SetSelectHdl( LINK( this, CertificateViewerCertPathTP
, CertSelectHdl
) );
390 maViewCertPB
.SetClickHdl( LINK( this, CertificateViewerCertPathTP
, ViewCertHdl
) );
392 // check if buttontext is to wide
393 const long nOffset
= 10;
394 OUString sText
= maViewCertPB
.GetText();
395 long nTxtW
= maViewCertPB
.GetTextWidth( sText
);
396 if ( sText
.indexOf( '~' ) == -1 )
398 long nBtnW
= maViewCertPB
.GetSizePixel().Width();
401 // broaden the button
402 long nDelta
= nTxtW
- nBtnW
;
403 Size aNewSize
= maViewCertPB
.GetSizePixel();
404 aNewSize
.Width() += nDelta
;
405 maViewCertPB
.SetSizePixel( aNewSize
);
406 // and give it a new position
407 Point aNewPos
= maViewCertPB
.GetPosPixel();
408 aNewPos
.X() -= nDelta
;
409 maViewCertPB
.SetPosPixel( aNewPos
);
413 CertificateViewerCertPathTP::~CertificateViewerCertPathTP()
418 void CertificateViewerCertPathTP::ActivatePage()
420 if ( !mbFirstActivateDone
)
422 mbFirstActivateDone
= true;
423 Sequence
< Reference
< security::XCertificate
> > aCertPath
=
424 mpParent
->mxSecurityEnvironment
->buildCertificatePath( mpParent
->mxCert
);
425 const Reference
< security::XCertificate
>* pCertPath
= aCertPath
.getConstArray();
427 sal_Int32 i
, nCnt
= aCertPath
.getLength();
428 SvTreeListEntry
* pParent
= NULL
;
431 const Reference
< security::XCertificate
> rCert
= pCertPath
[ --i
];
432 OUString sName
= XmlSec::GetContentPart( rCert
->getSubjectName() );
433 //Verify the certificate
434 sal_Int32 certStatus
= mpDlg
->mxSecurityEnvironment
->verifyCertificate(rCert
,
435 Sequence
<Reference
<css::security::XCertificate
> >());
436 bool bCertValid
= certStatus
== css::security::CertificateValidity::VALID
? true : false;
437 pParent
= InsertCert( pParent
, sName
, rCert
, bCertValid
);
440 maCertPathLB
.Select( pParent
);
441 maViewCertPB
.Disable(); // Own certificate selected
445 maCertPathLB
.Expand( pParent
);
446 pParent
= maCertPathLB
.GetParent( pParent
);
449 CertSelectHdl( NULL
);
453 IMPL_LINK_NOARG(CertificateViewerCertPathTP
, ViewCertHdl
)
455 SvTreeListEntry
* pEntry
= maCertPathLB
.FirstSelected();
458 CertificateViewer
aViewer( this, mpDlg
->mxSecurityEnvironment
, ((CertPath_UserData
*)pEntry
->GetUserData())->mxCert
, false );
465 IMPL_LINK_NOARG(CertificateViewerCertPathTP
, CertSelectHdl
)
468 SvTreeListEntry
* pEntry
= maCertPathLB
.FirstSelected();
471 CertPath_UserData
* pData
= (CertPath_UserData
*) pEntry
->GetUserData();
473 sStatus
= pData
->mbValid
? msCertOK
: msCertNotValidated
;
476 maCertStatusML
.SetText( sStatus
);
477 maViewCertPB
.Enable( pEntry
&& ( pEntry
!= maCertPathLB
.Last() ) );
481 void CertificateViewerCertPathTP::Clear( void )
483 maCertStatusML
.SetText( OUString() );
485 SvTreeListEntry
* pEntry
= maCertPathLB
.GetEntry( i
);
488 delete ( CertPath_UserData
* ) pEntry
->GetUserData();
490 pEntry
= maCertPathLB
.GetEntry( i
);
493 maCertPathLB
.Clear();
496 SvTreeListEntry
* CertificateViewerCertPathTP::InsertCert(
497 SvTreeListEntry
* _pParent
, const OUString
& _rName
, css::uno::Reference
< css::security::XCertificate
> rxCert
,
500 Image aImage
= bValid
? maCertImage
: maCertNotValidatedImage
;
501 SvTreeListEntry
* pEntry
= maCertPathLB
.InsertEntry( _rName
, aImage
, aImage
, _pParent
);
502 pEntry
->SetUserData( ( void* ) new CertPath_UserData( rxCert
, bValid
) );
507 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */