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