static void DSA_meth_free (DSA_METHOD *meth) { if (meth != NULL) { if (meth->name != NULL) { _pkcs11h_mem_free ((void *)&meth->name); } _pkcs11h_mem_free ((void *)&meth); } }
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_session_freeObjectAttributes ( IN OUT const CK_ATTRIBUTE_PTR attrs, IN const unsigned count ) { unsigned i; _PKCS11H_ASSERT (attrs!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_freeObjectAttributes entry attrs=%p, count=%u", (void *)attrs, count ); for (i=0;i<count;i++) { if (attrs[i].pValue != NULL) { _pkcs11h_mem_free ((void *)&attrs[i].pValue); attrs[i].pValue = NULL; } } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_freeObjectAttributes return" ); return CKR_OK; }
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" ); }
pkcs11h_openssl_session_t pkcs11h_openssl_createSession ( IN const pkcs11h_certificate_t certificate ) { pkcs11h_openssl_session_t openssl_session = NULL; CK_RV rv; PKCS11H_BOOL ok = FALSE; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_createSession - entry" ); OpenSSL_add_all_digests (); if ( _pkcs11h_mem_malloc ( (void*)&openssl_session, sizeof (struct pkcs11h_openssl_session_s)) != CKR_OK ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate memory"); goto cleanup; } openssl_session->certificate = certificate; openssl_session->reference_count = 1; #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexInit(&openssl_session->reference_count_lock)) != CKR_OK) { _PKCS11H_LOG (PKCS11H_LOG_ERROR, "PKCS#11: Cannot initialize mutex %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } #endif ok = TRUE; cleanup: if (!ok) { _pkcs11h_mem_free ((void *)&openssl_session); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_createSession - return openssl_session=%p", (void *)openssl_session ); return openssl_session; }
CK_RV _pkcs11h_token_newTokenId ( OUT pkcs11h_token_id_t * const p_token_id ) { CK_RV rv = CKR_FUNCTION_FAILED; pkcs11h_token_id_t token_id = NULL; _PKCS11H_ASSERT (_g_pkcs11h_data!=NULL); _PKCS11H_ASSERT (_g_pkcs11h_data->initialized); _PKCS11H_ASSERT (p_token_id!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_token_newTokenId entry p_token_id=%p", (void *)p_token_id ); *p_token_id = NULL; if ((rv = _pkcs11h_mem_malloc ((void *)&token_id, sizeof (struct pkcs11h_token_id_s))) != CKR_OK) { goto cleanup; } *p_token_id = token_id; token_id = NULL; rv = CKR_OK; cleanup: if (token_id != NULL) { _pkcs11h_mem_free ((void *)&token_id); token_id = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_token_newTokenId return rv=%lu-'%s', *p_token_id=%p", rv, pkcs11h_getMessage (rv), (void *)*p_token_id ); return rv; }
CK_RV pkcs11h_token_freeTokenId ( IN pkcs11h_token_id_t token_id ) { _PKCS11H_ASSERT (_g_pkcs11h_data!=NULL); _PKCS11H_ASSERT (_g_pkcs11h_data->initialized); _PKCS11H_ASSERT (token_id!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_freeTokenId entry certificate_id=%p", (void *)token_id ); _pkcs11h_mem_free ((void *)&token_id); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_freeTokenId return" ); return CKR_OK; }
static ECDSA_SIG * __pkcs11h_openssl_ecdsa_do_sign( IN const unsigned char *dgst, IN int dlen, IN const BIGNUM *inv, IN const BIGNUM *r, OUT EC_KEY *ec ) { pkcs11h_certificate_t certificate = __pkcs11h_openssl_ecdsa_get_pkcs11h_certificate (ec); unsigned char *sigbuf = NULL; size_t siglen; ECDSA_SIG *sig = NULL; ECDSA_SIG *ret = NULL; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_ecdsa_do_sign - entered dgst=%p, dlen=%d, inv=%p, r=%p, ec=%p", (void *)dgst, dlen, (void *)inv, (void *)r, (void *)ec ); _PKCS11H_ASSERT (dgst!=NULL); _PKCS11H_ASSERT (inv==NULL); _PKCS11H_ASSERT (r==NULL); _PKCS11H_ASSERT (ec!=NULL); _PKCS11H_ASSERT (certificate!=NULL); if ( (rv = pkcs11h_certificate_signAny ( certificate, CKM_ECDSA, dgst, (size_t)dlen, NULL, &siglen )) != CKR_OK ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } if ((rv = _pkcs11h_mem_malloc ((void *)&sigbuf, siglen)) != CKR_OK) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot cannot allocate signature buffer"); goto cleanup; } if ( (rv = pkcs11h_certificate_signAny ( certificate, CKM_ECDSA, dgst, (size_t)dlen, sigbuf, &siglen )) != CKR_OK ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } if ((sig = ECDSA_SIG_new ()) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate ECDSA_SIG"); goto cleanup; } if (BN_bin2bn (&sigbuf[0], siglen/2, sig->r) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert ecdsa r"); goto cleanup; } if (BN_bin2bn (&sigbuf[siglen/2], siglen/2, sig->s) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert ecdsa s"); goto cleanup; } ret = sig; sig = NULL; cleanup: if (sigbuf != NULL) { _pkcs11h_mem_free ((void *)&sigbuf); } if (sig != NULL) { ECDSA_SIG_free (sig); sig = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_ecdsa_do_sign - return sig=%p", (void *)sig ); return ret; }
static void * __pkcs11h_slotevent_provider ( IN void *p ) { _pkcs11h_provider_t provider = (_pkcs11h_provider_t)p; CK_SLOT_ID slot; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_slotevent_provider provider='%s' entry", provider->manufacturerID ); if (!provider->enabled) { rv = CKR_OPERATION_NOT_INITIALIZED; goto cleanup; } if (provider->slot_poll_interval == 0) { provider->slot_poll_interval = _PKCS11H_DEFAULT_SLOTEVENT_POLL; } /* * If we cannot finalize, we cannot cause * WaitForSlotEvent to terminate */ if (!provider->should_finalize) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Setup slotevent provider='%s' mode hardset to poll", provider->manufacturerID ); provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_POLL; } if ( provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO || provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_TRIGGER ) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Setup slotevent provider='%s' checking trigger", provider->manufacturerID ); while ( !_g_pkcs11h_data->slotevent.should_terminate && provider->enabled && (rv = provider->f->C_WaitForSlotEvent ( 0, &slot, NULL_PTR )) == CKR_OK ) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Slotevent provider='%s' event", provider->manufacturerID ); _pkcs11h_threading_condSignal (&_g_pkcs11h_data->slotevent.cond_event); } if (rv != CKR_FUNCTION_NOT_SUPPORTED) { goto cleanup; } } if ( provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO || provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_POLL ) { PKCS11H_BOOL had_sleep = TRUE; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Setup slotevent provider='%s' checking poll", provider->manufacturerID ); while ( !_g_pkcs11h_data->slotevent.should_terminate && provider->enabled && ( (rv = provider->f->C_WaitForSlotEvent ( CKF_DONT_BLOCK, &slot, NULL_PTR )) == CKR_OK || rv == CKR_NO_EVENT ) ) { if (rv == CKR_OK) { if (had_sleep) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Slotevent provider='%s' event", provider->manufacturerID ); had_sleep = FALSE; /* Mask out seq events */ _pkcs11h_threading_condSignal (&_g_pkcs11h_data->slotevent.cond_event); } } else { _pkcs11h_threading_sleep (provider->slot_poll_interval); had_sleep = TRUE; } } if (rv != CKR_FUNCTION_NOT_SUPPORTED) { goto cleanup; } } if ( provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO || provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_FETCH ) { unsigned long last_checksum = 0; PKCS11H_BOOL is_first_time = TRUE; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Setup slotevent provider='%s' checking fetch", provider->manufacturerID ); while ( !_g_pkcs11h_data->slotevent.should_terminate && provider->enabled ) { unsigned long current_checksum = 0; CK_ULONG i; CK_SLOT_ID_PTR slots = NULL; CK_ULONG slotnum; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Slotevent provider='%s' poll", provider->manufacturerID ); if ( (rv = _pkcs11h_session_getSlotList ( provider, TRUE, &slots, &slotnum )) != CKR_OK ) { goto cleanup1; } for (i=0;i<slotnum;i++) { CK_TOKEN_INFO info; if (provider->f->C_GetTokenInfo (slots[i], &info) == CKR_OK) { current_checksum += ( __pkcs11h_slotevent_checksum ( info.label, sizeof (info.label) ) + __pkcs11h_slotevent_checksum ( info.manufacturerID, sizeof (info.manufacturerID) ) + __pkcs11h_slotevent_checksum ( info.model, sizeof (info.model) ) + __pkcs11h_slotevent_checksum ( info.serialNumber, sizeof (info.serialNumber) ) ); } } if (is_first_time) { is_first_time = FALSE; } else { if (last_checksum != current_checksum) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Slotevent provider='%s' event", provider->manufacturerID ); _pkcs11h_threading_condSignal (&_g_pkcs11h_data->slotevent.cond_event); } } last_checksum = current_checksum; rv = CKR_OK; cleanup1: if (slots != NULL) { _pkcs11h_mem_free ((void *)&slots); } if (rv != CKR_OK) { goto cleanup; } if (!_g_pkcs11h_data->slotevent.should_terminate) { _pkcs11h_threading_sleep (provider->slot_poll_interval); } } } cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_slotevent_provider provider='%s' return", provider->manufacturerID ); return NULL; }
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; }
static DSA_SIG * __pkcs11h_openssl_dsa_do_sign( IN const unsigned char *dgst, IN int dlen, OUT DSA *dsa ) { pkcs11h_certificate_t certificate = __pkcs11h_openssl_dsa_get_pkcs11h_certificate (dsa); unsigned char *sigbuf = NULL; size_t siglen; DSA_SIG *sig = NULL; DSA_SIG *ret = NULL; BIGNUM *r = NULL; BIGNUM *s = NULL; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_dsa_do_sign - entered dgst=%p, dlen=%d, dsa=%p", (void *)dgst, dlen, (void *)dsa ); _PKCS11H_ASSERT (dgst!=NULL); _PKCS11H_ASSERT (dsa!=NULL); _PKCS11H_ASSERT (certificate!=NULL); if ( (rv = pkcs11h_certificate_signAny ( certificate, CKM_DSA, dgst, (size_t)dlen, NULL, &siglen )) != CKR_OK ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } if ((rv = _pkcs11h_mem_malloc ((void *)&sigbuf, siglen)) != CKR_OK) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot cannot allocate signature buffer"); goto cleanup; } if ( (rv = pkcs11h_certificate_signAny ( certificate, CKM_DSA, dgst, (size_t)dlen, sigbuf, &siglen )) != CKR_OK ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } if ((sig = DSA_SIG_new ()) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate DSA_SIG"); goto cleanup; } if ((r = BN_bin2bn (&sigbuf[0], siglen/2, NULL)) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert dsa r"); goto cleanup; } if ((s = BN_bin2bn (&sigbuf[siglen/2], siglen/2, NULL)) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert dsa s"); goto cleanup; } DSA_SIG_set0 (sig, r, s); ret = sig; sig = NULL; r = NULL; s = NULL; cleanup: if (sigbuf != NULL) { _pkcs11h_mem_free ((void *)&sigbuf); } if (sig != NULL) { DSA_SIG_free (sig); sig = NULL; } if (r != NULL) { BN_clear_free (r); } if (s != NULL) { BN_clear_free (s); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_dsa_do_sign - return sig=%p", (void *)sig ); return ret; }
CK_RV _pkcs11h_session_getSlotList ( IN const _pkcs11h_provider_t provider, IN const CK_BBOOL token_present, OUT CK_SLOT_ID_PTR * const pSlotList, OUT CK_ULONG_PTR pulCount ) { CK_SLOT_ID_PTR _slots = NULL; CK_ULONG _slotnum = 0; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (provider!=NULL); _PKCS11H_ASSERT (pSlotList!=NULL); _PKCS11H_ASSERT (pulCount!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_getSlotList entry provider=%p, token_present=%d, pSlotList=%p, pulCount=%p", (void *)provider, token_present ? 1 : 0, (void *)pSlotList, (void *)pulCount ); *pSlotList = NULL; *pulCount = 0; if (!provider->enabled) { rv = CKR_CRYPTOKI_NOT_INITIALIZED; goto cleanup; } if ( (rv = provider->f->C_GetSlotList ( token_present, NULL_PTR, &_slotnum )) != CKR_OK ) { goto cleanup; } if (_slotnum > 0) { if ((rv = _pkcs11h_mem_malloc ((void *)&_slots, _slotnum * sizeof (CK_SLOT_ID))) != CKR_OK) { goto cleanup; } } if (_slotnum > 0) { if ( (rv = provider->f->C_GetSlotList ( token_present, _slots, &_slotnum )) != CKR_OK ) { goto cleanup; } } *pSlotList = _slots; _slots = NULL; *pulCount = _slotnum; rv = CKR_OK; cleanup: if (_slots != NULL) { _pkcs11h_mem_free ((void *)&_slots); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_getSlotList return rv=%lu-'%s' *pulCount=%ld", rv, pkcs11h_getMessage (rv), *pulCount ); return rv; }
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; }
CK_RV pkcs11h_addProvider ( IN const char * const reference, IN const char * const provider_location, IN const PKCS11H_BOOL allow_protected_auth, IN const unsigned mask_private_mode, IN const unsigned slot_event_method, IN const unsigned slot_poll_interval, IN const PKCS11H_BOOL cert_is_private ) { #if defined(ENABLE_PKCS11H_THREADING) PKCS11H_BOOL mutex_locked = FALSE; #endif #if defined(ENABLE_PKCS11H_DEBUG) #if defined(_WIN32) int mypid = 0; #else pid_t mypid = getpid (); #endif #endif #if !defined(_WIN32) void *p; #endif _pkcs11h_provider_t provider = NULL; CK_C_GetFunctionList gfl = NULL; CK_C_INITIALIZE_ARGS initargs; CK_C_INITIALIZE_ARGS_PTR pinitargs = NULL; CK_INFO info; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (_g_pkcs11h_data!=NULL); _PKCS11H_ASSERT (_g_pkcs11h_data->initialized); _PKCS11H_ASSERT (provider_location!=NULL); /*_PKCS11H_ASSERT (szSignMode!=NULL); NOT NEEDED*/ _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_addProvider entry version='%s', pid=%d, reference='%s', provider_location='%s', allow_protected_auth=%d, mask_private_mode=%08x, cert_is_private=%d", PACKAGE_VERSION, mypid, reference, provider_location, allow_protected_auth ? 1 : 0, mask_private_mode, cert_is_private ? 1 : 0 ); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Adding provider '%s'-'%s'", reference, provider_location ); #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global)) != CKR_OK) { goto cleanup; } mutex_locked = TRUE; #endif if ((rv = _pkcs11h_mem_malloc ((void *)&provider, sizeof (struct _pkcs11h_provider_s))) != CKR_OK) { goto cleanup; } strncpy ( provider->reference, reference, sizeof (provider->reference)-1 ); provider->reference[sizeof (provider->reference)-1] = '\x0'; strncpy ( provider->manufacturerID, ( strlen (provider_location) < sizeof (provider->manufacturerID) ? provider_location : provider_location+strlen (provider_location)-sizeof (provider->manufacturerID)+1 ), sizeof (provider->manufacturerID)-1 ); provider->manufacturerID[sizeof (provider->manufacturerID)-1] = '\x0'; provider->allow_protected_auth = allow_protected_auth; provider->mask_private_mode = mask_private_mode; provider->slot_event_method = slot_event_method; provider->slot_poll_interval = slot_poll_interval; provider->cert_is_private = cert_is_private; #if defined(_WIN32) provider->handle = LoadLibraryA (provider_location); #else provider->handle = dlopen (provider_location, RTLD_NOW); #endif if (provider->handle == NULL) { rv = CKR_FUNCTION_FAILED; goto cleanup; } #if defined(_WIN32) gfl = (CK_C_GetFunctionList)GetProcAddress ( provider->handle, "C_GetFunctionList" ); #else /* * Make compiler happy! */ p = dlsym ( provider->handle, "C_GetFunctionList" ); memmove ( &gfl, &p, sizeof (void *) ); #endif if (gfl == NULL) { rv = CKR_FUNCTION_FAILED; goto cleanup; } if ((rv = gfl (&provider->f)) != CKR_OK) { goto cleanup; } memset(&initargs, 0, sizeof(initargs)); if ((initargs.pReserved = getenv("PKCS11H_INIT_ARGS_RESERVED")) != NULL) { pinitargs = &initargs; } if ((rv = provider->f->C_Initialize (pinitargs)) != CKR_OK) { if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) { rv = CKR_OK; } else { goto cleanup; } } else { provider->should_finalize = TRUE; } if ((rv = provider->f->C_GetInfo (&info)) != CKR_OK) { goto cleanup; } _pkcs11h_util_fixupFixedString ( provider->manufacturerID, (char *)info.manufacturerID, sizeof (info.manufacturerID) ); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_addProvider Provider '%s' manufacturerID '%s'", reference, provider->manufacturerID ); provider->enabled = TRUE; if (_g_pkcs11h_data->providers == NULL) { _g_pkcs11h_data->providers = provider; } else { _pkcs11h_provider_t last = NULL; for ( last = _g_pkcs11h_data->providers; last->next != NULL; last = last->next ); last->next = provider; } provider = NULL; rv = CKR_OK; cleanup: if (provider != NULL) { if (provider->handle != NULL) { #if defined(_WIN32) FreeLibrary (provider->handle); #else dlclose (provider->handle); #endif provider->handle = NULL; } _pkcs11h_mem_free ((void *)&provider); provider = NULL; } #if defined(ENABLE_PKCS11H_THREADING) if (mutex_locked) { _pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.global); mutex_locked = FALSE; } #endif #if defined(ENABLE_PKCS11H_SLOTEVENT) _pkcs11h_slotevent_notify (); #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Provider '%s' added rv=%lu-'%s'", reference, rv, pkcs11h_getMessage (rv) ); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_addProvider return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv; }
X509 * pkcs11h_openssl_getX509 ( IN const pkcs11h_certificate_t certificate ) { unsigned char *certificate_blob = NULL; size_t certificate_blob_size = 0; X509 *x509 = NULL; CK_RV rv = CKR_FUNCTION_FAILED; __pkcs11_openssl_d2i_t d2i1 = NULL; _PKCS11H_ASSERT (certificate!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_getX509 - entry certificate=%p", (void *)certificate ); if ((x509 = X509_new ()) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to allocate certificate object"); rv = CKR_HOST_MEMORY; goto cleanup; } if ( (rv = pkcs11h_certificate_getCertificateBlob ( certificate, NULL, &certificate_blob_size )) != CKR_OK ) { goto cleanup; } if ((rv = _pkcs11h_mem_malloc ((void *)&certificate_blob, certificate_blob_size)) != CKR_OK) { goto cleanup; } if ( (rv = pkcs11h_certificate_getCertificateBlob ( certificate, certificate_blob, &certificate_blob_size )) != CKR_OK ) { goto cleanup; } d2i1 = (__pkcs11_openssl_d2i_t)certificate_blob; if (!d2i_X509 (&x509, &d2i1, certificate_blob_size)) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate"); rv = CKR_FUNCTION_FAILED; goto cleanup; } rv = CKR_OK; cleanup: if (certificate_blob != NULL) { _pkcs11h_mem_free((void *)&certificate_blob); } if (rv != CKR_OK) { if (x509 != NULL) { X509_free (x509); x509 = NULL; } } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_getX509 - return rv=%ld-'%s', x509=%p", rv, pkcs11h_getMessage (rv), (void *)x509 ); return x509; }
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_findObjects ( IN const _pkcs11h_session_t session, IN const CK_ATTRIBUTE * const filter, IN const CK_ULONG filter_attrs, OUT CK_OBJECT_HANDLE **const p_objects, OUT CK_ULONG *p_objects_found ) { /* * THREADING: * session->mutex must be locked */ PKCS11H_BOOL should_FindObjectsFinal = FALSE; CK_OBJECT_HANDLE *objects = NULL; CK_ULONG objects_size = 0; CK_OBJECT_HANDLE objects_buffer[100]; CK_ULONG objects_found; CK_OBJECT_HANDLE oLast = _PKCS11H_INVALID_OBJECT_HANDLE; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (session!=NULL); _PKCS11H_ASSERT (!(filter==NULL && filter_attrs!=0) || filter!=NULL); _PKCS11H_ASSERT (p_objects!=NULL); _PKCS11H_ASSERT (p_objects_found!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_findObjects entry session=%p, filter=%p, filter_attrs=%ld, p_objects=%p, p_objects_found=%p", (void *)session, (void *)filter, filter_attrs, (void *)p_objects, (void *)p_objects_found ); *p_objects = NULL; *p_objects_found = 0; if ( (rv = session->provider->f->C_FindObjectsInit ( session->session_handle, (CK_ATTRIBUTE *)filter, filter_attrs )) != CKR_OK ) { goto cleanup; } should_FindObjectsFinal = TRUE; while ( (rv = session->provider->f->C_FindObjects ( session->session_handle, objects_buffer, sizeof (objects_buffer) / sizeof (CK_OBJECT_HANDLE), &objects_found )) == CKR_OK && objects_found > 0 ) { CK_OBJECT_HANDLE *temp = NULL; /* * Begin workaround * * Workaround iKey bug * It returns the same objects over and over */ if (oLast == objects_buffer[0]) { _PKCS11H_LOG ( PKCS11H_LOG_WARN, "PKCS#11: Bad PKCS#11 C_FindObjects implementation detected, workaround applied" ); break; } oLast = objects_buffer[0]; /* End workaround */ if ( (rv = _pkcs11h_mem_malloc ( (void *)&temp, (objects_size+objects_found) * sizeof (CK_OBJECT_HANDLE) )) != CKR_OK ) { goto cleanup; } if (objects != NULL) { memmove ( temp, objects, objects_size * sizeof (CK_OBJECT_HANDLE) ); } memmove ( temp + objects_size, objects_buffer, objects_found * sizeof (CK_OBJECT_HANDLE) ); if (objects != NULL) { _pkcs11h_mem_free ((void *)&objects); objects = NULL; } objects = temp; objects_size += objects_found; temp = NULL; } if (should_FindObjectsFinal) { session->provider->f->C_FindObjectsFinal ( session->session_handle ); should_FindObjectsFinal = FALSE; } *p_objects = objects; *p_objects_found = objects_size; objects = NULL; objects_size = 0; rv = CKR_OK; cleanup: if (objects != NULL) { _pkcs11h_mem_free ((void *)&objects); objects = NULL; objects_size = 0; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_findObjects return rv=%lu-'%s', *p_objects_found=%ld", rv, pkcs11h_getMessage (rv), *p_objects_found ); return rv; }
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_certificate_deserializeCertificateId ( OUT pkcs11h_certificate_id_t * const p_certificate_id, IN const char * const sz ) { pkcs11h_certificate_id_t certificate_id = NULL; CK_RV rv = CKR_FUNCTION_FAILED; char *p = NULL; char *_sz = NULL; _PKCS11H_ASSERT (p_certificate_id!=NULL); _PKCS11H_ASSERT (sz!=NULL); *p_certificate_id = NULL; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'", (void *)p_certificate_id, sz ); if ( (rv = _pkcs11h_mem_strdup ( (void *)&_sz, sz )) != CKR_OK ) { goto cleanup; } p = _sz; if ((rv = _pkcs11h_certificate_newCertificateId (&certificate_id)) != CKR_OK) { goto cleanup; } if ((p = strrchr (_sz, '/')) == NULL) { rv = CKR_ATTRIBUTE_VALUE_INVALID; goto cleanup; } *p = '\x0'; p++; if ( (rv = pkcs11h_token_deserializeTokenId ( &certificate_id->token_id, _sz )) != CKR_OK ) { goto cleanup; } certificate_id->attrCKA_ID_size = strlen (p)/2; if ( (rv = _pkcs11h_mem_malloc ( (void *)&certificate_id->attrCKA_ID, certificate_id->attrCKA_ID_size) ) != CKR_OK || (rv = _pkcs11h_util_hexToBinary ( certificate_id->attrCKA_ID, p, &certificate_id->attrCKA_ID_size )) != CKR_OK ) { goto cleanup; } *p_certificate_id = certificate_id; certificate_id = NULL; rv = CKR_OK; cleanup: if (certificate_id != NULL) { pkcs11h_certificate_freeCertificateId (certificate_id); certificate_id = NULL; } if (_sz != NULL) { _pkcs11h_mem_free ((void *)&_sz); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_certificate_deserializeCertificateId return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv; }
CK_RV _pkcs11h_token_getTokenId ( IN const CK_TOKEN_INFO_PTR info, OUT pkcs11h_token_id_t * const p_token_id ) { pkcs11h_token_id_t token_id; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (info!=NULL); _PKCS11H_ASSERT (p_token_id!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_token_getTokenId entry p_token_id=%p", (void *)p_token_id ); *p_token_id = NULL; if ((rv = _pkcs11h_token_newTokenId (&token_id)) != CKR_OK) { goto cleanup; } _pkcs11h_util_fixupFixedString ( token_id->label, (char *)info->label, sizeof (info->label) ); _pkcs11h_util_fixupFixedString ( token_id->manufacturerID, (char *)info->manufacturerID, sizeof (info->manufacturerID) ); _pkcs11h_util_fixupFixedString ( token_id->model, (char *)info->model, sizeof (info->model) ); _pkcs11h_util_fixupFixedString ( token_id->serialNumber, (char *)info->serialNumber, sizeof (info->serialNumber) ); strncpy ( token_id->display, token_id->label, sizeof (token_id->display) ); *p_token_id = token_id; token_id = NULL; rv = CKR_OK; cleanup: if (token_id != NULL) { _pkcs11h_mem_free ((void *)&token_id); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_token_getTokenId return rv=%lu-'%s', *p_token_id=%p", rv, pkcs11h_getMessage (rv), (void *)*p_token_id ); return rv; }