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