xref: /AOO41X/main/xmlsecurity/source/dialogs/certificatechooser.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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