void pkcs11h_openssl_freeSession ( IN const pkcs11h_openssl_session_t openssl_session ) { CK_RV rv; _PKCS11H_ASSERT (openssl_session!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_freeSession - entry openssl_session=%p, count=%d", (void *)openssl_session, openssl_session->reference_count ); #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock)) != CKR_OK) { _PKCS11H_LOG (PKCS11H_LOG_ERROR, "PKCS#11: Cannot lock mutex %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } #endif openssl_session->reference_count--; #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock); #endif _PKCS11H_ASSERT (openssl_session->reference_count>=0); if (openssl_session->reference_count == 0) { #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexFree(&openssl_session->reference_count_lock); #endif if (openssl_session->cleanup_hook != NULL) { openssl_session->cleanup_hook (openssl_session->certificate); } if (openssl_session->x509 != NULL) { X509_free (openssl_session->x509); openssl_session->x509 = NULL; } if (openssl_session->certificate != NULL) { pkcs11h_certificate_freeCertificate (openssl_session->certificate); openssl_session->certificate = NULL; } _pkcs11h_mem_free ((void *)&openssl_session); } cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_freeSession - return" ); }
CK_RV pkcs11h_initialize (void) { #if defined(ENABLE_PKCS11H_THREADING) PKCS11H_BOOL has_mutex_global = FALSE; PKCS11H_BOOL has_mutex_cache = FALSE; PKCS11H_BOOL has_mutex_session = FALSE; #endif CK_RV rv = CKR_FUNCTION_FAILED; _pkcs11h_data_t data = NULL; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_initialize entry" ); pkcs11h_terminate (); if ((rv = _pkcs11h_mem_malloc ((void*)&data, sizeof (struct _pkcs11h_data_s))) != CKR_OK) { goto cleanup; } if (_g_pkcs11h_crypto_engine.initialize == NULL) { if ((rv = pkcs11h_engine_setCrypto (PKCS11H_ENGINE_CRYPTO_AUTO)) != CKR_OK) { goto cleanup; } } if (!_g_pkcs11h_crypto_engine.initialize (_g_pkcs11h_crypto_engine.global_data)) { _PKCS11H_DEBUG ( PKCS11H_LOG_ERROR, "PKCS#11: Cannot initialize crypto engine" ); rv = CKR_FUNCTION_FAILED; goto cleanup; } #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexInit (&data->mutexes.global)) != CKR_OK) { goto cleanup; } has_mutex_global = TRUE; if ((rv = _pkcs11h_threading_mutexInit (&data->mutexes.cache)) != CKR_OK) { goto cleanup; } has_mutex_cache = TRUE; if ((rv = _pkcs11h_threading_mutexInit (&data->mutexes.session)) != CKR_OK) { goto cleanup; } has_mutex_session = TRUE; #if !defined(_WIN32) if ( pthread_atfork ( __pkcs11h_threading_atfork_prepare, __pkcs11h_threading_atfork_parent, __pkcs11h_threading_atfork_child ) ) { rv = CKR_FUNCTION_FAILED; goto cleanup; } #endif #endif data->max_retries = _PKCS11H_DEFAULT_MAX_LOGIN_RETRY; data->allow_protected_auth = TRUE; data->pin_cache_period = _PKCS11H_DEFAULT_PIN_CACHE_PERIOD; data->initialized = TRUE; _g_pkcs11h_data = data; data = NULL; pkcs11h_setLogHook (__pkcs11h_hooks_default_log, NULL); pkcs11h_setTokenPromptHook (__pkcs11h_hooks_default_token_prompt, NULL); pkcs11h_setPINPromptHook (__pkcs11h_hooks_default_pin_prompt, NULL); rv = CKR_OK; cleanup: if (data != NULL) { #if defined(ENABLE_PKCS11H_THREADING) if (has_mutex_global) { _pkcs11h_threading_mutexFree (&data->mutexes.global); has_mutex_global = FALSE; } if (has_mutex_cache) { _pkcs11h_threading_mutexFree (&data->mutexes.cache); has_mutex_cache = FALSE; } if (has_mutex_session) { _pkcs11h_threading_mutexFree (&data->mutexes.session); has_mutex_session = FALSE; } #endif _pkcs11h_mem_free ((void *)&data); data = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_initialize return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv; }
CK_RV pkcs11h_terminate (void) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_terminate entry" ); if (_g_pkcs11h_data != NULL) { _pkcs11h_provider_t current_provider = NULL; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Removing providers" ); for ( current_provider = _g_pkcs11h_data->providers; current_provider != NULL; current_provider = current_provider->next ) { pkcs11h_removeProvider (current_provider->reference); } #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.cache); _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.session); _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global); #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Releasing sessions" ); while (_g_pkcs11h_data->sessions != NULL) { _pkcs11h_session_t current = _g_pkcs11h_data->sessions; _g_pkcs11h_data->sessions = _g_pkcs11h_data->sessions->next; #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexLock (¤t->mutex); #endif current->valid = FALSE; if (current->reference_count != 0) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Warning: Found session with references" ); } if (current->token_id != NULL) { pkcs11h_token_freeTokenId (current->token_id); current->token_id = NULL; } #if defined(ENABLE_PKCS11H_CERTIFICATE) pkcs11h_certificate_freeCertificateIdList (current->cached_certs); #endif current->provider = NULL; #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexFree (¤t->mutex); #endif _pkcs11h_mem_free ((void *)¤t); } #if defined(ENABLE_PKCS11H_SLOTEVENT) _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Terminating slotevent" ); _pkcs11h_slotevent_terminate (); #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Marking as uninitialized" ); _g_pkcs11h_data->initialized = FALSE; while (_g_pkcs11h_data->providers != NULL) { _pkcs11h_provider_t current = _g_pkcs11h_data->providers; _g_pkcs11h_data->providers = _g_pkcs11h_data->providers->next; _pkcs11h_mem_free ((void *)¤t); } #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.global); _pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.cache); _pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.session); #endif _g_pkcs11h_crypto_engine.uninitialize (_g_pkcs11h_crypto_engine.global_data); _pkcs11h_mem_free ((void *)&_g_pkcs11h_data); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_terminate return" ); return CKR_OK; }
CK_RV _pkcs11h_session_getSessionByTokenId ( IN const pkcs11h_token_id_t token_id, OUT _pkcs11h_session_t * const p_session ) { #if defined(ENABLE_PKCS11H_THREADING) PKCS11H_BOOL mutex_locked = FALSE; PKCS11H_BOOL have_session_mutex = FALSE; #endif _pkcs11h_session_t session = NULL; _pkcs11h_session_t current_session; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (token_id!=NULL); _PKCS11H_ASSERT (p_session!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_getSessionByTokenId entry token_id=%p, p_session=%p", (void *)token_id, (void *)p_session ); *p_session = NULL; #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.session)) != CKR_OK) { goto cleanup; } mutex_locked = TRUE; #endif for ( current_session = _g_pkcs11h_data->sessions; current_session != NULL && session == NULL; current_session = current_session->next ) { if ( pkcs11h_token_sameTokenId ( current_session->token_id, token_id ) ) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Using cached session" ); session = current_session; session->reference_count++; } } if (session == NULL) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Creating a new session" ); if ( (rv = _pkcs11h_mem_malloc ( (void *)&session, sizeof (struct _pkcs11h_session_s)) ) != CKR_OK ) { goto cleanup; } session->reference_count = 1; session->session_handle = _PKCS11H_INVALID_SESSION_HANDLE; session->pin_cache_period = _g_pkcs11h_data->pin_cache_period; if ( (rv = pkcs11h_token_duplicateTokenId ( &session->token_id, token_id )) != CKR_OK ) { goto cleanup; } #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexInit (&session->mutex)) != CKR_OK) { goto cleanup; } have_session_mutex = TRUE; #endif session->valid = TRUE; session->next = _g_pkcs11h_data->sessions; _g_pkcs11h_data->sessions = session; } *p_session = session; session = NULL; rv = CKR_OK; cleanup: if (session != NULL) { #if defined(ENABLE_PKCS11H_THREADING) if (have_session_mutex) { _pkcs11h_threading_mutexFree (&session->mutex); } #endif _pkcs11h_mem_free ((void *)&session); } #if defined(ENABLE_PKCS11H_THREADING) if (mutex_locked) { _pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.session); mutex_locked = FALSE; } #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_getSessionByTokenId return rv=%lu-'%s', *p_session=%p", rv, pkcs11h_getMessage (rv), (void *)*p_session ); return rv; }