xref: /AOO41X/main/xmlsecurity/source/dialogs/certificatechooser.cxx (revision 06b3ce531745799678cf4bb887ef37436d81238b)
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 
GetSelectedEntryPos(void) const51cdf0e10cSrcweir 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 
CertificateChooser(Window * _pParent,uno::Reference<uno::XComponentContext> & _rxCtx,uno::Reference<dcss::xml::crypto::XSecurityEnvironment> & _rxSecurityEnvironment,const SignatureInformations & _rCertsToIgnore)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 
~CertificateChooser()90cdf0e10cSrcweir CertificateChooser::~CertificateChooser()
91cdf0e10cSrcweir {
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
Execute()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 )
ImplInitialize()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 
GetSelectedCertificate()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 
IMPL_LINK(CertificateChooser,CertificateHighlightHdl,void *,EMPTYARG)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 
IMPL_LINK(CertificateChooser,CertificateSelectHdl,void *,EMPTYARG)213cdf0e10cSrcweir IMPL_LINK( CertificateChooser, CertificateSelectHdl, void*, EMPTYARG )
214cdf0e10cSrcweir {
215cdf0e10cSrcweir     EndDialog( RET_OK );
216cdf0e10cSrcweir     return 0;
217cdf0e10cSrcweir }
218cdf0e10cSrcweir 
IMPL_LINK(CertificateChooser,ViewButtonHdl,Button *,EMPTYARG)219cdf0e10cSrcweir IMPL_LINK( CertificateChooser, ViewButtonHdl, Button*, EMPTYARG )
220cdf0e10cSrcweir {
221cdf0e10cSrcweir     ImplShowCertificateDetails();
222cdf0e10cSrcweir     return 0;
223cdf0e10cSrcweir }
224cdf0e10cSrcweir 
ImplShowCertificateDetails()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