1*06b3ce53SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*06b3ce53SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*06b3ce53SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*06b3ce53SAndrew Rist * distributed with this work for additional information 6*06b3ce53SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*06b3ce53SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*06b3ce53SAndrew Rist * "License"); you may not use this file except in compliance 9*06b3ce53SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*06b3ce53SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*06b3ce53SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*06b3ce53SAndrew Rist * software distributed under the License is distributed on an 15*06b3ce53SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*06b3ce53SAndrew Rist * KIND, either express or implied. See the License for the 17*06b3ce53SAndrew Rist * specific language governing permissions and limitations 18*06b3ce53SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*06b3ce53SAndrew Rist *************************************************************/ 21*06b3ce53SAndrew Rist 22*06b3ce53SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_xmlsecurity.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <xmlsecurity/certificatechooser.hxx> 28cdf0e10cSrcweir #include <xmlsecurity/certificateviewer.hxx> 29cdf0e10cSrcweir #include <xmlsecurity/biginteger.hxx> 30cdf0e10cSrcweir #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> 31cdf0e10cSrcweir #include <comphelper/sequence.hxx> 32cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include <com/sun/star/security/NoPasswordException.hpp> 35cdf0e10cSrcweir #include <com/sun/star/security/CertificateCharacters.hpp> 36cdf0e10cSrcweir #include <com/sun/star/security/SerialNumberAdapter.hpp> 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include <dialogs.hrc> 39cdf0e10cSrcweir #include <resourcemanager.hxx> 40cdf0e10cSrcweir #include <vcl/msgbox.hxx> 41cdf0e10cSrcweir 42cdf0e10cSrcweir /* HACK: disable some warnings for MS-C */ 43cdf0e10cSrcweir #ifdef _MSC_VER 44cdf0e10cSrcweir #pragma warning (disable : 4355) // 4355: this used in initializer-list 45cdf0e10cSrcweir #endif 46cdf0e10cSrcweir 47cdf0e10cSrcweir using namespace ::com::sun::star; 48cdf0e10cSrcweir 49cdf0e10cSrcweir #define INVAL_SEL 0xFFFF 50cdf0e10cSrcweir 51cdf0e10cSrcweir sal_uInt16 CertificateChooser::GetSelectedEntryPos( void ) const 52cdf0e10cSrcweir { 53cdf0e10cSrcweir sal_uInt16 nSel = INVAL_SEL; 54cdf0e10cSrcweir 55cdf0e10cSrcweir SvLBoxEntry* pSel = maCertLB.FirstSelected(); 56cdf0e10cSrcweir if( pSel ) 57cdf0e10cSrcweir nSel = (sal_uInt16) ( sal_uIntPtr ) pSel->GetUserData(); 58cdf0e10cSrcweir 59cdf0e10cSrcweir return (sal_uInt16) nSel; 60cdf0e10cSrcweir } 61cdf0e10cSrcweir 62cdf0e10cSrcweir CertificateChooser::CertificateChooser( Window* _pParent, uno::Reference< uno::XComponentContext>& _rxCtx, uno::Reference< dcss::xml::crypto::XSecurityEnvironment >& _rxSecurityEnvironment, const SignatureInformations& _rCertsToIgnore ) 63cdf0e10cSrcweir :ModalDialog ( _pParent, XMLSEC_RES( RID_XMLSECDLG_CERTCHOOSER ) ) 64cdf0e10cSrcweir ,maCertsToIgnore( _rCertsToIgnore ) 65cdf0e10cSrcweir ,maHintFT ( this, XMLSEC_RES( FT_HINT_SELECT ) ) 66cdf0e10cSrcweir ,maCertLB ( this, XMLSEC_RES( LB_SIGNATURES ) ) 67cdf0e10cSrcweir ,maViewBtn ( this, XMLSEC_RES( BTN_VIEWCERT ) ) 68cdf0e10cSrcweir ,maBottomSepFL ( this, XMLSEC_RES( FL_BOTTOM_SEP ) ) 69cdf0e10cSrcweir ,maOKBtn ( this, XMLSEC_RES( BTN_OK ) ) 70cdf0e10cSrcweir ,maCancelBtn ( this, XMLSEC_RES( BTN_CANCEL ) ) 71cdf0e10cSrcweir ,maHelpBtn ( this, XMLSEC_RES( BTN_HELP ) ) 72cdf0e10cSrcweir { 73cdf0e10cSrcweir static long nTabs[] = { 3, 0, 30*CS_LB_WIDTH/100, 60*CS_LB_WIDTH/100 }; 74cdf0e10cSrcweir maCertLB.SetTabs( &nTabs[0] ); 75cdf0e10cSrcweir maCertLB.InsertHeaderEntry( String( XMLSEC_RES( STR_HEADERBAR ) ) ); 76cdf0e10cSrcweir maCertLB.SetSelectHdl( LINK( this, CertificateChooser, CertificateHighlightHdl ) ); 77cdf0e10cSrcweir maCertLB.SetDoubleClickHdl( LINK( this, CertificateChooser, CertificateSelectHdl ) ); 78cdf0e10cSrcweir maViewBtn.SetClickHdl( LINK( this, CertificateChooser, ViewButtonHdl ) ); 79cdf0e10cSrcweir 80cdf0e10cSrcweir FreeResource(); 81cdf0e10cSrcweir 82cdf0e10cSrcweir mxCtx = _rxCtx; 83cdf0e10cSrcweir mxSecurityEnvironment = _rxSecurityEnvironment; 84cdf0e10cSrcweir mbInitialized = sal_False; 85cdf0e10cSrcweir 86cdf0e10cSrcweir // disable buttons 87cdf0e10cSrcweir CertificateHighlightHdl( NULL ); 88cdf0e10cSrcweir } 89cdf0e10cSrcweir 90cdf0e10cSrcweir CertificateChooser::~CertificateChooser() 91cdf0e10cSrcweir { 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94cdf0e10cSrcweir short CertificateChooser::Execute() 95cdf0e10cSrcweir { 96cdf0e10cSrcweir // #i48432# 97cdf0e10cSrcweir // We can't check for personal certificates before raising this dialog, 98cdf0e10cSrcweir // because the mozilla implementation throws a NoPassword exception, 99cdf0e10cSrcweir // if the user pressed cancel, and also if the database does not exist! 100cdf0e10cSrcweir // But in the later case, the is no password query, and the user is confused 101cdf0e10cSrcweir // that nothing happens when pressing "Add..." in the SignatureDialog. 102cdf0e10cSrcweir 103cdf0e10cSrcweir // PostUserEvent( LINK( this, CertificateChooser, Initialize ) ); 104cdf0e10cSrcweir 105cdf0e10cSrcweir // PostUserLink behavior is to slow, so do it directly before Execute(). 106cdf0e10cSrcweir // Problem: This Dialog should be visible right now, and the parent should not be accessible. 107cdf0e10cSrcweir // Show, Update, DIsableInput... 108cdf0e10cSrcweir 109cdf0e10cSrcweir Window* pMe = this; 110cdf0e10cSrcweir Window* pParent = GetParent(); 111cdf0e10cSrcweir if ( pParent ) 112cdf0e10cSrcweir pParent->EnableInput( sal_False ); 113cdf0e10cSrcweir pMe->Show(); 114cdf0e10cSrcweir pMe->Update(); 115cdf0e10cSrcweir ImplInitialize(); 116cdf0e10cSrcweir if ( pParent ) 117cdf0e10cSrcweir pParent->EnableInput( sal_True ); 118cdf0e10cSrcweir return ModalDialog::Execute(); 119cdf0e10cSrcweir } 120cdf0e10cSrcweir 121cdf0e10cSrcweir // IMPL_LINK( CertificateChooser, Initialize, void*, EMPTYARG ) 122cdf0e10cSrcweir void CertificateChooser::ImplInitialize() 123cdf0e10cSrcweir { 124cdf0e10cSrcweir if ( !mbInitialized ) 125cdf0e10cSrcweir { 126cdf0e10cSrcweir try 127cdf0e10cSrcweir { 128cdf0e10cSrcweir maCerts = mxSecurityEnvironment->getPersonalCertificates(); 129cdf0e10cSrcweir } 130cdf0e10cSrcweir catch (security::NoPasswordException&) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir uno::Reference< dcss::security::XSerialNumberAdapter> xSerialNumberAdapter = 135cdf0e10cSrcweir ::com::sun::star::security::SerialNumberAdapter::create(mxCtx); 136cdf0e10cSrcweir 137cdf0e10cSrcweir sal_Int32 nCertificates = maCerts.getLength(); 138cdf0e10cSrcweir sal_Int32 nCertificatesToIgnore = maCertsToIgnore.size(); 139cdf0e10cSrcweir for( sal_Int32 nCert = nCertificates; nCert; ) 140cdf0e10cSrcweir { 141cdf0e10cSrcweir uno::Reference< security::XCertificate > xCert = maCerts[ --nCert ]; 142cdf0e10cSrcweir sal_Bool bIgnoreThis = false; 143cdf0e10cSrcweir 144cdf0e10cSrcweir // Do we already use that? 145cdf0e10cSrcweir if( nCertificatesToIgnore ) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir rtl::OUString aIssuerName = xCert->getIssuerName(); 148cdf0e10cSrcweir for( sal_Int32 nSig = 0; nSig < nCertificatesToIgnore; ++nSig ) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir const SignatureInformation& rInf = maCertsToIgnore[ nSig ]; 151cdf0e10cSrcweir if ( ( aIssuerName == rInf.ouX509IssuerName ) && 152cdf0e10cSrcweir ( xSerialNumberAdapter->toString( xCert->getSerialNumber() ) == rInf.ouX509SerialNumber ) ) 153cdf0e10cSrcweir { 154cdf0e10cSrcweir bIgnoreThis = true; 155cdf0e10cSrcweir break; 156cdf0e10cSrcweir } 157cdf0e10cSrcweir } 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir if ( !bIgnoreThis ) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir // Check if we have a private key for this... 163cdf0e10cSrcweir long nCertificateCharacters = mxSecurityEnvironment->getCertificateCharacters( xCert ); 164cdf0e10cSrcweir 165cdf0e10cSrcweir if ( !( nCertificateCharacters & security::CertificateCharacters::HAS_PRIVATE_KEY ) ) 166cdf0e10cSrcweir bIgnoreThis = true; 167cdf0e10cSrcweir 168cdf0e10cSrcweir } 169cdf0e10cSrcweir 170cdf0e10cSrcweir if ( bIgnoreThis ) 171cdf0e10cSrcweir { 172cdf0e10cSrcweir ::comphelper::removeElementAt( maCerts, nCert ); 173cdf0e10cSrcweir nCertificates = maCerts.getLength(); 174cdf0e10cSrcweir } 175cdf0e10cSrcweir } 176cdf0e10cSrcweir 177cdf0e10cSrcweir // fill list of certificates; the first entry will be selected 178cdf0e10cSrcweir for ( sal_Int32 nC = 0; nC < nCertificates; ++nC ) 179cdf0e10cSrcweir { 180cdf0e10cSrcweir String sEntry( XmlSec::GetContentPart( maCerts[ nC ]->getSubjectName() ) ); 181cdf0e10cSrcweir sEntry += '\t'; 182cdf0e10cSrcweir sEntry += XmlSec::GetContentPart( maCerts[ nC ]->getIssuerName() ); 183cdf0e10cSrcweir sEntry += '\t'; 184cdf0e10cSrcweir sEntry += XmlSec::GetDateString( maCerts[ nC ]->getNotValidAfter() ); 185cdf0e10cSrcweir SvLBoxEntry* pEntry = maCertLB.InsertEntry( sEntry ); 186cdf0e10cSrcweir pEntry->SetUserData( ( void* )nC ); // missuse user data as index 187cdf0e10cSrcweir } 188cdf0e10cSrcweir 189cdf0e10cSrcweir // enable/disable buttons 190cdf0e10cSrcweir CertificateHighlightHdl( NULL ); 191cdf0e10cSrcweir mbInitialized = sal_True; 192cdf0e10cSrcweir } 193cdf0e10cSrcweir } 194cdf0e10cSrcweir 195cdf0e10cSrcweir 196cdf0e10cSrcweir uno::Reference< dcss::security::XCertificate > CertificateChooser::GetSelectedCertificate() 197cdf0e10cSrcweir { 198cdf0e10cSrcweir uno::Reference< dcss::security::XCertificate > xCert; 199cdf0e10cSrcweir sal_uInt16 nSelected = GetSelectedEntryPos(); 200cdf0e10cSrcweir if ( nSelected < maCerts.getLength() ) 201cdf0e10cSrcweir xCert = maCerts[ nSelected ]; 202cdf0e10cSrcweir return xCert; 203cdf0e10cSrcweir } 204cdf0e10cSrcweir 205cdf0e10cSrcweir IMPL_LINK( CertificateChooser, CertificateHighlightHdl, void*, EMPTYARG ) 206cdf0e10cSrcweir { 207cdf0e10cSrcweir sal_Bool bEnable = GetSelectedCertificate().is(); 208cdf0e10cSrcweir maViewBtn.Enable( bEnable ); 209cdf0e10cSrcweir maOKBtn.Enable( bEnable ); 210cdf0e10cSrcweir return 0; 211cdf0e10cSrcweir } 212cdf0e10cSrcweir 213cdf0e10cSrcweir IMPL_LINK( CertificateChooser, CertificateSelectHdl, void*, EMPTYARG ) 214cdf0e10cSrcweir { 215cdf0e10cSrcweir EndDialog( RET_OK ); 216cdf0e10cSrcweir return 0; 217cdf0e10cSrcweir } 218cdf0e10cSrcweir 219cdf0e10cSrcweir IMPL_LINK( CertificateChooser, ViewButtonHdl, Button*, EMPTYARG ) 220cdf0e10cSrcweir { 221cdf0e10cSrcweir ImplShowCertificateDetails(); 222cdf0e10cSrcweir return 0; 223cdf0e10cSrcweir } 224cdf0e10cSrcweir 225cdf0e10cSrcweir void CertificateChooser::ImplShowCertificateDetails() 226cdf0e10cSrcweir { 227cdf0e10cSrcweir uno::Reference< dcss::security::XCertificate > xCert = GetSelectedCertificate(); 228cdf0e10cSrcweir if( xCert.is() ) 229cdf0e10cSrcweir { 230cdf0e10cSrcweir CertificateViewer aViewer( this, mxSecurityEnvironment, xCert, sal_True ); 231cdf0e10cSrcweir aViewer.Execute(); 232cdf0e10cSrcweir } 233cdf0e10cSrcweir } 234cdf0e10cSrcweir 235