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