xref: /AOO41X/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