1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
31 #include <xmlsecurity/certificatechooser.hxx>
32 #include <xmlsecurity/certificateviewer.hxx>
33 #include <xmlsecurity/biginteger.hxx>
34 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
35 #include <comphelper/sequence.hxx>
36 #include <comphelper/processfactory.hxx>
38 #include <com/sun/star/security/NoPasswordException.hpp>
39 #include <com/sun/star/security/CertificateCharacters.hpp>
40 #include <com/sun/star/security/SerialNumberAdapter.hpp>
42 #include <dialogs.hrc>
43 #include <resourcemanager.hxx>
44 #include <vcl/msgbox.hxx>
46 /* HACK: disable some warnings for MS-C */
48 #pragma warning (disable : 4355) // 4355: this used in initializer-list
51 using namespace ::com::sun::star
;
53 #define INVAL_SEL 0xFFFF
55 USHORT
CertificateChooser::GetSelectedEntryPos( void ) const
57 USHORT nSel
= INVAL_SEL
;
59 SvLBoxEntry
* pSel
= maCertLB
.FirstSelected();
61 nSel
= (USHORT
) ( sal_uIntPtr
) pSel
->GetUserData();
66 CertificateChooser::CertificateChooser( Window
* _pParent
, uno::Reference
< uno::XComponentContext
>& _rxCtx
, uno::Reference
< dcss::xml::crypto::XSecurityEnvironment
>& _rxSecurityEnvironment
, const SignatureInformations
& _rCertsToIgnore
)
67 :ModalDialog ( _pParent
, XMLSEC_RES( RID_XMLSECDLG_CERTCHOOSER
) )
68 ,maCertsToIgnore( _rCertsToIgnore
)
69 ,maHintFT ( this, XMLSEC_RES( FT_HINT_SELECT
) )
70 ,maCertLB ( this, XMLSEC_RES( LB_SIGNATURES
) )
71 ,maViewBtn ( this, XMLSEC_RES( BTN_VIEWCERT
) )
72 ,maBottomSepFL ( this, XMLSEC_RES( FL_BOTTOM_SEP
) )
73 ,maOKBtn ( this, XMLSEC_RES( BTN_OK
) )
74 ,maCancelBtn ( this, XMLSEC_RES( BTN_CANCEL
) )
75 ,maHelpBtn ( this, XMLSEC_RES( BTN_HELP
) )
77 static long nTabs
[] = { 3, 0, 30*CS_LB_WIDTH
/100, 60*CS_LB_WIDTH
/100 };
78 maCertLB
.SetTabs( &nTabs
[0] );
79 maCertLB
.InsertHeaderEntry( String( XMLSEC_RES( STR_HEADERBAR
) ) );
80 maCertLB
.SetSelectHdl( LINK( this, CertificateChooser
, CertificateHighlightHdl
) );
81 maCertLB
.SetDoubleClickHdl( LINK( this, CertificateChooser
, CertificateSelectHdl
) );
82 maViewBtn
.SetClickHdl( LINK( this, CertificateChooser
, ViewButtonHdl
) );
87 mxSecurityEnvironment
= _rxSecurityEnvironment
;
88 mbInitialized
= FALSE
;
91 CertificateHighlightHdl( NULL
);
94 CertificateChooser::~CertificateChooser()
98 short CertificateChooser::Execute()
101 // We can't check for personal certificates before raising this dialog,
102 // because the mozilla implementation throws a NoPassword exception,
103 // if the user pressed cancel, and also if the database does not exist!
104 // But in the later case, the is no password query, and the user is confused
105 // that nothing happens when pressing "Add..." in the SignatureDialog.
107 // PostUserEvent( LINK( this, CertificateChooser, Initialize ) );
109 // PostUserLink behavior is to slow, so do it directly before Execute().
110 // Problem: This Dialog should be visible right now, and the parent should not be accessible.
111 // Show, Update, DIsableInput...
114 Window
* pParent
= GetParent();
116 pParent
->EnableInput( FALSE
);
121 pParent
->EnableInput( TRUE
);
122 return ModalDialog::Execute();
125 // IMPL_LINK( CertificateChooser, Initialize, void*, EMPTYARG )
126 void CertificateChooser::ImplInitialize()
128 if ( !mbInitialized
)
132 maCerts
= mxSecurityEnvironment
->getPersonalCertificates();
134 catch (security::NoPasswordException
&)
138 uno::Reference
< dcss::security::XSerialNumberAdapter
> xSerialNumberAdapter
=
139 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx
);
141 sal_Int32 nCertificates
= maCerts
.getLength();
142 sal_Int32 nCertificatesToIgnore
= maCertsToIgnore
.size();
143 for( sal_Int32 nCert
= nCertificates
; nCert
; )
145 uno::Reference
< security::XCertificate
> xCert
= maCerts
[ --nCert
];
146 sal_Bool bIgnoreThis
= false;
148 // Do we already use that?
149 if( nCertificatesToIgnore
)
151 rtl::OUString aIssuerName
= xCert
->getIssuerName();
152 for( sal_Int32 nSig
= 0; nSig
< nCertificatesToIgnore
; ++nSig
)
154 const SignatureInformation
& rInf
= maCertsToIgnore
[ nSig
];
155 if ( ( aIssuerName
== rInf
.ouX509IssuerName
) &&
156 ( xSerialNumberAdapter
->toString( xCert
->getSerialNumber() ) == rInf
.ouX509SerialNumber
) )
166 // Check if we have a private key for this...
167 long nCertificateCharacters
= mxSecurityEnvironment
->getCertificateCharacters( xCert
);
169 if ( !( nCertificateCharacters
& security::CertificateCharacters::HAS_PRIVATE_KEY
) )
176 ::comphelper::removeElementAt( maCerts
, nCert
);
177 nCertificates
= maCerts
.getLength();
181 // fill list of certificates; the first entry will be selected
182 for ( sal_Int32 nC
= 0; nC
< nCertificates
; ++nC
)
184 String
sEntry( XmlSec::GetContentPart( maCerts
[ nC
]->getSubjectName() ) );
186 sEntry
+= XmlSec::GetContentPart( maCerts
[ nC
]->getIssuerName() );
188 sEntry
+= XmlSec::GetDateString( maCerts
[ nC
]->getNotValidAfter() );
189 SvLBoxEntry
* pEntry
= maCertLB
.InsertEntry( sEntry
);
190 pEntry
->SetUserData( ( void* )nC
); // missuse user data as index
193 // enable/disable buttons
194 CertificateHighlightHdl( NULL
);
195 mbInitialized
= TRUE
;
200 uno::Reference
< dcss::security::XCertificate
> CertificateChooser::GetSelectedCertificate()
202 uno::Reference
< dcss::security::XCertificate
> xCert
;
203 USHORT nSelected
= GetSelectedEntryPos();
204 if ( nSelected
< maCerts
.getLength() )
205 xCert
= maCerts
[ nSelected
];
209 IMPL_LINK( CertificateChooser
, CertificateHighlightHdl
, void*, EMPTYARG
)
211 sal_Bool bEnable
= GetSelectedCertificate().is();
212 maViewBtn
.Enable( bEnable
);
213 maOKBtn
.Enable( bEnable
);
217 IMPL_LINK( CertificateChooser
, CertificateSelectHdl
, void*, EMPTYARG
)
223 IMPL_LINK( CertificateChooser
, ViewButtonHdl
, Button
*, EMPTYARG
)
225 ImplShowCertificateDetails();
229 void CertificateChooser::ImplShowCertificateDetails()
231 uno::Reference
< dcss::security::XCertificate
> xCert
= GetSelectedCertificate();
234 CertificateViewer
aViewer( this, mxSecurityEnvironment
, xCert
, TRUE
);