Bump version to 5.0-14
[LibreOffice.git] / xmlsecurity / source / dialogs / certificateviewer.cxx
blob3ed07b59a80c6c1035c71a15aa21222b5adf5c83
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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;
50 mxCert = _rXCert;
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()
64 disposeOnce();
67 void CertificateViewer::dispose()
69 mpTabCtrl->GetTabPage(mnGeneralId)->disposeOnce();
70 mpTabCtrl->GetTabPage(mnDetailsId)->disposeOnce();
71 mpTabCtrl->GetTabPage(mnPathId)->disposeOnce();
72 mpTabCtrl.clear();
73 TabDialog::dispose();
76 CertificateViewerTP::CertificateViewerTP( vcl::Window* _pParent, const OString& rID,
77 const OUString& rUIXMLDescription, CertificateViewer* _pDlg )
78 : TabPage(_pParent, rID, rUIXMLDescription)
79 , mpDlg(_pDlg)
83 CertificateViewerTP::~CertificateViewerTP()
85 disposeOnce();
88 void CertificateViewerTP::dispose()
90 mpDlg.clear();
91 TabPage::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;
113 if ( !bCertValid )
115 m_pCertImg->SetImage(
116 Image( XMLSEC_RES( IMG_STATE_NOT_VALIDATED ) ) );
117 m_pHintNotTrustedFI->SetText( XMLSEC_RES( STR_CERTIFICATE_NOT_VALIDATED ) );
120 // insert data
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 )
147 m_pKeyImg->Hide();
148 m_pHintCorrespPrivKeyFI->Hide();
152 CertificateViewerGeneralTP::~CertificateViewerGeneralTP()
154 disposeOnce();
157 void CertificateViewerGeneralTP::dispose()
159 m_pCertImg.clear();
160 m_pHintNotTrustedFI.clear();
161 m_pIssuedToFI.clear();
162 m_pIssuedByFI.clear();
163 m_pValidFromDateFI.clear();
164 m_pValidToDateFI.clear();
165 m_pKeyImg.clear();
166 m_pHintCorrespPrivKeyFI.clear();
167 CertificateViewerTP::dispose();
170 void CertificateViewerGeneralTP::ActivatePage()
176 struct Details_UserDatat
178 OUString maTxt;
179 bool mbFixedWidthFont;
181 inline Details_UserDatat( const OUString& _rTxt, bool _bFixedWidthFont );
184 inline Details_UserDatat::Details_UserDatat( const OUString& _rTxt, bool _bFixedWidthFont )
185 :maTxt ( _rTxt )
186 ,mbFixedWidthFont ( _bFixedWidthFont )
191 void CertificateViewerDetailsTP::Clear()
193 m_pValueDetails->SetText( OUString() );
194 sal_uLong i = 0;
195 SvTreeListEntry* pEntry = m_pElementsLB->GetEntry( i );
196 while( pEntry )
198 delete static_cast<Details_UserDatat*>(pEntry->GetUserData());
199 ++i;
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 ) );
233 // fill list box
234 Reference< security::XCertificate > xCert = mpDlg->mxCert;
235 sal_uInt16 nLineBreak = 16;
236 const char* pHexSep = " ";
237 OUString aLBEntry;
238 OUString aDetails;
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() );
256 aLBEntry += " ";
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() );
261 aLBEntry += " ";
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()
296 disposeOnce();
299 void CertificateViewerDetailsTP::dispose()
301 Clear();
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;
317 if( pEntry )
319 const Details_UserDatat* p = static_cast<Details_UserDatat*>(pEntry->GetUserData());
320 aElementText = p->maTxt;
321 bFixedWidthFont = p->mbFixedWidthFont;
323 else
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 );
330 return 0;
333 struct CertPath_UserData
335 css::uno::Reference< css::security::XCertificate > mxCert;
336 OUString maStatus;
337 bool mbValid;
339 CertPath_UserData( css::uno::Reference< css::security::XCertificate > xCert, bool bValid):
340 mxCert(xCert),
341 mbValid(bValid)
347 CertificateViewerCertPathTP::CertificateViewerCertPathTP( vcl::Window* _pParent, CertificateViewer* _pDlg )
348 : CertificateViewerTP(_pParent, "CertPage", "xmlsec/ui/certpage.ui", _pDlg)
349 , mpParent(_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()
375 disposeOnce();
378 void CertificateViewerCertPathTP::dispose()
380 Clear();
381 mpCertPathLB.clear();
382 mpViewCertPB.clear();
383 mpCertStatusML.clear();
384 mpParent.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;
399 for( i = nCnt; i; )
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
413 while( pParent )
415 mpCertPathLB->Expand( pParent );
416 pParent = mpCertPathLB->GetParent( pParent );
419 CertSelectHdl( NULL );
423 IMPL_LINK_NOARG(CertificateViewerCertPathTP, ViewCertHdl)
425 SvTreeListEntry* pEntry = mpCertPathLB->FirstSelected();
426 if( pEntry )
428 ScopedVclPtrInstance< CertificateViewer > aViewer(
429 this, mpDlg->mxSecurityEnvironment,
430 static_cast<CertPath_UserData*>(pEntry->GetUserData())->mxCert,
431 false );
432 aViewer->Execute();
435 return 0;
438 IMPL_LINK_NOARG(CertificateViewerCertPathTP, CertSelectHdl)
440 OUString sStatus;
441 SvTreeListEntry* pEntry = mpCertPathLB->FirstSelected();
442 if( pEntry )
444 CertPath_UserData* pData = static_cast<CertPath_UserData*>(pEntry->GetUserData());
445 if ( pData )
446 sStatus = pData->mbValid ? msCertOK : msCertNotValidated;
449 mpCertStatusML->SetText( sStatus );
450 mpViewCertPB->Enable( pEntry && ( pEntry != mpCertPathLB->Last() ) );
451 return 0;
454 void CertificateViewerCertPathTP::Clear()
456 mpCertStatusML->SetText( OUString() );
457 sal_uLong i = 0;
458 SvTreeListEntry* pEntry = mpCertPathLB->GetEntry( i );
459 while( pEntry )
461 delete static_cast<CertPath_UserData*>(pEntry->GetUserData());
462 ++i;
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,
471 bool bValid)
473 Image aImage = bValid ? maCertImage : maCertNotValidatedImage;
474 SvTreeListEntry* pEntry = mpCertPathLB->InsertEntry( _rName, aImage, aImage, _pParent );
475 pEntry->SetUserData( ( void* ) new CertPath_UserData( rxCert, bValid ) );
477 return pEntry;
480 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */