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