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