Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / xmlsecurity / source / dialogs / certificateviewer.cxx
blobcb7ce254dd7e80c512e71a44e4b86e4fcc89c722
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>
31 #include <strings.hrc>
32 #include <resourcemanager.hxx>
33 #include <comphelper/xmlsechelper.hxx>
34 #include <tools/datetime.hxx>
35 #include <bitmaps.hlst>
37 #include <vcl/settings.hxx>
38 #include <vcl/svapp.hxx>
40 using namespace comphelper;
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::uno;
44 CertificateViewer::CertificateViewer(weld::Window* _pParent,
45 const css::uno::Reference< css::xml::crypto::XSecurityEnvironment >& _rxSecurityEnvironment,
46 const css::uno::Reference< css::security::XCertificate >& _rXCert, bool bCheckForPrivateKey,
47 CertificateChooser* pParentChooser)
48 : GenericDialogController(_pParent, "xmlsec/ui/viewcertdialog.ui", "ViewCertDialog")
49 , mbCheckForPrivateKey(bCheckForPrivateKey)
50 , mpParentChooser(pParentChooser)
51 , mxTabCtrl(m_xBuilder->weld_notebook("tabcontrol"))
53 mxTabCtrl->connect_enter_page(LINK(this, CertificateViewer, ActivatePageHdl));
55 mxSecurityEnvironment = _rxSecurityEnvironment;
56 mxCert = _rXCert;
58 mxGeneralPage.reset(new CertificateViewerGeneralTP(mxTabCtrl->get_page("general"), this));
59 mxDetailsPage.reset(new CertificateViewerDetailsTP(mxTabCtrl->get_page("details"), this));
60 if (!mxSecurityEnvironment->buildCertificatePath(mxCert).hasElements())
61 mxTabCtrl->remove_page("path");
62 else
63 mxPathId.reset(new CertificateViewerCertPathTP(mxTabCtrl->get_page("path"), this));
64 mxTabCtrl->set_current_page("general");
67 IMPL_LINK(CertificateViewer, ActivatePageHdl, const OString&, rPage, void)
69 if (rPage == "path")
70 mxPathId->ActivatePage();
73 CertificateViewerTP::CertificateViewerTP(weld::Container* pParent, const OUString& rUIXMLDescription,
74 const OString& rID, CertificateViewer* pDlg)
75 : mxBuilder(Application::CreateBuilder(pParent, rUIXMLDescription))
76 , mxContainer(mxBuilder->weld_container(rID))
77 , mpDlg(pDlg)
81 CertificateViewerGeneralTP::CertificateViewerGeneralTP(weld::Container* pParent, CertificateViewer* pDlg)
82 : CertificateViewerTP(pParent, "xmlsec/ui/certgeneral.ui", "CertGeneral", pDlg)
83 , m_xCertImg(mxBuilder->weld_image("certimage"))
84 , m_xHintNotTrustedFT(mxBuilder->weld_label("hintnotrust"))
85 , m_xIssuedToLabelFT(mxBuilder->weld_label("issued_to"))
86 , m_xIssuedToFT(mxBuilder->weld_label("issued_to_value"))
87 , m_xIssuedByLabelFT(mxBuilder->weld_label("issued_by"))
88 , m_xIssuedByFT(mxBuilder->weld_label("issued_by_value"))
89 , m_xValidFromDateFT(mxBuilder->weld_label("valid_from_value"))
90 , m_xValidToDateFT(mxBuilder->weld_label("valid_to_value"))
91 , m_xKeyImg(mxBuilder->weld_image("keyimage"))
92 , m_xHintCorrespPrivKeyFT(mxBuilder->weld_label("privatekey"))
94 //Verify the certificate
95 sal_Int32 certStatus = mpDlg->mxSecurityEnvironment->verifyCertificate(mpDlg->mxCert,
96 Sequence<Reference<css::security::XCertificate> >());
98 bool bCertValid = certStatus == css::security::CertificateValidity::VALID;
100 if ( !bCertValid )
102 m_xCertImg->set_from_icon_name(BMP_STATE_NOT_VALIDATED);
103 m_xHintNotTrustedFT->set_label(XsResId(STR_CERTIFICATE_NOT_VALIDATED));
106 // insert data
107 css::uno::Reference< css::security::XCertificate > xCert = mpDlg->mxCert;
109 OUString sSubjectName(xmlsec::GetContentPart(xCert->getSubjectName()));
110 if (!sSubjectName.isEmpty())
111 m_xIssuedToFT->set_label(sSubjectName);
112 else
113 m_xIssuedToLabelFT->hide();
114 OUString sIssuerName(xmlsec::GetContentPart(xCert->getIssuerName()));
115 if (!sIssuerName.isEmpty())
116 m_xIssuedByFT->set_label(sIssuerName);
117 else
118 m_xIssuedByLabelFT->hide();
120 DateTime aDateTimeStart( DateTime::EMPTY );
121 DateTime aDateTimeEnd( DateTime::EMPTY );
122 utl::typeConvert( xCert->getNotValidBefore(), aDateTimeStart );
123 utl::typeConvert( xCert->getNotValidAfter(), aDateTimeEnd );
125 OUString sValidFromDate = Application::GetSettings().GetUILocaleDataWrapper().getDate(Date(aDateTimeStart.GetDate()));
126 OUString sValidToDate = Application::GetSettings().GetUILocaleDataWrapper().getDate(Date(aDateTimeEnd.GetDate()));
128 m_xValidFromDateFT->set_label(sValidFromDate);
129 m_xValidToDateFT->set_label(sValidToDate);
131 // Check if we have the private key...
132 bool bHasPrivateKey = false;
133 // #i41270# Check only if we have that certificate in our security environment
134 if (pDlg->mbCheckForPrivateKey)
136 long nCertificateCharacters = pDlg->mxSecurityEnvironment->getCertificateCharacters(xCert);
137 bHasPrivateKey = (nCertificateCharacters & security::CertificateCharacters::HAS_PRIVATE_KEY);
139 if (!bHasPrivateKey)
141 m_xKeyImg->hide();
142 m_xHintCorrespPrivKeyFT->hide();
146 void CertificateViewerDetailsTP::InsertElement(const OUString& rField, const OUString& rValue,
147 const OUString& rDetails, bool bFixedWidthFont)
149 m_aUserData.emplace_back(std::make_unique<Details_UserDatat>(rDetails, bFixedWidthFont));
150 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(m_aUserData.back().get())));
151 m_xElementsLB->append(sId, rField);
152 m_xElementsLB->set_text(m_xElementsLB->n_children() -1, rValue, 1);
155 CertificateViewerDetailsTP::CertificateViewerDetailsTP(weld::Container* pParent, CertificateViewer* pDlg)
156 : CertificateViewerTP(pParent, "xmlsec/ui/certdetails.ui", "CertDetails", pDlg)
157 , m_xElementsLB(mxBuilder->weld_tree_view("tablecontainer"))
158 , m_xValueDetails(mxBuilder->weld_text_view("valuedetails"))
160 const int nWidth = m_xElementsLB->get_approximate_digit_width() * 60;
161 const int nHeight = m_xElementsLB->get_height_rows(8);
162 m_xElementsLB->set_size_request(nWidth, nHeight);
163 m_xValueDetails->set_size_request(nWidth, nHeight);
164 std::vector<int> aWidths;
165 aWidths.push_back(nWidth / 2);
166 m_xElementsLB->set_column_fixed_widths(aWidths);
168 // fill list box
169 Reference< security::XCertificate > xCert = mpDlg->mxCert;
170 sal_uInt16 nLineBreak = 16;
171 const char* const pHexSep = " ";
172 OUString aLBEntry;
173 OUString aDetails;
174 // Certificate Versions are reported wrong (#i35107#) - 0 == "V1", 1 == "V2", ..., n = "V(n+1)"
175 aLBEntry = "V" + OUString::number( xCert->getVersion() + 1 );
176 InsertElement( XsResId( STR_VERSION ), aLBEntry, aLBEntry );
177 Sequence< sal_Int8 > aSeq = xCert->getSerialNumber();
178 aLBEntry = xmlsec::GetHexString( aSeq, pHexSep );
179 aDetails = xmlsec::GetHexString( aSeq, pHexSep, nLineBreak );
180 InsertElement( XsResId( STR_SERIALNUM ), aLBEntry, aDetails, true );
182 std::pair< OUString, OUString> pairIssuer =
183 xmlsec::GetDNForCertDetailsView(xCert->getIssuerName());
184 aLBEntry = pairIssuer.first;
185 aDetails = pairIssuer.second;
186 InsertElement( XsResId( STR_ISSUER ), aLBEntry, aDetails );
188 DateTime aDateTime( DateTime::EMPTY );
189 utl::typeConvert( xCert->getNotValidBefore(), aDateTime );
190 aLBEntry = Application::GetSettings().GetUILocaleDataWrapper().getDate(Date(aDateTime.GetDate())) + " ";
191 aLBEntry += Application::GetSettings().GetUILocaleDataWrapper().getTime(tools::Time(aDateTime.GetTime()));
192 InsertElement( XsResId( STR_VALIDFROM ), aLBEntry, aLBEntry );
193 utl::typeConvert( xCert->getNotValidAfter(), aDateTime );
194 aLBEntry = Application::GetSettings().GetUILocaleDataWrapper().getDate(Date(aDateTime.GetDate()) ) + " ";
195 aLBEntry += Application::GetSettings().GetUILocaleDataWrapper().getTime(tools::Time(aDateTime.GetTime()));
196 InsertElement( XsResId( STR_VALIDTO ), aLBEntry, aLBEntry );
198 std::pair< OUString, OUString > pairSubject =
199 xmlsec::GetDNForCertDetailsView(xCert->getSubjectName());
200 aLBEntry = pairSubject.first;
201 aDetails = pairSubject.second;
202 InsertElement( XsResId( STR_SUBJECT ), aLBEntry, aDetails );
204 aLBEntry = aDetails = xCert->getSubjectPublicKeyAlgorithm();
205 InsertElement( XsResId( STR_SUBJECT_PUBKEY_ALGO ), aLBEntry, aDetails );
206 aSeq = xCert->getSubjectPublicKeyValue();
207 aLBEntry = xmlsec::GetHexString( aSeq, pHexSep );
208 aDetails = xmlsec::GetHexString( aSeq, pHexSep, nLineBreak );
209 InsertElement( XsResId( STR_SUBJECT_PUBKEY_VAL ), aLBEntry, aDetails, true );
211 aLBEntry = aDetails = xCert->getSignatureAlgorithm();
212 InsertElement( XsResId( STR_SIGNATURE_ALGO ), aLBEntry, aDetails );
214 CertificateChooser* pChooser = mpDlg->GetParentChooser();
215 if (pChooser)
217 aLBEntry = CertificateChooser::UsageInClearText( mpDlg->mxCert->getCertificateUsage() );
218 InsertElement( XsResId( STR_USE ), aLBEntry, aLBEntry );
221 aSeq = xCert->getSHA1Thumbprint();
222 aLBEntry = xmlsec::GetHexString( aSeq, pHexSep );
223 aDetails = xmlsec::GetHexString( aSeq, pHexSep, nLineBreak );
224 InsertElement( XsResId( STR_THUMBPRINT_SHA1 ), aLBEntry, aDetails, true );
226 aSeq = xCert->getMD5Thumbprint();
227 aLBEntry = xmlsec::GetHexString( aSeq, pHexSep );
228 aDetails = xmlsec::GetHexString( aSeq, pHexSep, nLineBreak );
229 InsertElement( XsResId( STR_THUMBPRINT_MD5 ), aLBEntry, aDetails, true );
231 m_xElementsLB->connect_changed(LINK(this, CertificateViewerDetailsTP, ElementSelectHdl));
234 IMPL_LINK_NOARG(CertificateViewerDetailsTP, ElementSelectHdl, weld::TreeView&, void)
236 int nEntry = m_xElementsLB->get_selected_index();
237 OUString aElementText;
238 bool bFixedWidthFont;
239 if (nEntry != -1)
241 const Details_UserDatat* p = reinterpret_cast<Details_UserDatat*>(m_xElementsLB->get_id(nEntry).toInt64());
242 aElementText = p->maTxt;
243 bFixedWidthFont = p->mbFixedWidthFont;
245 else
246 bFixedWidthFont = false;
248 m_xValueDetails->set_monospace(bFixedWidthFont);
249 m_xValueDetails->set_text(aElementText);
252 CertificateViewerCertPathTP::CertificateViewerCertPathTP(weld::Container* pParent, CertificateViewer* pDlg)
253 : CertificateViewerTP(pParent, "xmlsec/ui/certpage.ui", "CertPage", pDlg)
254 , mpParent(pDlg)
255 , mbFirstActivateDone(false)
256 , mxCertPathLB(mxBuilder->weld_tree_view("signatures"))
257 , mxViewCertPB(mxBuilder->weld_button("viewcert"))
258 , mxCertStatusML(mxBuilder->weld_text_view("status"))
259 , mxCertOK(mxBuilder->weld_label("certok"))
260 , mxCertNotValidated(mxBuilder->weld_label("certnotok"))
262 const int nWidth = mxCertPathLB->get_approximate_digit_width() * 60;
263 const int nHeight = mxCertPathLB->get_height_rows(6);
264 mxCertPathLB->set_size_request(nWidth, nHeight);
265 mxCertStatusML->set_size_request(nWidth, nHeight);
267 mxCertPathLB->connect_changed( LINK( this, CertificateViewerCertPathTP, CertSelectHdl ) );
268 mxViewCertPB->connect_clicked( LINK( this, CertificateViewerCertPathTP, ViewCertHdl ) );
271 void CertificateViewerCertPathTP::ActivatePage()
273 if ( !mbFirstActivateDone )
275 mbFirstActivateDone = true;
276 Sequence< Reference< security::XCertificate > > aCertPath =
277 mpParent->mxSecurityEnvironment->buildCertificatePath( mpParent->mxCert );
278 const Reference< security::XCertificate >* pCertPath = aCertPath.getConstArray();
280 sal_Int32 i, nCnt = aCertPath.getLength();
281 std::unique_ptr<weld::TreeIter> xParent;
282 for (i = nCnt-1; i >= 0; i--)
284 const Reference< security::XCertificate > rCert = pCertPath[ i ];
285 OUString sName = xmlsec::GetContentPart( rCert->getSubjectName() );
286 //Verify the certificate
287 sal_Int32 certStatus = mpDlg->mxSecurityEnvironment->verifyCertificate(rCert,
288 Sequence<Reference<css::security::XCertificate> >());
289 bool bCertValid = certStatus == css::security::CertificateValidity::VALID;
290 InsertCert(xParent.get(), sName, rCert, bCertValid);
291 if (!xParent)
293 xParent = mxCertPathLB->make_iterator();
294 (void)mxCertPathLB->get_iter_first(*xParent);
296 else
298 mxCertPathLB->iter_children(*xParent);
302 if (xParent)
303 mxCertPathLB->select(*xParent);
304 mxViewCertPB->set_sensitive(false); // Own certificate selected
306 while (xParent)
308 mxCertPathLB->expand_row(*xParent);
309 if (!mxCertPathLB->iter_parent(*xParent))
310 xParent.reset();
313 CertSelectHdl(*mxCertPathLB);
317 IMPL_LINK_NOARG(CertificateViewerCertPathTP, ViewCertHdl, weld::Button&, void)
319 std::unique_ptr<weld::TreeIter> xIter = mxCertPathLB->make_iterator();
320 if (mxCertPathLB->get_selected(xIter.get()))
322 CertPath_UserData* pData = reinterpret_cast<CertPath_UserData*>(mxCertPathLB->get_id(*xIter).toInt64());
323 CertificateViewer aViewer(mpDlg->getDialog(), mpDlg->mxSecurityEnvironment,
324 pData->mxCert, false, nullptr);
325 aViewer.run();
329 IMPL_LINK_NOARG(CertificateViewerCertPathTP, CertSelectHdl, weld::TreeView&, void)
331 OUString sStatus;
333 std::unique_ptr<weld::TreeIter> xIter = mxCertPathLB->make_iterator();
334 bool bEntry = mxCertPathLB->get_selected(xIter.get());
335 if (bEntry)
337 CertPath_UserData* pData = reinterpret_cast<CertPath_UserData*>(mxCertPathLB->get_id(*xIter).toInt64());
338 if (pData)
339 sStatus = pData->mbValid ? mxCertOK->get_label() : mxCertNotValidated->get_label();
342 mxCertStatusML->set_text(sStatus);
344 bool bSensitive = false;
345 if (bEntry)
347 // if has children, so not the last one in the chain
348 if (mxCertPathLB->iter_children(*xIter))
349 bSensitive = true;
351 mxViewCertPB->set_sensitive(bSensitive);
354 void CertificateViewerCertPathTP::InsertCert(const weld::TreeIter* pParent, const OUString& rName,
355 const css::uno::Reference< css::security::XCertificate >& rxCert,
356 bool bValid)
358 OUString sImage = bValid ? OUStringLiteral(BMP_CERT_OK) : OUStringLiteral(BMP_CERT_NOT_OK);
359 maUserData.emplace_back(std::make_unique<CertPath_UserData>(rxCert, bValid));
360 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(maUserData.back().get())));
361 mxCertPathLB->insert(pParent, -1, &rName, &sId, nullptr, nullptr, &sImage, false, nullptr);
364 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */