Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / xmlsecurity / source / dialogs / certificateviewer.cxx
blobe4afcacf4714d38afd7ca8701303cbd3041673c0
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 <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;
52 mxCert = _rXCert;
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);
62 else
63 mpTabCtrl->SetTabPage(mnPathId, VclPtr<CertificateViewerCertPathTP>::Create( mpTabCtrl, this));
64 mpTabCtrl->SetCurPageId(mnGeneralId);
67 CertificateViewer::~CertificateViewer()
69 disposeOnce();
72 void CertificateViewer::dispose()
74 mpTabCtrl->GetTabPage(mnGeneralId)->disposeOnce();
75 mpTabCtrl->GetTabPage(mnDetailsId)->disposeOnce();
76 if (mpTabCtrl->GetTabPage(mnPathId))
77 mpTabCtrl->GetTabPage(mnPathId)->disposeOnce();
78 mpTabCtrl.clear();
79 TabDialog::dispose();
82 CertificateViewerTP::CertificateViewerTP( vcl::Window* _pParent, const OString& rID,
83 const OUString& rUIXMLDescription, CertificateViewer* _pDlg )
84 : TabPage(_pParent, rID, rUIXMLDescription)
85 , mpDlg(_pDlg)
89 CertificateViewerTP::~CertificateViewerTP()
91 disposeOnce();
94 void CertificateViewerTP::dispose()
96 mpDlg.clear();
97 TabPage::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;
121 if ( !bCertValid )
123 m_pCertImg->SetImage(Image(BitmapEx(BMP_STATE_NOT_VALIDATED)));
124 m_pHintNotTrustedFT->SetText( XsResId( STR_CERTIFICATE_NOT_VALIDATED ) );
127 // insert data
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);
133 else
134 m_pIssuedToLabelFT->Hide();
135 OUString sIssuerName(XmlSec::GetContentPart(xCert->getIssuerName()));
136 if (!sIssuerName.isEmpty())
137 m_pIssuedByFT->SetText(sIssuerName);
138 else
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 )
162 m_pKeyImg->Hide();
163 m_pHintCorrespPrivKeyFT->Hide();
167 CertificateViewerGeneralTP::~CertificateViewerGeneralTP()
169 disposeOnce();
172 void CertificateViewerGeneralTP::dispose()
174 m_pCertImg.clear();
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();
182 m_pKeyImg.clear();
183 m_pHintCorrespPrivKeyFT.clear();
184 CertificateViewerTP::dispose();
187 void CertificateViewerGeneralTP::ActivatePage()
193 struct Details_UserDatat
195 OUString maTxt;
196 bool mbFixedWidthFont;
198 inline Details_UserDatat( const OUString& _rTxt, bool _bFixedWidthFont );
201 inline Details_UserDatat::Details_UserDatat( const OUString& _rTxt, bool _bFixedWidthFont )
202 :maTxt ( _rTxt )
203 ,mbFixedWidthFont ( _bFixedWidthFont )
208 void CertificateViewerDetailsTP::Clear()
210 m_pValueDetails->SetText( OUString() );
211 sal_uLong i = 0;
212 SvTreeListEntry* pEntry = m_pElementsLB->GetEntry( i );
213 while( pEntry )
215 delete static_cast<Details_UserDatat*>(pEntry->GetUserData());
216 ++i;
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 ) );
255 // fill list box
256 Reference< security::XCertificate > xCert = mpDlg->mxCert;
257 sal_uInt16 nLineBreak = 16;
258 const char* const pHexSep = " ";
259 OUString aLBEntry;
260 OUString aDetails;
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()) );
278 aLBEntry += " ";
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()) );
283 aLBEntry += " ";
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());
304 if (pChooser)
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()
325 disposeOnce();
328 void CertificateViewerDetailsTP::dispose()
330 Clear();
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;
346 if( pEntry )
348 const Details_UserDatat* p = static_cast<Details_UserDatat*>(pEntry->GetUserData());
349 aElementText = p->maTxt;
350 bFixedWidthFont = p->mbFixedWidthFont;
352 else
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;
363 bool mbValid;
365 CertPath_UserData( css::uno::Reference< css::security::XCertificate > const & xCert, bool bValid):
366 mxCert(xCert),
367 mbValid(bValid)
373 CertificateViewerCertPathTP::CertificateViewerCertPathTP( vcl::Window* _pParent, CertificateViewer* _pDlg )
374 : CertificateViewerTP(_pParent, "CertPage", "xmlsec/ui/certpage.ui", _pDlg)
375 , mpParent(_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()
401 disposeOnce();
404 void CertificateViewerCertPathTP::dispose()
406 Clear();
407 mpCertPathLB.clear();
408 mpViewCertPB.clear();
409 mpCertStatusML.clear();
410 mpParent.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);
436 if (pParent)
437 mpCertPathLB->Select( pParent );
438 mpViewCertPB->Disable(); // Own certificate selected
440 while( pParent )
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();
453 if( pEntry )
455 ScopedVclPtrInstance< CertificateViewer > aViewer(
456 this, mpDlg->mxSecurityEnvironment,
457 static_cast<CertPath_UserData*>(pEntry->GetUserData())->mxCert,
458 false );
459 aViewer->Execute();
463 IMPL_LINK_NOARG(CertificateViewerCertPathTP, CertSelectHdl, SvTreeListBox*, void)
465 OUString sStatus;
466 SvTreeListEntry* pEntry = mpCertPathLB->FirstSelected();
467 if( pEntry )
469 CertPath_UserData* pData = static_cast<CertPath_UserData*>(pEntry->GetUserData());
470 if ( pData )
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() );
481 sal_uLong i = 0;
482 SvTreeListEntry* pEntry = mpCertPathLB->GetEntry( i );
483 while( pEntry )
485 delete static_cast<CertPath_UserData*>(pEntry->GetUserData());
486 ++i;
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,
495 bool bValid)
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 )) );
501 return pEntry;
504 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */