xref: /trunk/main/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.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 
29*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
30*cdf0e10cSrcweir #include "precompiled_xmlsecurity.hxx"
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir //todo before commit:  nssrenam.h is not delivered!!!
33*cdf0e10cSrcweir #include "nssrenam.h"
34*cdf0e10cSrcweir #include "cert.h"
35*cdf0e10cSrcweir #include "secerr.h"
36*cdf0e10cSrcweir #include "ocsp.h"
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include <sal/config.h>
39*cdf0e10cSrcweir #include "securityenvironment_nssimpl.hxx"
40*cdf0e10cSrcweir #include "x509certificate_nssimpl.hxx"
41*cdf0e10cSrcweir #include <rtl/uuid.h>
42*cdf0e10cSrcweir #include "../diagnose.hxx"
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #include <sal/types.h>
45*cdf0e10cSrcweir //For reasons that escape me, this is what xmlsec does when size_t is not 4
46*cdf0e10cSrcweir #if SAL_TYPES_SIZEOFPOINTER != 4
47*cdf0e10cSrcweir #    define XMLSEC_NO_SIZE_T
48*cdf0e10cSrcweir #endif
49*cdf0e10cSrcweir #include <xmlsec/xmlsec.h>
50*cdf0e10cSrcweir #include <xmlsec/keysmngr.h>
51*cdf0e10cSrcweir #include <xmlsec/crypto.h>
52*cdf0e10cSrcweir #include <xmlsec/base64.h>
53*cdf0e10cSrcweir #include <xmlsec/strings.h>
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir #include <tools/string.hxx>
56*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
57*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
58*cdf0e10cSrcweir #include <cppuhelper/servicefactory.hxx>
59*cdf0e10cSrcweir #include <comphelper/docpasswordrequest.hxx>
60*cdf0e10cSrcweir #include <xmlsecurity/biginteger.hxx>
61*cdf0e10cSrcweir #include <rtl/logfile.h>
62*cdf0e10cSrcweir #include <com/sun/star/task/XInteractionHandler.hpp>
63*cdf0e10cSrcweir #include <vector>
64*cdf0e10cSrcweir #include "boost/scoped_array.hpp"
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir #include "secerror.hxx"
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir // MM : added for password exception
69*cdf0e10cSrcweir #include <com/sun/star/security/NoPasswordException.hpp>
70*cdf0e10cSrcweir namespace csss = ::com::sun::star::security;
71*cdf0e10cSrcweir using namespace xmlsecurity;
72*cdf0e10cSrcweir using namespace ::com::sun::star::security;
73*cdf0e10cSrcweir using namespace com::sun::star;
74*cdf0e10cSrcweir using namespace ::com::sun::star::uno ;
75*cdf0e10cSrcweir using namespace ::com::sun::star::lang ;
76*cdf0e10cSrcweir using ::com::sun::star::lang::XMultiServiceFactory ;
77*cdf0e10cSrcweir using ::com::sun::star::lang::XSingleServiceFactory ;
78*cdf0e10cSrcweir using ::rtl::OUString ;
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
81*cdf0e10cSrcweir using ::com::sun::star::security::XCertificate ;
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir extern X509Certificate_NssImpl* NssCertToXCert( CERTCertificate* cert ) ;
84*cdf0e10cSrcweir extern X509Certificate_NssImpl* NssPrivKeyToXCert( SECKEYPrivateKey* ) ;
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir struct UsageDescription
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir     SECCertificateUsage usage;
90*cdf0e10cSrcweir     char const* description;
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir     UsageDescription()
93*cdf0e10cSrcweir     : usage( certificateUsageCheckAllUsages )
94*cdf0e10cSrcweir     , description( NULL )
95*cdf0e10cSrcweir     {}
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir     UsageDescription( SECCertificateUsage i_usage, char const* i_description )
98*cdf0e10cSrcweir     : usage( i_usage )
99*cdf0e10cSrcweir     , description( i_description )
100*cdf0e10cSrcweir     {}
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir     UsageDescription( const UsageDescription& aDescription )
103*cdf0e10cSrcweir     : usage( aDescription.usage )
104*cdf0e10cSrcweir     , description( aDescription.description )
105*cdf0e10cSrcweir     {}
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir     UsageDescription& operator =( const UsageDescription& aDescription )
108*cdf0e10cSrcweir     {
109*cdf0e10cSrcweir         usage = aDescription.usage;
110*cdf0e10cSrcweir         description = aDescription.description;
111*cdf0e10cSrcweir         return *this;
112*cdf0e10cSrcweir     }
113*cdf0e10cSrcweir };
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir char* GetPasswordFunction( PK11SlotInfo* pSlot, PRBool bRetry, void* /*arg*/ )
118*cdf0e10cSrcweir {
119*cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() );
120*cdf0e10cSrcweir     if ( xMSF.is() )
121*cdf0e10cSrcweir     {
122*cdf0e10cSrcweir         uno::Reference < task::XInteractionHandler > xInteractionHandler(
123*cdf0e10cSrcweir             xMSF->createInstance( rtl::OUString::createFromAscii("com.sun.star.task.InteractionHandler") ), uno::UNO_QUERY );
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir         if ( xInteractionHandler.is() )
126*cdf0e10cSrcweir         {
127*cdf0e10cSrcweir             task::PasswordRequestMode eMode = bRetry ? task::PasswordRequestMode_PASSWORD_REENTER : task::PasswordRequestMode_PASSWORD_ENTER;
128*cdf0e10cSrcweir             ::comphelper::DocPasswordRequest* pPasswordRequest = new ::comphelper::DocPasswordRequest(
129*cdf0e10cSrcweir                 ::comphelper::DocPasswordRequestType_STANDARD, eMode, ::rtl::OUString::createFromAscii(PK11_GetTokenName(pSlot)) );
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir             uno::Reference< task::XInteractionRequest > xRequest( pPasswordRequest );
132*cdf0e10cSrcweir             xInteractionHandler->handle( xRequest );
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir             if ( pPasswordRequest->isPassword() )
135*cdf0e10cSrcweir             {
136*cdf0e10cSrcweir                 ByteString aPassword = ByteString( String( pPasswordRequest->getPassword() ), gsl_getSystemTextEncoding() );
137*cdf0e10cSrcweir                 sal_uInt16 nLen = aPassword.Len();
138*cdf0e10cSrcweir                 char* pPassword = (char*) PORT_Alloc( nLen+1 ) ;
139*cdf0e10cSrcweir                 pPassword[nLen] = 0;
140*cdf0e10cSrcweir                 memcpy( pPassword, aPassword.GetBuffer(), nLen );
141*cdf0e10cSrcweir                 return pPassword;
142*cdf0e10cSrcweir             }
143*cdf0e10cSrcweir         }
144*cdf0e10cSrcweir     }
145*cdf0e10cSrcweir     return NULL;
146*cdf0e10cSrcweir }
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir SecurityEnvironment_NssImpl :: SecurityEnvironment_NssImpl( const Reference< XMultiServiceFactory >& ) :
149*cdf0e10cSrcweir m_pHandler( NULL ) , m_tSymKeyList() , m_tPubKeyList() , m_tPriKeyList() {
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir     PK11_SetPasswordFunc( GetPasswordFunction ) ;
152*cdf0e10cSrcweir }
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir SecurityEnvironment_NssImpl :: ~SecurityEnvironment_NssImpl() {
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir     PK11_SetPasswordFunc( NULL ) ;
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir     for (CIT_SLOTS i = m_Slots.begin(); i != m_Slots.end(); i++)
159*cdf0e10cSrcweir     {
160*cdf0e10cSrcweir         PK11_FreeSlot(*i);
161*cdf0e10cSrcweir     }
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir     if( !m_tSymKeyList.empty()  ) {
164*cdf0e10cSrcweir         std::list< PK11SymKey* >::iterator symKeyIt ;
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir         for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; symKeyIt ++ )
167*cdf0e10cSrcweir             PK11_FreeSymKey( *symKeyIt ) ;
168*cdf0e10cSrcweir     }
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir     if( !m_tPubKeyList.empty()  ) {
171*cdf0e10cSrcweir         std::list< SECKEYPublicKey* >::iterator pubKeyIt ;
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir         for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; pubKeyIt ++ )
174*cdf0e10cSrcweir             SECKEY_DestroyPublicKey( *pubKeyIt ) ;
175*cdf0e10cSrcweir     }
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir     if( !m_tPriKeyList.empty()  ) {
178*cdf0e10cSrcweir         std::list< SECKEYPrivateKey* >::iterator priKeyIt ;
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir         for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; priKeyIt ++ )
181*cdf0e10cSrcweir             SECKEY_DestroyPrivateKey( *priKeyIt ) ;
182*cdf0e10cSrcweir     }
183*cdf0e10cSrcweir }
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir /* XInitialization */
186*cdf0e10cSrcweir void SAL_CALL SecurityEnvironment_NssImpl :: initialize( const Sequence< Any >& ) throw( Exception, RuntimeException ) {
187*cdf0e10cSrcweir     // TBD
188*cdf0e10cSrcweir } ;
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir /* XServiceInfo */
191*cdf0e10cSrcweir OUString SAL_CALL SecurityEnvironment_NssImpl :: getImplementationName() throw( RuntimeException ) {
192*cdf0e10cSrcweir     return impl_getImplementationName() ;
193*cdf0e10cSrcweir }
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir /* XServiceInfo */
196*cdf0e10cSrcweir sal_Bool SAL_CALL SecurityEnvironment_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
197*cdf0e10cSrcweir     Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
198*cdf0e10cSrcweir     const OUString* pArray = seqServiceNames.getConstArray() ;
199*cdf0e10cSrcweir     for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
200*cdf0e10cSrcweir         if( *( pArray + i ) == serviceName )
201*cdf0e10cSrcweir             return sal_True ;
202*cdf0e10cSrcweir     }
203*cdf0e10cSrcweir     return sal_False ;
204*cdf0e10cSrcweir }
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir /* XServiceInfo */
207*cdf0e10cSrcweir Sequence< OUString > SAL_CALL SecurityEnvironment_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) {
208*cdf0e10cSrcweir     return impl_getSupportedServiceNames() ;
209*cdf0e10cSrcweir }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir //Helper for XServiceInfo
212*cdf0e10cSrcweir Sequence< OUString > SecurityEnvironment_NssImpl :: impl_getSupportedServiceNames() {
213*cdf0e10cSrcweir     ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
214*cdf0e10cSrcweir     Sequence< OUString > seqServiceNames( 1 ) ;
215*cdf0e10cSrcweir     seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.SecurityEnvironment" ) ;
216*cdf0e10cSrcweir     return seqServiceNames ;
217*cdf0e10cSrcweir }
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir OUString SecurityEnvironment_NssImpl :: impl_getImplementationName() throw( RuntimeException ) {
220*cdf0e10cSrcweir     return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_NssImpl" ) ;
221*cdf0e10cSrcweir }
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir //Helper for registry
224*cdf0e10cSrcweir Reference< XInterface > SAL_CALL SecurityEnvironment_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
225*cdf0e10cSrcweir     return Reference< XInterface >( *new SecurityEnvironment_NssImpl( aServiceManager ) ) ;
226*cdf0e10cSrcweir }
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir Reference< XSingleServiceFactory > SecurityEnvironment_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
229*cdf0e10cSrcweir     //Reference< XSingleServiceFactory > xFactory ;
230*cdf0e10cSrcweir     //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
231*cdf0e10cSrcweir     //return xFactory ;
232*cdf0e10cSrcweir     return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
233*cdf0e10cSrcweir }
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir /* XUnoTunnel */
236*cdf0e10cSrcweir sal_Int64 SAL_CALL SecurityEnvironment_NssImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier )
237*cdf0e10cSrcweir     throw( RuntimeException )
238*cdf0e10cSrcweir {
239*cdf0e10cSrcweir     if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
240*cdf0e10cSrcweir         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
241*cdf0e10cSrcweir     }
242*cdf0e10cSrcweir     return 0 ;
243*cdf0e10cSrcweir }
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir /* XUnoTunnel extension */
246*cdf0e10cSrcweir const Sequence< sal_Int8>& SecurityEnvironment_NssImpl :: getUnoTunnelId() {
247*cdf0e10cSrcweir     static Sequence< sal_Int8 >* pSeq = 0 ;
248*cdf0e10cSrcweir     if( !pSeq ) {
249*cdf0e10cSrcweir         ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
250*cdf0e10cSrcweir         if( !pSeq ) {
251*cdf0e10cSrcweir             static Sequence< sal_Int8> aSeq( 16 ) ;
252*cdf0e10cSrcweir             rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ;
253*cdf0e10cSrcweir             pSeq = &aSeq ;
254*cdf0e10cSrcweir         }
255*cdf0e10cSrcweir     }
256*cdf0e10cSrcweir     return *pSeq ;
257*cdf0e10cSrcweir }
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir /* XUnoTunnel extension */
260*cdf0e10cSrcweir SecurityEnvironment_NssImpl* SecurityEnvironment_NssImpl :: getImplementation( const Reference< XInterface > xObj ) {
261*cdf0e10cSrcweir     Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ;
262*cdf0e10cSrcweir     if( xUT.is() ) {
263*cdf0e10cSrcweir         return reinterpret_cast<SecurityEnvironment_NssImpl*>(
264*cdf0e10cSrcweir             sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( getUnoTunnelId() ))) ;
265*cdf0e10cSrcweir     } else
266*cdf0e10cSrcweir         return NULL ;
267*cdf0e10cSrcweir }
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir ::rtl::OUString SecurityEnvironment_NssImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException )
271*cdf0e10cSrcweir {
272*cdf0e10cSrcweir     rtl::OUString result;
273*cdf0e10cSrcweir     ::rtl::OUStringBuffer buff;
274*cdf0e10cSrcweir     for (CIT_SLOTS is = m_Slots.begin(); is != m_Slots.end(); is++)
275*cdf0e10cSrcweir     {
276*cdf0e10cSrcweir         buff.append(rtl::OUString::createFromAscii(PK11_GetTokenName(*is)));
277*cdf0e10cSrcweir         buff.appendAscii("\n");
278*cdf0e10cSrcweir     }
279*cdf0e10cSrcweir     return buff.makeStringAndClear();
280*cdf0e10cSrcweir }
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir void SecurityEnvironment_NssImpl::addCryptoSlot( PK11SlotInfo* aSlot) throw( Exception , RuntimeException )
283*cdf0e10cSrcweir {
284*cdf0e10cSrcweir     PK11_ReferenceSlot(aSlot);
285*cdf0e10cSrcweir     m_Slots.push_back(aSlot);
286*cdf0e10cSrcweir }
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir CERTCertDBHandle* SecurityEnvironment_NssImpl :: getCertDb() throw( Exception , RuntimeException ) {
289*cdf0e10cSrcweir     return m_pHandler ;
290*cdf0e10cSrcweir }
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir //Could we have multiple cert dbs?
293*cdf0e10cSrcweir void SecurityEnvironment_NssImpl :: setCertDb( CERTCertDBHandle* aCertDb ) throw( Exception , RuntimeException ) {
294*cdf0e10cSrcweir     m_pHandler = aCertDb ;
295*cdf0e10cSrcweir }
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir void SecurityEnvironment_NssImpl :: adoptSymKey( PK11SymKey* aSymKey ) throw( Exception , RuntimeException ) {
298*cdf0e10cSrcweir     PK11SymKey* symkey ;
299*cdf0e10cSrcweir     std::list< PK11SymKey* >::iterator keyIt ;
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir     if( aSymKey != NULL ) {
302*cdf0e10cSrcweir         //First try to find the key in the list
303*cdf0e10cSrcweir         for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
304*cdf0e10cSrcweir             if( *keyIt == aSymKey )
305*cdf0e10cSrcweir                 return ;
306*cdf0e10cSrcweir         }
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir         //If we do not find the key in the list, add a new node
309*cdf0e10cSrcweir         symkey = PK11_ReferenceSymKey( aSymKey ) ;
310*cdf0e10cSrcweir         if( symkey == NULL )
311*cdf0e10cSrcweir             throw RuntimeException() ;
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir         try {
314*cdf0e10cSrcweir             m_tSymKeyList.push_back( symkey ) ;
315*cdf0e10cSrcweir         } catch ( Exception& ) {
316*cdf0e10cSrcweir             PK11_FreeSymKey( symkey ) ;
317*cdf0e10cSrcweir         }
318*cdf0e10cSrcweir     }
319*cdf0e10cSrcweir }
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir void SecurityEnvironment_NssImpl :: rejectSymKey( PK11SymKey* aSymKey ) throw( Exception , RuntimeException ) {
322*cdf0e10cSrcweir     PK11SymKey* symkey ;
323*cdf0e10cSrcweir     std::list< PK11SymKey* >::iterator keyIt ;
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir     if( aSymKey != NULL ) {
326*cdf0e10cSrcweir         for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
327*cdf0e10cSrcweir             if( *keyIt == aSymKey ) {
328*cdf0e10cSrcweir                 symkey = *keyIt ;
329*cdf0e10cSrcweir                 PK11_FreeSymKey( symkey ) ;
330*cdf0e10cSrcweir                 m_tSymKeyList.erase( keyIt ) ;
331*cdf0e10cSrcweir                 break ;
332*cdf0e10cSrcweir             }
333*cdf0e10cSrcweir         }
334*cdf0e10cSrcweir     }
335*cdf0e10cSrcweir }
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir PK11SymKey* SecurityEnvironment_NssImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) {
338*cdf0e10cSrcweir     PK11SymKey* symkey ;
339*cdf0e10cSrcweir     std::list< PK11SymKey* >::iterator keyIt ;
340*cdf0e10cSrcweir     unsigned int pos ;
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir     symkey = NULL ;
343*cdf0e10cSrcweir     for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; pos ++ , keyIt ++ ) ;
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir     if( pos == position && keyIt != m_tSymKeyList.end() )
346*cdf0e10cSrcweir         symkey = *keyIt ;
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir     return symkey ;
349*cdf0e10cSrcweir }
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir void SecurityEnvironment_NssImpl :: adoptPubKey( SECKEYPublicKey* aPubKey ) throw( Exception , RuntimeException ) {
352*cdf0e10cSrcweir     SECKEYPublicKey*    pubkey ;
353*cdf0e10cSrcweir     std::list< SECKEYPublicKey* >::iterator keyIt ;
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir     if( aPubKey != NULL ) {
356*cdf0e10cSrcweir         //First try to find the key in the list
357*cdf0e10cSrcweir         for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
358*cdf0e10cSrcweir             if( *keyIt == aPubKey )
359*cdf0e10cSrcweir                 return ;
360*cdf0e10cSrcweir         }
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir         //If we do not find the key in the list, add a new node
363*cdf0e10cSrcweir         pubkey = SECKEY_CopyPublicKey( aPubKey ) ;
364*cdf0e10cSrcweir         if( pubkey == NULL )
365*cdf0e10cSrcweir             throw RuntimeException() ;
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir         try {
368*cdf0e10cSrcweir             m_tPubKeyList.push_back( pubkey ) ;
369*cdf0e10cSrcweir         } catch ( Exception& ) {
370*cdf0e10cSrcweir             SECKEY_DestroyPublicKey( pubkey ) ;
371*cdf0e10cSrcweir         }
372*cdf0e10cSrcweir     }
373*cdf0e10cSrcweir }
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir void SecurityEnvironment_NssImpl :: rejectPubKey( SECKEYPublicKey* aPubKey ) throw( Exception , RuntimeException ) {
376*cdf0e10cSrcweir     SECKEYPublicKey*    pubkey ;
377*cdf0e10cSrcweir     std::list< SECKEYPublicKey* >::iterator keyIt ;
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir     if( aPubKey != NULL ) {
380*cdf0e10cSrcweir         for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
381*cdf0e10cSrcweir             if( *keyIt == aPubKey ) {
382*cdf0e10cSrcweir                 pubkey = *keyIt ;
383*cdf0e10cSrcweir                 SECKEY_DestroyPublicKey( pubkey ) ;
384*cdf0e10cSrcweir                 m_tPubKeyList.erase( keyIt ) ;
385*cdf0e10cSrcweir                 break ;
386*cdf0e10cSrcweir             }
387*cdf0e10cSrcweir         }
388*cdf0e10cSrcweir     }
389*cdf0e10cSrcweir }
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir SECKEYPublicKey* SecurityEnvironment_NssImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) {
392*cdf0e10cSrcweir     SECKEYPublicKey* pubkey ;
393*cdf0e10cSrcweir     std::list< SECKEYPublicKey* >::iterator keyIt ;
394*cdf0e10cSrcweir     unsigned int pos ;
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir     pubkey = NULL ;
397*cdf0e10cSrcweir     for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; pos ++ , keyIt ++ ) ;
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir     if( pos == position && keyIt != m_tPubKeyList.end() )
400*cdf0e10cSrcweir         pubkey = *keyIt ;
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir     return pubkey ;
403*cdf0e10cSrcweir }
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir void SecurityEnvironment_NssImpl :: adoptPriKey( SECKEYPrivateKey* aPriKey ) throw( Exception , RuntimeException ) {
406*cdf0e10cSrcweir     SECKEYPrivateKey*   prikey ;
407*cdf0e10cSrcweir     std::list< SECKEYPrivateKey* >::iterator keyIt ;
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir     if( aPriKey != NULL ) {
410*cdf0e10cSrcweir         //First try to find the key in the list
411*cdf0e10cSrcweir         for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
412*cdf0e10cSrcweir             if( *keyIt == aPriKey )
413*cdf0e10cSrcweir                 return ;
414*cdf0e10cSrcweir         }
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir         //If we do not find the key in the list, add a new node
417*cdf0e10cSrcweir         prikey = SECKEY_CopyPrivateKey( aPriKey ) ;
418*cdf0e10cSrcweir         if( prikey == NULL )
419*cdf0e10cSrcweir             throw RuntimeException() ;
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir         try {
422*cdf0e10cSrcweir             m_tPriKeyList.push_back( prikey ) ;
423*cdf0e10cSrcweir         } catch ( Exception& ) {
424*cdf0e10cSrcweir             SECKEY_DestroyPrivateKey( prikey ) ;
425*cdf0e10cSrcweir         }
426*cdf0e10cSrcweir     }
427*cdf0e10cSrcweir }
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir void SecurityEnvironment_NssImpl :: rejectPriKey( SECKEYPrivateKey* aPriKey ) throw( Exception , RuntimeException ) {
430*cdf0e10cSrcweir     SECKEYPrivateKey*   prikey ;
431*cdf0e10cSrcweir     std::list< SECKEYPrivateKey* >::iterator keyIt ;
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir     if( aPriKey != NULL ) {
434*cdf0e10cSrcweir         for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
435*cdf0e10cSrcweir             if( *keyIt == aPriKey ) {
436*cdf0e10cSrcweir                 prikey = *keyIt ;
437*cdf0e10cSrcweir                 SECKEY_DestroyPrivateKey( prikey ) ;
438*cdf0e10cSrcweir                 m_tPriKeyList.erase( keyIt ) ;
439*cdf0e10cSrcweir                 break ;
440*cdf0e10cSrcweir             }
441*cdf0e10cSrcweir         }
442*cdf0e10cSrcweir     }
443*cdf0e10cSrcweir }
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir SECKEYPrivateKey* SecurityEnvironment_NssImpl :: getPriKey( unsigned int position ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException )  {
446*cdf0e10cSrcweir     SECKEYPrivateKey* prikey ;
447*cdf0e10cSrcweir     std::list< SECKEYPrivateKey* >::iterator keyIt ;
448*cdf0e10cSrcweir     unsigned int pos ;
449*cdf0e10cSrcweir 
450*cdf0e10cSrcweir     prikey = NULL ;
451*cdf0e10cSrcweir     for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; pos ++ , keyIt ++ ) ;
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir     if( pos == position && keyIt != m_tPriKeyList.end() )
454*cdf0e10cSrcweir         prikey = *keyIt ;
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir     return prikey ;
457*cdf0e10cSrcweir }
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir void SecurityEnvironment_NssImpl::updateSlots()
460*cdf0e10cSrcweir {
461*cdf0e10cSrcweir     //In case new tokens are present then we can obtain the corresponding slot
462*cdf0e10cSrcweir     PK11SlotList * soltList = NULL;
463*cdf0e10cSrcweir     PK11SlotListElement * soltEle = NULL;
464*cdf0e10cSrcweir     PK11SlotInfo * pSlot = NULL;
465*cdf0e10cSrcweir     PK11SymKey * pSymKey = NULL;
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir     osl::MutexGuard guard(m_mutex);
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir     m_Slots.clear();
470*cdf0e10cSrcweir     m_tSymKeyList.clear();
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir     soltList = PK11_GetAllTokens( CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL ) ;
473*cdf0e10cSrcweir     if( soltList != NULL )
474*cdf0e10cSrcweir     {
475*cdf0e10cSrcweir         for( soltEle = soltList->head ; soltEle != NULL; soltEle = soltEle->next )
476*cdf0e10cSrcweir         {
477*cdf0e10cSrcweir             pSlot = soltEle->slot ;
478*cdf0e10cSrcweir 
479*cdf0e10cSrcweir             if(pSlot != NULL)
480*cdf0e10cSrcweir             {
481*cdf0e10cSrcweir                 RTL_LOGFILE_TRACE2( "XMLSEC: Found a slot: SlotName=%s, TokenName=%s", PK11_GetSlotName(pSlot), PK11_GetTokenName(pSlot) );
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir //The following code which is commented out checks if a slot, that is a smart card for example, is
484*cdf0e10cSrcweir //              able to generate a symmetric key of type CKM_DES3_CBC. If this fails then this token
485*cdf0e10cSrcweir //              will not be used. This key is possibly used for the encryption service. However, all
486*cdf0e10cSrcweir //              interfaces and services used for public key signature and encryption are not published
487*cdf0e10cSrcweir //              and the encryption is not used in OOo. Therefore it does not do any harm to remove
488*cdf0e10cSrcweir //              this code, hence allowing smart cards which cannot generate this type of key.
489*cdf0e10cSrcweir //
490*cdf0e10cSrcweir //              By doing this, the encryption may fail if a smart card is being used which does not
491*cdf0e10cSrcweir //              support this key generation.
492*cdf0e10cSrcweir //
493*cdf0e10cSrcweir                 pSymKey = PK11_KeyGen( pSlot , CKM_DES3_CBC, NULL, 128, NULL ) ;
494*cdf0e10cSrcweir //              if( pSymKey == NULL )
495*cdf0e10cSrcweir //              {
496*cdf0e10cSrcweir //                  PK11_FreeSlot( pSlot ) ;
497*cdf0e10cSrcweir //                  RTL_LOGFILE_TRACE( "XMLSEC: Error - pSymKey is NULL" );
498*cdf0e10cSrcweir //                  continue;
499*cdf0e10cSrcweir //              }
500*cdf0e10cSrcweir                 addCryptoSlot(pSlot);
501*cdf0e10cSrcweir                 PK11_FreeSlot( pSlot ) ;
502*cdf0e10cSrcweir                 pSlot = NULL;
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir                 if (pSymKey != NULL)
505*cdf0e10cSrcweir                 {
506*cdf0e10cSrcweir                     adoptSymKey( pSymKey ) ;
507*cdf0e10cSrcweir                     PK11_FreeSymKey( pSymKey ) ;
508*cdf0e10cSrcweir                     pSymKey = NULL;
509*cdf0e10cSrcweir                 }
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir             }// end of if(pSlot != NULL)
512*cdf0e10cSrcweir         }// end of for
513*cdf0e10cSrcweir     }// end of if( soltList != NULL )
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir }
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir Sequence< Reference < XCertificate > >
519*cdf0e10cSrcweir SecurityEnvironment_NssImpl::getPersonalCertificates() throw( SecurityException , RuntimeException )
520*cdf0e10cSrcweir {
521*cdf0e10cSrcweir     sal_Int32 length ;
522*cdf0e10cSrcweir     X509Certificate_NssImpl* xcert ;
523*cdf0e10cSrcweir     std::list< X509Certificate_NssImpl* > certsList ;
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir     updateSlots();
526*cdf0e10cSrcweir     //firstly, we try to find private keys in slot
527*cdf0e10cSrcweir     for (CIT_SLOTS is = m_Slots.begin(); is != m_Slots.end(); is++)
528*cdf0e10cSrcweir     {
529*cdf0e10cSrcweir         PK11SlotInfo *slot = *is;
530*cdf0e10cSrcweir         SECKEYPrivateKeyList* priKeyList ;
531*cdf0e10cSrcweir         SECKEYPrivateKeyListNode* curPri ;
532*cdf0e10cSrcweir 
533*cdf0e10cSrcweir         if( PK11_NeedLogin(slot ) ) {
534*cdf0e10cSrcweir             SECStatus nRet = PK11_Authenticate(slot, PR_TRUE, NULL);
535*cdf0e10cSrcweir             //PK11_Authenticate may fail in case the a slot has not been initialized.
536*cdf0e10cSrcweir             //this is the case if the user has a new profile, so that they have never
537*cdf0e10cSrcweir             //added a personal certificate.
538*cdf0e10cSrcweir             if( nRet != SECSuccess && PORT_GetError() != SEC_ERROR_IO) {
539*cdf0e10cSrcweir                 throw NoPasswordException();
540*cdf0e10cSrcweir             }
541*cdf0e10cSrcweir         }
542*cdf0e10cSrcweir 
543*cdf0e10cSrcweir         priKeyList = PK11_ListPrivateKeysInSlot(slot) ;
544*cdf0e10cSrcweir         if( priKeyList != NULL ) {
545*cdf0e10cSrcweir             for( curPri = PRIVKEY_LIST_HEAD( priKeyList );
546*cdf0e10cSrcweir                 !PRIVKEY_LIST_END( curPri, priKeyList ) && curPri != NULL ;
547*cdf0e10cSrcweir                 curPri = PRIVKEY_LIST_NEXT( curPri ) ) {
548*cdf0e10cSrcweir                 xcert = NssPrivKeyToXCert( curPri->key ) ;
549*cdf0e10cSrcweir                 if( xcert != NULL )
550*cdf0e10cSrcweir                     certsList.push_back( xcert ) ;
551*cdf0e10cSrcweir             }
552*cdf0e10cSrcweir         }
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir         SECKEY_DestroyPrivateKeyList( priKeyList ) ;
555*cdf0e10cSrcweir     }
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir     //secondly, we try to find certificate from registered private keys.
558*cdf0e10cSrcweir     if( !m_tPriKeyList.empty()  ) {
559*cdf0e10cSrcweir         std::list< SECKEYPrivateKey* >::iterator priKeyIt ;
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir         for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; priKeyIt ++ ) {
562*cdf0e10cSrcweir             xcert = NssPrivKeyToXCert( *priKeyIt ) ;
563*cdf0e10cSrcweir             if( xcert != NULL )
564*cdf0e10cSrcweir                 certsList.push_back( xcert ) ;
565*cdf0e10cSrcweir         }
566*cdf0e10cSrcweir     }
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir     length = certsList.size() ;
569*cdf0e10cSrcweir     if( length != 0 ) {
570*cdf0e10cSrcweir         int i ;
571*cdf0e10cSrcweir         std::list< X509Certificate_NssImpl* >::iterator xcertIt ;
572*cdf0e10cSrcweir         Sequence< Reference< XCertificate > > certSeq( length ) ;
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir         for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); xcertIt ++, i++ ) {
575*cdf0e10cSrcweir             certSeq[i] = *xcertIt ;
576*cdf0e10cSrcweir         }
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir         return certSeq ;
579*cdf0e10cSrcweir     }
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir     return Sequence< Reference < XCertificate > > ();
582*cdf0e10cSrcweir }
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir Reference< XCertificate > SecurityEnvironment_NssImpl :: getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& serialNumber ) throw( SecurityException , RuntimeException )
585*cdf0e10cSrcweir {
586*cdf0e10cSrcweir     X509Certificate_NssImpl* xcert = NULL;
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir     if( m_pHandler != NULL ) {
589*cdf0e10cSrcweir         CERTIssuerAndSN issuerAndSN ;
590*cdf0e10cSrcweir         CERTCertificate* cert ;
591*cdf0e10cSrcweir         CERTName* nmIssuer ;
592*cdf0e10cSrcweir         char* chIssuer ;
593*cdf0e10cSrcweir         SECItem* derIssuer ;
594*cdf0e10cSrcweir         PRArenaPool* arena ;
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir         arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ) ;
597*cdf0e10cSrcweir         if( arena == NULL )
598*cdf0e10cSrcweir             throw RuntimeException() ;
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir                 /*
601*cdf0e10cSrcweir                  * mmi : because MS Crypto use the 'S' tag (equal to the 'ST' tag in NSS), but the NSS can't recognise
602*cdf0e10cSrcweir                  *      it, so the 'S' tag should be changed to 'ST' tag
603*cdf0e10cSrcweir                  *
604*cdf0e10cSrcweir                  * PS  : it can work, but inside libxmlsec, the 'S' tag is till used to find cert in NSS engine, so it
605*cdf0e10cSrcweir                  *       is not useful at all. (comment out now)
606*cdf0e10cSrcweir                  */
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir                 /*
609*cdf0e10cSrcweir                 sal_Int32 nIndex = 0;
610*cdf0e10cSrcweir                 OUString newIssuerName;
611*cdf0e10cSrcweir                 do
612*cdf0e10cSrcweir                 {
613*cdf0e10cSrcweir                     OUString aToken = issuerName.getToken( 0, ',', nIndex ).trim();
614*cdf0e10cSrcweir                     if (aToken.compareToAscii("S=",2) == 0)
615*cdf0e10cSrcweir                     {
616*cdf0e10cSrcweir                         newIssuerName+=OUString::createFromAscii("ST=");
617*cdf0e10cSrcweir                         newIssuerName+=aToken.copy(2);
618*cdf0e10cSrcweir                     }
619*cdf0e10cSrcweir                     else
620*cdf0e10cSrcweir                     {
621*cdf0e10cSrcweir                         newIssuerName+=aToken;
622*cdf0e10cSrcweir                     }
623*cdf0e10cSrcweir 
624*cdf0e10cSrcweir                     if (nIndex >= 0)
625*cdf0e10cSrcweir                     {
626*cdf0e10cSrcweir                         newIssuerName+=OUString::createFromAscii(",");
627*cdf0e10cSrcweir                     }
628*cdf0e10cSrcweir                 } while ( nIndex >= 0 );
629*cdf0e10cSrcweir                 */
630*cdf0e10cSrcweir 
631*cdf0e10cSrcweir                 /* end */
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir         //Create cert info from issue and serial
634*cdf0e10cSrcweir         rtl::OString ostr = rtl::OUStringToOString( issuerName , RTL_TEXTENCODING_UTF8 ) ;
635*cdf0e10cSrcweir         chIssuer = PL_strndup( ( char* )ostr.getStr(), ( int )ostr.getLength() ) ;
636*cdf0e10cSrcweir         nmIssuer = CERT_AsciiToName( chIssuer ) ;
637*cdf0e10cSrcweir         if( nmIssuer == NULL ) {
638*cdf0e10cSrcweir             PL_strfree( chIssuer ) ;
639*cdf0e10cSrcweir             PORT_FreeArena( arena, PR_FALSE ) ;
640*cdf0e10cSrcweir 
641*cdf0e10cSrcweir             /*
642*cdf0e10cSrcweir              * i40394
643*cdf0e10cSrcweir              *
644*cdf0e10cSrcweir              * mmi : no need to throw exception
645*cdf0e10cSrcweir              *       just return "no found"
646*cdf0e10cSrcweir              */
647*cdf0e10cSrcweir             //throw RuntimeException() ;
648*cdf0e10cSrcweir             return NULL;
649*cdf0e10cSrcweir         }
650*cdf0e10cSrcweir 
651*cdf0e10cSrcweir         derIssuer = SEC_ASN1EncodeItem( arena, NULL, ( void* )nmIssuer, SEC_ASN1_GET( CERT_NameTemplate ) ) ;
652*cdf0e10cSrcweir         if( derIssuer == NULL ) {
653*cdf0e10cSrcweir             PL_strfree( chIssuer ) ;
654*cdf0e10cSrcweir             CERT_DestroyName( nmIssuer ) ;
655*cdf0e10cSrcweir             PORT_FreeArena( arena, PR_FALSE ) ;
656*cdf0e10cSrcweir             throw RuntimeException() ;
657*cdf0e10cSrcweir         }
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir         memset( &issuerAndSN, 0, sizeof( issuerAndSN ) ) ;
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir         issuerAndSN.derIssuer.data = derIssuer->data ;
662*cdf0e10cSrcweir         issuerAndSN.derIssuer.len = derIssuer->len ;
663*cdf0e10cSrcweir 
664*cdf0e10cSrcweir         issuerAndSN.serialNumber.data = ( unsigned char* )&serialNumber[0] ;
665*cdf0e10cSrcweir         issuerAndSN.serialNumber.len = serialNumber.getLength() ;
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir         cert = CERT_FindCertByIssuerAndSN( m_pHandler, &issuerAndSN ) ;
668*cdf0e10cSrcweir         if( cert != NULL ) {
669*cdf0e10cSrcweir             xcert = NssCertToXCert( cert ) ;
670*cdf0e10cSrcweir         } else {
671*cdf0e10cSrcweir             xcert = NULL ;
672*cdf0e10cSrcweir         }
673*cdf0e10cSrcweir 
674*cdf0e10cSrcweir         PL_strfree( chIssuer ) ;
675*cdf0e10cSrcweir         CERT_DestroyName( nmIssuer ) ;
676*cdf0e10cSrcweir         //SECITEM_FreeItem( derIssuer, PR_FALSE ) ;
677*cdf0e10cSrcweir         CERT_DestroyCertificate( cert ) ;
678*cdf0e10cSrcweir         PORT_FreeArena( arena, PR_FALSE ) ;
679*cdf0e10cSrcweir     } else {
680*cdf0e10cSrcweir         xcert = NULL ;
681*cdf0e10cSrcweir     }
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir     return xcert ;
684*cdf0e10cSrcweir }
685*cdf0e10cSrcweir 
686*cdf0e10cSrcweir Reference< XCertificate > SecurityEnvironment_NssImpl :: getCertificate( const OUString& issuerName, const OUString& serialNumber ) throw( SecurityException , RuntimeException ) {
687*cdf0e10cSrcweir     Sequence< sal_Int8 > serial = numericStringToBigInteger( serialNumber ) ;
688*cdf0e10cSrcweir     return getCertificate( issuerName, serial ) ;
689*cdf0e10cSrcweir }
690*cdf0e10cSrcweir 
691*cdf0e10cSrcweir Sequence< Reference < XCertificate > > SecurityEnvironment_NssImpl :: buildCertificatePath( const Reference< XCertificate >& begin ) throw( SecurityException , RuntimeException ) {
692*cdf0e10cSrcweir     const X509Certificate_NssImpl* xcert ;
693*cdf0e10cSrcweir     const CERTCertificate* cert ;
694*cdf0e10cSrcweir     CERTCertList* certChain ;
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir     Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ;
697*cdf0e10cSrcweir     if( !xCertTunnel.is() ) {
698*cdf0e10cSrcweir         throw RuntimeException() ;
699*cdf0e10cSrcweir     }
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir     xcert = reinterpret_cast<X509Certificate_NssImpl*>(
702*cdf0e10cSrcweir         sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething( X509Certificate_NssImpl::getUnoTunnelId() ))) ;
703*cdf0e10cSrcweir     if( xcert == NULL ) {
704*cdf0e10cSrcweir         throw RuntimeException() ;
705*cdf0e10cSrcweir     }
706*cdf0e10cSrcweir 
707*cdf0e10cSrcweir     cert = xcert->getNssCert() ;
708*cdf0e10cSrcweir     if( cert != NULL ) {
709*cdf0e10cSrcweir         int64 timeboundary ;
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir         //Get the system clock time
712*cdf0e10cSrcweir         timeboundary = PR_Now() ;
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir         certChain = CERT_GetCertChainFromCert( ( CERTCertificate* )cert, timeboundary, certUsageAnyCA ) ;
715*cdf0e10cSrcweir     } else {
716*cdf0e10cSrcweir         certChain = NULL ;
717*cdf0e10cSrcweir     }
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir     if( certChain != NULL ) {
720*cdf0e10cSrcweir         X509Certificate_NssImpl* pCert ;
721*cdf0e10cSrcweir         CERTCertListNode* node ;
722*cdf0e10cSrcweir         int len ;
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir         for( len = 0, node = CERT_LIST_HEAD( certChain ); !CERT_LIST_END( node, certChain ); node = CERT_LIST_NEXT( node ), len ++ ) ;
725*cdf0e10cSrcweir         Sequence< Reference< XCertificate > > xCertChain( len ) ;
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir         for( len = 0, node = CERT_LIST_HEAD( certChain ); !CERT_LIST_END( node, certChain ); node = CERT_LIST_NEXT( node ), len ++ ) {
728*cdf0e10cSrcweir             pCert = new X509Certificate_NssImpl() ;
729*cdf0e10cSrcweir             if( pCert == NULL ) {
730*cdf0e10cSrcweir                 CERT_DestroyCertList( certChain ) ;
731*cdf0e10cSrcweir                 throw RuntimeException() ;
732*cdf0e10cSrcweir             }
733*cdf0e10cSrcweir 
734*cdf0e10cSrcweir             pCert->setCert( node->cert ) ;
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir             xCertChain[len] = pCert ;
737*cdf0e10cSrcweir         }
738*cdf0e10cSrcweir 
739*cdf0e10cSrcweir         CERT_DestroyCertList( certChain ) ;
740*cdf0e10cSrcweir 
741*cdf0e10cSrcweir         return xCertChain ;
742*cdf0e10cSrcweir     }
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir     return Sequence< Reference < XCertificate > >();
745*cdf0e10cSrcweir }
746*cdf0e10cSrcweir 
747*cdf0e10cSrcweir Reference< XCertificate > SecurityEnvironment_NssImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) {
748*cdf0e10cSrcweir     X509Certificate_NssImpl* xcert ;
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir     if( rawCertificate.getLength() > 0 ) {
751*cdf0e10cSrcweir         xcert = new X509Certificate_NssImpl() ;
752*cdf0e10cSrcweir         if( xcert == NULL )
753*cdf0e10cSrcweir             throw RuntimeException() ;
754*cdf0e10cSrcweir 
755*cdf0e10cSrcweir         xcert->setRawCert( rawCertificate ) ;
756*cdf0e10cSrcweir     } else {
757*cdf0e10cSrcweir         xcert = NULL ;
758*cdf0e10cSrcweir     }
759*cdf0e10cSrcweir 
760*cdf0e10cSrcweir     return xcert ;
761*cdf0e10cSrcweir }
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir Reference< XCertificate > SecurityEnvironment_NssImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) {
764*cdf0e10cSrcweir     xmlChar* chCert ;
765*cdf0e10cSrcweir     xmlSecSize certSize ;
766*cdf0e10cSrcweir 
767*cdf0e10cSrcweir     rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ;
768*cdf0e10cSrcweir 
769*cdf0e10cSrcweir     chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ;
770*cdf0e10cSrcweir 
771*cdf0e10cSrcweir     certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ;
772*cdf0e10cSrcweir 
773*cdf0e10cSrcweir     Sequence< sal_Int8 > rawCert( certSize ) ;
774*cdf0e10cSrcweir     for( unsigned int i = 0 ; i < certSize ; i ++ )
775*cdf0e10cSrcweir         rawCert[i] = *( chCert + i ) ;
776*cdf0e10cSrcweir 
777*cdf0e10cSrcweir     xmlFree( chCert ) ;
778*cdf0e10cSrcweir 
779*cdf0e10cSrcweir     return createCertificateFromRaw( rawCert ) ;
780*cdf0e10cSrcweir }
781*cdf0e10cSrcweir 
782*cdf0e10cSrcweir sal_Int32 SecurityEnvironment_NssImpl ::
783*cdf0e10cSrcweir verifyCertificate( const Reference< csss::XCertificate >& aCert,
784*cdf0e10cSrcweir                    const Sequence< Reference< csss::XCertificate > >&  intermediateCerts )
785*cdf0e10cSrcweir     throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException )
786*cdf0e10cSrcweir {
787*cdf0e10cSrcweir     sal_Int32 validity = csss::CertificateValidity::INVALID;
788*cdf0e10cSrcweir     const X509Certificate_NssImpl* xcert ;
789*cdf0e10cSrcweir     const CERTCertificate* cert ;
790*cdf0e10cSrcweir     ::std::vector<CERTCertificate*> vecTmpNSSCertificates;
791*cdf0e10cSrcweir     Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
792*cdf0e10cSrcweir     if( !xCertTunnel.is() ) {
793*cdf0e10cSrcweir         throw RuntimeException() ;
794*cdf0e10cSrcweir     }
795*cdf0e10cSrcweir 
796*cdf0e10cSrcweir     xmlsec_trace("Start verification of certificate: \n %s \n",
797*cdf0e10cSrcweir               OUStringToOString(
798*cdf0e10cSrcweir                   aCert->getSubjectName(), osl_getThreadTextEncoding()).getStr());
799*cdf0e10cSrcweir 
800*cdf0e10cSrcweir     xcert = reinterpret_cast<X509Certificate_NssImpl*>(
801*cdf0e10cSrcweir        sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething( X509Certificate_NssImpl::getUnoTunnelId() ))) ;
802*cdf0e10cSrcweir     if( xcert == NULL ) {
803*cdf0e10cSrcweir         throw RuntimeException() ;
804*cdf0e10cSrcweir     }
805*cdf0e10cSrcweir 
806*cdf0e10cSrcweir     //CERT_PKIXVerifyCert does not take a db as argument. It will therefore
807*cdf0e10cSrcweir     //internally use CERT_GetDefaultCertDB
808*cdf0e10cSrcweir     //Make sure m_pHandler is the default DB
809*cdf0e10cSrcweir     OSL_ASSERT(m_pHandler == CERT_GetDefaultCertDB());
810*cdf0e10cSrcweir     CERTCertDBHandle * certDb = m_pHandler != NULL ? m_pHandler : CERT_GetDefaultCertDB();
811*cdf0e10cSrcweir     cert = xcert->getNssCert() ;
812*cdf0e10cSrcweir     if( cert != NULL )
813*cdf0e10cSrcweir     {
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir         //prepare the intermediate certificates
816*cdf0e10cSrcweir         for (sal_Int32 i = 0; i < intermediateCerts.getLength(); i++)
817*cdf0e10cSrcweir         {
818*cdf0e10cSrcweir             Sequence<sal_Int8> der = intermediateCerts[i]->getEncoded();
819*cdf0e10cSrcweir             SECItem item;
820*cdf0e10cSrcweir             item.type = siBuffer;
821*cdf0e10cSrcweir             item.data = (unsigned char*)der.getArray();
822*cdf0e10cSrcweir             item.len = der.getLength();
823*cdf0e10cSrcweir 
824*cdf0e10cSrcweir             CERTCertificate* certTmp = CERT_NewTempCertificate(certDb, &item,
825*cdf0e10cSrcweir                                            NULL     /* nickname */,
826*cdf0e10cSrcweir                                            PR_FALSE /* isPerm */,
827*cdf0e10cSrcweir                                            PR_TRUE  /* copyDER */);
828*cdf0e10cSrcweir              if (!certTmp)
829*cdf0e10cSrcweir              {
830*cdf0e10cSrcweir                  xmlsec_trace("Failed to add a temporary certificate: %s",
831*cdf0e10cSrcweir                            OUStringToOString(intermediateCerts[i]->getIssuerName(),
832*cdf0e10cSrcweir                                              osl_getThreadTextEncoding()).getStr());
833*cdf0e10cSrcweir 
834*cdf0e10cSrcweir              }
835*cdf0e10cSrcweir              else
836*cdf0e10cSrcweir              {
837*cdf0e10cSrcweir                  xmlsec_trace("Added temporary certificate: %s",
838*cdf0e10cSrcweir                            certTmp->subjectName ? certTmp->subjectName : "");
839*cdf0e10cSrcweir                  vecTmpNSSCertificates.push_back(certTmp);
840*cdf0e10cSrcweir              }
841*cdf0e10cSrcweir         }
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir         SECStatus status ;
845*cdf0e10cSrcweir 
846*cdf0e10cSrcweir         CERTVerifyLog log;
847*cdf0e10cSrcweir         log.arena = PORT_NewArena(512);
848*cdf0e10cSrcweir         log.head = log.tail = NULL;
849*cdf0e10cSrcweir         log.count = 0;
850*cdf0e10cSrcweir 
851*cdf0e10cSrcweir         CERT_EnableOCSPChecking(certDb);
852*cdf0e10cSrcweir         CERT_DisableOCSPDefaultResponder(certDb);
853*cdf0e10cSrcweir         CERTValOutParam cvout[5];
854*cdf0e10cSrcweir         CERTValInParam cvin[3];
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir         cvin[0].type = cert_pi_useAIACertFetch;
857*cdf0e10cSrcweir         cvin[0].value.scalar.b = PR_TRUE;
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir         PRUint64 revFlagsLeaf[2];
860*cdf0e10cSrcweir         PRUint64 revFlagsChain[2];
861*cdf0e10cSrcweir         CERTRevocationFlags rev;
862*cdf0e10cSrcweir         rev.leafTests.number_of_defined_methods = 2;
863*cdf0e10cSrcweir         rev.leafTests.cert_rev_flags_per_method = revFlagsLeaf;
864*cdf0e10cSrcweir         //the flags are defined in cert.h
865*cdf0e10cSrcweir         //We check both leaf and chain.
866*cdf0e10cSrcweir         //It is enough if one revocation method has fresh info,
867*cdf0e10cSrcweir         //but at least one must have some. Otherwise validation fails.
868*cdf0e10cSrcweir         //!!! using leaf test and CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE
869*cdf0e10cSrcweir         // when validating a root certificate will result in "revoked". Usually
870*cdf0e10cSrcweir         //there is no revocation information available for the root cert because
871*cdf0e10cSrcweir         //it must be trusted anyway and it does itself issue revocation information.
872*cdf0e10cSrcweir         //When we use the flag here and OOo shows the certification path then the root
873*cdf0e10cSrcweir         //cert is invalid while all other can be valid. It would probably best if
874*cdf0e10cSrcweir         //this interface method returned the whole chain.
875*cdf0e10cSrcweir         //Otherwise we need to check if the certificate is self-signed and if it is
876*cdf0e10cSrcweir         //then not use the flag when doing the leaf-test.
877*cdf0e10cSrcweir         rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] =
878*cdf0e10cSrcweir             CERT_REV_M_TEST_USING_THIS_METHOD
879*cdf0e10cSrcweir             | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE;
880*cdf0e10cSrcweir         rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] =
881*cdf0e10cSrcweir             CERT_REV_M_TEST_USING_THIS_METHOD
882*cdf0e10cSrcweir             | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE;
883*cdf0e10cSrcweir         rev.leafTests.number_of_preferred_methods = 0;
884*cdf0e10cSrcweir         rev.leafTests.preferred_methods = NULL;
885*cdf0e10cSrcweir         rev.leafTests.cert_rev_method_independent_flags =
886*cdf0e10cSrcweir             CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST;
887*cdf0e10cSrcweir //            | CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE;
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir         rev.chainTests.number_of_defined_methods = 2;
890*cdf0e10cSrcweir         rev.chainTests.cert_rev_flags_per_method = revFlagsChain;
891*cdf0e10cSrcweir         rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] =
892*cdf0e10cSrcweir             CERT_REV_M_TEST_USING_THIS_METHOD
893*cdf0e10cSrcweir             | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE;
894*cdf0e10cSrcweir         rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] =
895*cdf0e10cSrcweir             CERT_REV_M_TEST_USING_THIS_METHOD
896*cdf0e10cSrcweir             | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE;
897*cdf0e10cSrcweir         rev.chainTests.number_of_preferred_methods = 0;
898*cdf0e10cSrcweir         rev.chainTests.preferred_methods = NULL;
899*cdf0e10cSrcweir         rev.chainTests.cert_rev_method_independent_flags =
900*cdf0e10cSrcweir             CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST;
901*cdf0e10cSrcweir //            | CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE;
902*cdf0e10cSrcweir 
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir         cvin[1].type = cert_pi_revocationFlags;
905*cdf0e10cSrcweir         cvin[1].value.pointer.revocation = &rev;
906*cdf0e10cSrcweir         // does not work, not implemented yet in 3.12.4
907*cdf0e10cSrcweir //         cvin[2].type = cert_pi_keyusage;
908*cdf0e10cSrcweir //         cvin[2].value.scalar.ui = KU_DIGITAL_SIGNATURE;
909*cdf0e10cSrcweir         cvin[2].type = cert_pi_end;
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir         cvout[0].type = cert_po_trustAnchor;
912*cdf0e10cSrcweir         cvout[0].value.pointer.cert = NULL;
913*cdf0e10cSrcweir         cvout[1].type = cert_po_errorLog;
914*cdf0e10cSrcweir         cvout[1].value.pointer.log = &log;
915*cdf0e10cSrcweir         cvout[2].type = cert_po_end;
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir         // We check SSL server certificates, CA certificates and signing sertificates.
918*cdf0e10cSrcweir         //
919*cdf0e10cSrcweir         // ToDo check keyusage, looking at CERT_KeyUsageAndTypeForCertUsage (
920*cdf0e10cSrcweir         // mozilla/security/nss/lib/certdb/certdb.c indicates that
921*cdf0e10cSrcweir         // certificateUsageSSLClient, certificateUsageSSLServer and certificateUsageSSLCA
922*cdf0e10cSrcweir         // are sufficient. They cover the key usages for digital signature, key agreement
923*cdf0e10cSrcweir         // and encipherment and certificate signature
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir         //never use the following usages because they are not checked properly
926*cdf0e10cSrcweir         // certificateUsageUserCertImport
927*cdf0e10cSrcweir         // certificateUsageVerifyCA
928*cdf0e10cSrcweir         // certificateUsageAnyCA
929*cdf0e10cSrcweir         // certificateUsageProtectedObjectSigner
930*cdf0e10cSrcweir 
931*cdf0e10cSrcweir         UsageDescription arUsages[5];
932*cdf0e10cSrcweir         arUsages[0] = UsageDescription( certificateUsageSSLClient, "certificateUsageSSLClient"  );
933*cdf0e10cSrcweir         arUsages[1] = UsageDescription( certificateUsageSSLServer, "certificateUsageSSLServer"  );
934*cdf0e10cSrcweir         arUsages[2] = UsageDescription( certificateUsageSSLCA, "certificateUsageSSLCA"  );
935*cdf0e10cSrcweir         arUsages[3] = UsageDescription( certificateUsageEmailSigner, "certificateUsageEmailSigner" );
936*cdf0e10cSrcweir         arUsages[4] = UsageDescription( certificateUsageEmailRecipient, "certificateUsageEmailRecipient" );
937*cdf0e10cSrcweir 
938*cdf0e10cSrcweir         int numUsages = sizeof(arUsages) / sizeof(UsageDescription);
939*cdf0e10cSrcweir         for (int i = 0; i < numUsages; i++)
940*cdf0e10cSrcweir         {
941*cdf0e10cSrcweir             xmlsec_trace("Testing usage %d of %d: %s (0x%x)", i + 1,
942*cdf0e10cSrcweir                       numUsages, arUsages[i].description, (int) arUsages[i].usage);
943*cdf0e10cSrcweir 
944*cdf0e10cSrcweir             status = CERT_PKIXVerifyCert(const_cast<CERTCertificate *>(cert), arUsages[i].usage,
945*cdf0e10cSrcweir                                          cvin, cvout, NULL);
946*cdf0e10cSrcweir             if( status == SECSuccess )
947*cdf0e10cSrcweir             {
948*cdf0e10cSrcweir                 xmlsec_trace("CERT_PKIXVerifyCert returned SECSuccess.");
949*cdf0e10cSrcweir                 //When an intermediate or root certificate is checked then we expect the usage
950*cdf0e10cSrcweir                 //certificateUsageSSLCA. This, however, will be only set when in the trust settings dialog
951*cdf0e10cSrcweir                 //the button "This certificate can identify websites" is checked. If for example only
952*cdf0e10cSrcweir                 //"This certificate can identify mail users" is set then the end certificate can
953*cdf0e10cSrcweir                 //be validated and the returned usage will conain certificateUsageEmailRecipient.
954*cdf0e10cSrcweir                 //But checking directly the root or intermediate certificate will fail. In the
955*cdf0e10cSrcweir                 //certificate path view the end certificate will be shown as valid but the others
956*cdf0e10cSrcweir                 //will be displayed as invalid.
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir                 validity = csss::CertificateValidity::VALID;
959*cdf0e10cSrcweir                 xmlsec_trace("Certificate is valid.\n");
960*cdf0e10cSrcweir                 CERTCertificate * issuerCert = cvout[0].value.pointer.cert;
961*cdf0e10cSrcweir                 if (issuerCert)
962*cdf0e10cSrcweir                 {
963*cdf0e10cSrcweir                     xmlsec_trace("Root certificate: %s", issuerCert->subjectName);
964*cdf0e10cSrcweir                     CERT_DestroyCertificate(issuerCert);
965*cdf0e10cSrcweir                 };
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir                 break;
968*cdf0e10cSrcweir             }
969*cdf0e10cSrcweir             else
970*cdf0e10cSrcweir             {
971*cdf0e10cSrcweir                 PRIntn err = PR_GetError();
972*cdf0e10cSrcweir                 xmlsec_trace("Error: , %d = %s", err, getCertError(err));
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir                 /* Display validation results */
975*cdf0e10cSrcweir                 if ( log.count > 0)
976*cdf0e10cSrcweir                 {
977*cdf0e10cSrcweir                     CERTVerifyLogNode *node = NULL;
978*cdf0e10cSrcweir                     printChainFailure(&log);
979*cdf0e10cSrcweir 
980*cdf0e10cSrcweir                     for (node = log.head; node; node = node->next) {
981*cdf0e10cSrcweir                         if (node->cert)
982*cdf0e10cSrcweir                             CERT_DestroyCertificate(node->cert);
983*cdf0e10cSrcweir                     }
984*cdf0e10cSrcweir                     log.head = log.tail = NULL;
985*cdf0e10cSrcweir                     log.count = 0;
986*cdf0e10cSrcweir                 }
987*cdf0e10cSrcweir                 xmlsec_trace("Certificate is invalid.\n");
988*cdf0e10cSrcweir             }
989*cdf0e10cSrcweir         }
990*cdf0e10cSrcweir 
991*cdf0e10cSrcweir     }
992*cdf0e10cSrcweir     else
993*cdf0e10cSrcweir     {
994*cdf0e10cSrcweir         validity = ::com::sun::star::security::CertificateValidity::INVALID ;
995*cdf0e10cSrcweir     }
996*cdf0e10cSrcweir 
997*cdf0e10cSrcweir     //Destroying the temporary certificates
998*cdf0e10cSrcweir     std::vector<CERTCertificate*>::const_iterator cert_i;
999*cdf0e10cSrcweir     for (cert_i = vecTmpNSSCertificates.begin(); cert_i != vecTmpNSSCertificates.end(); cert_i++)
1000*cdf0e10cSrcweir     {
1001*cdf0e10cSrcweir         xmlsec_trace("Destroying temporary certificate");
1002*cdf0e10cSrcweir         CERT_DestroyCertificate(*cert_i);
1003*cdf0e10cSrcweir     }
1004*cdf0e10cSrcweir     return validity ;
1005*cdf0e10cSrcweir }
1006*cdf0e10cSrcweir 
1007*cdf0e10cSrcweir sal_Int32 SecurityEnvironment_NssImpl::getCertificateCharacters(
1008*cdf0e10cSrcweir     const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& aCert ) throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) {
1009*cdf0e10cSrcweir     sal_Int32 characters ;
1010*cdf0e10cSrcweir     const X509Certificate_NssImpl* xcert ;
1011*cdf0e10cSrcweir     const CERTCertificate* cert ;
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir     Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
1014*cdf0e10cSrcweir     if( !xCertTunnel.is() ) {
1015*cdf0e10cSrcweir         throw RuntimeException() ;
1016*cdf0e10cSrcweir     }
1017*cdf0e10cSrcweir 
1018*cdf0e10cSrcweir     xcert = reinterpret_cast<X509Certificate_NssImpl*>(
1019*cdf0e10cSrcweir         sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething( X509Certificate_NssImpl::getUnoTunnelId() ))) ;
1020*cdf0e10cSrcweir     if( xcert == NULL ) {
1021*cdf0e10cSrcweir         throw RuntimeException() ;
1022*cdf0e10cSrcweir     }
1023*cdf0e10cSrcweir 
1024*cdf0e10cSrcweir     cert = xcert->getNssCert() ;
1025*cdf0e10cSrcweir 
1026*cdf0e10cSrcweir     characters = 0x00000000 ;
1027*cdf0e10cSrcweir 
1028*cdf0e10cSrcweir     //Firstly, find out whether or not the cert is self-signed.
1029*cdf0e10cSrcweir     if( SECITEM_CompareItem( &(cert->derIssuer), &(cert->derSubject) ) == SECEqual ) {
1030*cdf0e10cSrcweir         characters |= ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
1031*cdf0e10cSrcweir     } else {
1032*cdf0e10cSrcweir         characters &= ~ ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
1033*cdf0e10cSrcweir     }
1034*cdf0e10cSrcweir 
1035*cdf0e10cSrcweir     //Secondly, find out whether or not the cert has a private key.
1036*cdf0e10cSrcweir 
1037*cdf0e10cSrcweir     /*
1038*cdf0e10cSrcweir      * i40394
1039*cdf0e10cSrcweir      *
1040*cdf0e10cSrcweir      * mmi : need to check whether the cert's slot is valid first
1041*cdf0e10cSrcweir      */
1042*cdf0e10cSrcweir     SECKEYPrivateKey* priKey = NULL;
1043*cdf0e10cSrcweir 
1044*cdf0e10cSrcweir     if (cert->slot != NULL)
1045*cdf0e10cSrcweir     {
1046*cdf0e10cSrcweir         priKey = PK11_FindPrivateKeyFromCert( cert->slot, ( CERTCertificate* )cert, NULL ) ;
1047*cdf0e10cSrcweir     }
1048*cdf0e10cSrcweir     if(priKey == NULL)
1049*cdf0e10cSrcweir     {
1050*cdf0e10cSrcweir         for (CIT_SLOTS is = m_Slots.begin(); is != m_Slots.end(); is++)
1051*cdf0e10cSrcweir         {
1052*cdf0e10cSrcweir             priKey = PK11_FindPrivateKeyFromCert(*is, (CERTCertificate*)cert, NULL);
1053*cdf0e10cSrcweir             if (priKey)
1054*cdf0e10cSrcweir                 break;
1055*cdf0e10cSrcweir         }
1056*cdf0e10cSrcweir     }
1057*cdf0e10cSrcweir     if( priKey != NULL ) {
1058*cdf0e10cSrcweir         characters |=  ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir         SECKEY_DestroyPrivateKey( priKey ) ;
1061*cdf0e10cSrcweir     } else {
1062*cdf0e10cSrcweir         characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
1063*cdf0e10cSrcweir     }
1064*cdf0e10cSrcweir 
1065*cdf0e10cSrcweir     return characters ;
1066*cdf0e10cSrcweir }
1067*cdf0e10cSrcweir 
1068*cdf0e10cSrcweir X509Certificate_NssImpl* NssCertToXCert( CERTCertificate* cert )
1069*cdf0e10cSrcweir {
1070*cdf0e10cSrcweir     X509Certificate_NssImpl* xcert ;
1071*cdf0e10cSrcweir 
1072*cdf0e10cSrcweir     if( cert != NULL ) {
1073*cdf0e10cSrcweir         xcert = new X509Certificate_NssImpl() ;
1074*cdf0e10cSrcweir         if( xcert == NULL ) {
1075*cdf0e10cSrcweir             xcert = NULL ;
1076*cdf0e10cSrcweir         } else {
1077*cdf0e10cSrcweir             xcert->setCert( cert ) ;
1078*cdf0e10cSrcweir         }
1079*cdf0e10cSrcweir     } else {
1080*cdf0e10cSrcweir         xcert = NULL ;
1081*cdf0e10cSrcweir     }
1082*cdf0e10cSrcweir 
1083*cdf0e10cSrcweir     return xcert ;
1084*cdf0e10cSrcweir }
1085*cdf0e10cSrcweir 
1086*cdf0e10cSrcweir X509Certificate_NssImpl* NssPrivKeyToXCert( SECKEYPrivateKey* priKey )
1087*cdf0e10cSrcweir {
1088*cdf0e10cSrcweir     CERTCertificate* cert ;
1089*cdf0e10cSrcweir     X509Certificate_NssImpl* xcert ;
1090*cdf0e10cSrcweir 
1091*cdf0e10cSrcweir     if( priKey != NULL ) {
1092*cdf0e10cSrcweir         cert = PK11_GetCertFromPrivateKey( priKey ) ;
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir         if( cert != NULL ) {
1095*cdf0e10cSrcweir             xcert = NssCertToXCert( cert ) ;
1096*cdf0e10cSrcweir         } else {
1097*cdf0e10cSrcweir             xcert = NULL ;
1098*cdf0e10cSrcweir         }
1099*cdf0e10cSrcweir 
1100*cdf0e10cSrcweir         CERT_DestroyCertificate( cert ) ;
1101*cdf0e10cSrcweir     } else {
1102*cdf0e10cSrcweir         xcert = NULL ;
1103*cdf0e10cSrcweir     }
1104*cdf0e10cSrcweir 
1105*cdf0e10cSrcweir     return xcert ;
1106*cdf0e10cSrcweir }
1107*cdf0e10cSrcweir 
1108*cdf0e10cSrcweir 
1109*cdf0e10cSrcweir /* Native methods */
1110*cdf0e10cSrcweir xmlSecKeysMngrPtr SecurityEnvironment_NssImpl::createKeysManager() throw( Exception, RuntimeException ) {
1111*cdf0e10cSrcweir 
1112*cdf0e10cSrcweir     unsigned int i ;
1113*cdf0e10cSrcweir     CERTCertDBHandle* handler = NULL ;
1114*cdf0e10cSrcweir     PK11SymKey* symKey = NULL ;
1115*cdf0e10cSrcweir     SECKEYPublicKey* pubKey = NULL ;
1116*cdf0e10cSrcweir     SECKEYPrivateKey* priKey = NULL ;
1117*cdf0e10cSrcweir     xmlSecKeysMngrPtr pKeysMngr = NULL ;
1118*cdf0e10cSrcweir 
1119*cdf0e10cSrcweir     handler = this->getCertDb() ;
1120*cdf0e10cSrcweir 
1121*cdf0e10cSrcweir     /*-
1122*cdf0e10cSrcweir      * The following lines is based on the private version of xmlSec-NSS
1123*cdf0e10cSrcweir      * crypto engine
1124*cdf0e10cSrcweir      */
1125*cdf0e10cSrcweir     int cSlots = m_Slots.size();
1126*cdf0e10cSrcweir     boost::scoped_array<PK11SlotInfo*> sarSlots(new PK11SlotInfo*[cSlots]);
1127*cdf0e10cSrcweir     PK11SlotInfo**  slots = sarSlots.get();
1128*cdf0e10cSrcweir     int count = 0;
1129*cdf0e10cSrcweir     for (CIT_SLOTS islots = m_Slots.begin();islots != m_Slots.end(); islots++, count++)
1130*cdf0e10cSrcweir         slots[count] = *islots;
1131*cdf0e10cSrcweir 
1132*cdf0e10cSrcweir     pKeysMngr = xmlSecNssAppliedKeysMngrCreate(slots, cSlots, handler ) ;
1133*cdf0e10cSrcweir     if( pKeysMngr == NULL )
1134*cdf0e10cSrcweir         throw RuntimeException() ;
1135*cdf0e10cSrcweir 
1136*cdf0e10cSrcweir     /*-
1137*cdf0e10cSrcweir      * Adopt symmetric key into keys manager
1138*cdf0e10cSrcweir      */
1139*cdf0e10cSrcweir     for( i = 0 ; ( symKey = this->getSymKey( i ) ) != NULL ; i ++ ) {
1140*cdf0e10cSrcweir         if( xmlSecNssAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) {
1141*cdf0e10cSrcweir             throw RuntimeException() ;
1142*cdf0e10cSrcweir         }
1143*cdf0e10cSrcweir     }
1144*cdf0e10cSrcweir 
1145*cdf0e10cSrcweir     /*-
1146*cdf0e10cSrcweir      * Adopt asymmetric public key into keys manager
1147*cdf0e10cSrcweir      */
1148*cdf0e10cSrcweir     for( i = 0 ; ( pubKey = this->getPubKey( i ) ) != NULL ; i ++ ) {
1149*cdf0e10cSrcweir         if( xmlSecNssAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) {
1150*cdf0e10cSrcweir             throw RuntimeException() ;
1151*cdf0e10cSrcweir         }
1152*cdf0e10cSrcweir     }
1153*cdf0e10cSrcweir 
1154*cdf0e10cSrcweir     /*-
1155*cdf0e10cSrcweir      * Adopt asymmetric private key into keys manager
1156*cdf0e10cSrcweir      */
1157*cdf0e10cSrcweir     for( i = 0 ; ( priKey = this->getPriKey( i ) ) != NULL ; i ++ ) {
1158*cdf0e10cSrcweir         if( xmlSecNssAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) {
1159*cdf0e10cSrcweir             throw RuntimeException() ;
1160*cdf0e10cSrcweir         }
1161*cdf0e10cSrcweir     }
1162*cdf0e10cSrcweir     return pKeysMngr ;
1163*cdf0e10cSrcweir }
1164*cdf0e10cSrcweir void SecurityEnvironment_NssImpl::destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) {
1165*cdf0e10cSrcweir     if( pKeysMngr != NULL ) {
1166*cdf0e10cSrcweir         xmlSecKeysMngrDestroy( pKeysMngr ) ;
1167*cdf0e10cSrcweir     }
1168*cdf0e10cSrcweir }
1169