CK_RV pkcs11h_token_freeTokenIdList ( IN const pkcs11h_token_id_list_t token_id_list ) { pkcs11h_token_id_list_t _id = token_id_list; _PKCS11H_ASSERT (_g_pkcs11h_data!=NULL); _PKCS11H_ASSERT (_g_pkcs11h_data->initialized); /*_PKCS11H_ASSERT (token_id_list!=NULL); NOT NEEDED*/ _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_freeTokenIdList entry token_id_list=%p", (void *)token_id_list ); while (_id != NULL) { pkcs11h_token_id_list_t x = _id; _id = _id->next; if (x->token_id != NULL) { pkcs11h_token_freeTokenId (x->token_id); } x->next = NULL; _pkcs11h_mem_free ((void *)&x); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_freeTokenIdList return" ); return CKR_OK; }
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_token_enumTokenIds ( IN const unsigned method, OUT pkcs11h_token_id_list_t * const p_token_id_list ) { #if defined(ENABLE_PKCS11H_THREADING) PKCS11H_BOOL mutex_locked = FALSE; #endif pkcs11h_token_id_list_t token_id_list = NULL; _pkcs11h_provider_t current_provider; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (_g_pkcs11h_data!=NULL); _PKCS11H_ASSERT (_g_pkcs11h_data->initialized); _PKCS11H_ASSERT (p_token_id_list!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_enumTokenIds entry method=%u, p_token_id_list=%p", method, (void *)p_token_id_list ); *p_token_id_list = NULL; #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global)) != CKR_OK) { goto cleanup; } mutex_locked = TRUE; #endif for ( current_provider = _g_pkcs11h_data->providers; current_provider != NULL; current_provider = current_provider->next ) { CK_SLOT_ID_PTR slots = NULL; CK_ULONG slotnum; CK_SLOT_ID slot_index; /* * Skip disabled providers */ if (!current_provider->enabled) { continue; } if ( (rv = _pkcs11h_session_getSlotList ( current_provider, CK_TRUE, &slots, &slotnum )) != CKR_OK ) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Cannot get slot list for provider '%s' rv=%lu-'%s'", current_provider->manufacturerID, rv, pkcs11h_getMessage (rv) ); goto retry1; } for ( slot_index=0; slot_index < slotnum; slot_index++ ) { pkcs11h_token_id_list_t entry = NULL; CK_TOKEN_INFO info; if ( (rv = _pkcs11h_mem_malloc ( (void *)&entry, sizeof (struct pkcs11h_token_id_list_s) )) != CKR_OK || (rv = current_provider->f->C_GetTokenInfo ( slots[slot_index], &info )) != CKR_OK || (rv = _pkcs11h_token_getTokenId ( &info, &entry->token_id )) ) { goto retry11; } entry->next = token_id_list; token_id_list = entry; entry = NULL; rv = CKR_OK; retry11: if (entry != NULL) { pkcs11h_token_freeTokenIdList (entry); entry = NULL; } } retry1: if (slots != NULL) { _pkcs11h_mem_free ((void *)&slots); slots = NULL; } } if (method == PKCS11H_ENUM_METHOD_CACHE) { _pkcs11h_session_t session = NULL; for ( session = _g_pkcs11h_data->sessions; session != NULL; session = session->next ) { pkcs11h_token_id_list_t entry = NULL; PKCS11H_BOOL found = FALSE; for ( entry = token_id_list; entry != NULL && !found; entry = entry->next ) { if ( pkcs11h_token_sameTokenId ( session->token_id, entry->token_id ) ) { found = TRUE; } } if (!found) { entry = NULL; if ( (rv = _pkcs11h_mem_malloc ( (void *)&entry, sizeof (struct pkcs11h_token_id_list_s) )) != CKR_OK || (rv = pkcs11h_token_duplicateTokenId ( &entry->token_id, session->token_id )) != CKR_OK ) { goto retry12; } entry->next = token_id_list; token_id_list = entry; entry = NULL; retry12: if (entry != NULL) { if (entry->token_id != NULL) { pkcs11h_token_freeTokenId (entry->token_id); } _pkcs11h_mem_free ((void *)&entry); } } } } *p_token_id_list = token_id_list; token_id_list = NULL; rv = CKR_OK; cleanup: if (token_id_list != NULL) { pkcs11h_token_freeTokenIdList (token_id_list); token_id_list = NULL; } #if defined(ENABLE_PKCS11H_THREADING) if (mutex_locked) { rv = _pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.global); mutex_locked = FALSE; } #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_enumTokenIds return rv=%lu-'%s', *p_token_id_list=%p", rv, pkcs11h_getMessage (rv), (void *)p_token_id_list ); return rv; }
CK_RV pkcs11h_token_deserializeTokenId ( OUT pkcs11h_token_id_t *p_token_id, IN const char * const sz ) { #define __PKCS11H_TARGETS_NUMBER 4 struct { char *p; size_t s; } targets[__PKCS11H_TARGETS_NUMBER]; pkcs11h_token_id_t token_id = NULL; char *p1 = NULL; char *_sz = NULL; int e; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (p_token_id!=NULL); _PKCS11H_ASSERT (sz!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'", (void *)p_token_id, sz ); *p_token_id = NULL; if ( (rv = _pkcs11h_mem_strdup ( (void *)&_sz, sz )) != CKR_OK ) { goto cleanup; } p1 = _sz; if ((rv = _pkcs11h_token_newTokenId (&token_id)) != CKR_OK) { goto cleanup; } targets[0].p = token_id->manufacturerID; targets[0].s = sizeof (token_id->manufacturerID); targets[1].p = token_id->model; targets[1].s = sizeof (token_id->model); targets[2].p = token_id->serialNumber; targets[2].s = sizeof (token_id->serialNumber); targets[3].p = token_id->label; targets[3].s = sizeof (token_id->label); for (e=0;e < __PKCS11H_TARGETS_NUMBER;e++) { size_t l; char *p2 = NULL; /* * Don't search for last * separator */ if (e != __PKCS11H_TARGETS_NUMBER-1) { p2 = strchr (p1, '/'); if (p2 == NULL) { rv = CKR_ATTRIBUTE_VALUE_INVALID; goto cleanup; } else { *p2 = '\x0'; } } if ( (rv = _pkcs11h_util_unescapeString ( NULL, p1, &l )) != CKR_OK ) { goto cleanup; } if (l > targets[e].s) { rv = CKR_ATTRIBUTE_VALUE_INVALID; goto cleanup; } l = targets[e].s; if ( (rv = _pkcs11h_util_unescapeString ( targets[e].p, p1, &l )) != CKR_OK ) { goto cleanup; } p1 = p2+1; } strncpy ( token_id->display, token_id->label, sizeof (token_id->display) ); *p_token_id = token_id; token_id = NULL; rv = CKR_OK; cleanup: if (_sz != NULL) { _pkcs11h_mem_free ((void *)&_sz); } if (token_id != NULL) { pkcs11h_token_freeTokenId (token_id); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_deserializeTokenId return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv; #undef __PKCS11H_TARGETS_NUMBER }
CK_RV _pkcs11h_session_reset ( IN const _pkcs11h_session_t session, IN void * const user_data, IN const unsigned mask_prompt, OUT CK_SLOT_ID * const p_slot ) { PKCS11H_BOOL found = FALSE; CK_RV rv = CKR_FUNCTION_FAILED; unsigned nRetry = 0; _PKCS11H_ASSERT (session!=NULL); /*_PKCS11H_ASSERT (user_data) NOT NEEDED */ _PKCS11H_ASSERT (p_slot!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_reset entry session=%p, user_data=%p, mask_prompt=%08x, p_slot=%p", (void *)session, user_data, mask_prompt, (void *)p_slot ); *p_slot = _PKCS11H_INVALID_SLOT_ID; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_reset Expected token manufacturerID='%s' model='%s', serialNumber='%s', label='%s'", session->token_id->manufacturerID, session->token_id->model, session->token_id->serialNumber, session->token_id->label ); while (!found) { _pkcs11h_provider_t current_provider = NULL; for ( current_provider = _g_pkcs11h_data->providers; ( current_provider != NULL && !found ); current_provider = current_provider->next ) { CK_SLOT_ID_PTR slots = NULL; CK_ULONG slotnum; CK_SLOT_ID slot_index; /* * Skip all other providers, * if one was set in the past */ if ( session->provider != NULL && session->provider != current_provider ) { continue; } if ( (rv = _pkcs11h_session_getSlotList ( current_provider, CK_TRUE, &slots, &slotnum )) != CKR_OK ) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Cannot get slot list for provider '%s' rv=%lu-'%s'", current_provider->manufacturerID, rv, pkcs11h_getMessage (rv) ); goto retry1; } for ( slot_index=0; ( slot_index < slotnum && !found ); slot_index++ ) { pkcs11h_token_id_t token_id = NULL; CK_TOKEN_INFO info; if ( (rv = current_provider->f->C_GetTokenInfo ( slots[slot_index], &info )) != CKR_OK || (rv = _pkcs11h_token_getTokenId ( &info, &token_id )) != CKR_OK ) { goto retry11; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_reset Found token manufacturerID='%s' model='%s', serialNumber='%s', label='%s'", token_id->manufacturerID, token_id->model, token_id->serialNumber, token_id->label ); if ( pkcs11h_token_sameTokenId ( session->token_id, token_id ) ) { found = TRUE; *p_slot = slots[slot_index]; if (session->provider == NULL) { session->provider = current_provider; session->allow_protected_auth_supported = (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) != 0; } } rv = CKR_OK; retry11: if (rv != CKR_OK) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%lu-'%s'", current_provider->manufacturerID, slots[slot_index], rv, pkcs11h_getMessage (rv) ); } if (token_id != NULL) { pkcs11h_token_freeTokenId (token_id); } } retry1: if (slots != NULL) { _pkcs11h_mem_free ((void *)&slots); slots = NULL; } } if (!found && (mask_prompt & PKCS11H_PROMPT_MASK_ALLOW_TOKEN_PROMPT) == 0) { rv = CKR_TOKEN_NOT_PRESENT; goto cleanup; } if (!found) { PKCS11H_BOOL canceled; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Calling token_prompt hook for '%s'", session->token_id->display ); canceled = !_g_pkcs11h_data->hooks.token_prompt ( _g_pkcs11h_data->hooks.token_prompt_data, user_data, session->token_id, nRetry++ ); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: token_prompt returned %d", canceled ? 0 : 1 ); if (canceled) { rv = CKR_CANCEL; goto cleanup; } } } rv = CKR_OK; cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_reset return rv=%lu-'%s', *p_slot=%ld", rv, pkcs11h_getMessage (rv), *p_slot ); return rv; }