CK_RV _pkcs11h_mem_duplicate ( OUT const void * * const dest, OUT size_t * const p_dest_size, IN const void * const src, IN const size_t mem_size ) { CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (dest!=NULL); /*_PKCS11H_ASSERT (dest_size!=NULL); NOT NEEDED*/ _PKCS11H_ASSERT (!(mem_size!=0&&src==NULL)); *dest = NULL; if (p_dest_size != NULL) { *p_dest_size = 0; } if (src != NULL) { if ((rv = _pkcs11h_mem_malloc (dest, mem_size)) != CKR_OK) { goto cleanup; } if (p_dest_size != NULL) { *p_dest_size = mem_size; } memmove ((void*)*dest, src, mem_size); } rv = CKR_OK; cleanup: return rv; }
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; }
static RSA_METHOD * RSA_meth_dup (const RSA_METHOD *meth) { RSA_METHOD *ret = NULL; CK_RV rv; rv = _pkcs11h_mem_malloc ((void *)&ret, sizeof (RSA_METHOD)); if (rv != CKR_OK) { goto cleanup; } memmove (ret, meth, sizeof (RSA_METHOD)); cleanup: return ret; }
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; }
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 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; }
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_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; }
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_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_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_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_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; }
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_session_getObjectAttributes ( IN const _pkcs11h_session_t session, IN const CK_OBJECT_HANDLE object, IN OUT const CK_ATTRIBUTE_PTR attrs, IN const unsigned count ) { /* * THREADING: * session->mutex must be locked */ CK_RV rv = CKR_FUNCTION_FAILED; unsigned i; _PKCS11H_ASSERT (session!=NULL); _PKCS11H_ASSERT (attrs!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_getObjectAttributes entry session=%p, object=%ld, attrs=%p, count=%u", (void *)session, object, (void *)attrs, count ); if ( (rv = session->provider->f->C_GetAttributeValue ( session->session_handle, object, attrs, count )) != CKR_OK ) { goto cleanup; } for (i=0;i<count;i++) { if (attrs[i].ulValueLen == (CK_ULONG)-1) { rv = CKR_ATTRIBUTE_VALUE_INVALID; goto cleanup; } else if (attrs[i].ulValueLen == 0) { attrs[i].pValue = NULL; } else { if ( (rv = _pkcs11h_mem_malloc ( (void *)&attrs[i].pValue, attrs[i].ulValueLen )) != CKR_OK ) { goto cleanup; } } } if ( (rv = session->provider->f->C_GetAttributeValue ( session->session_handle, object, attrs, count )) != CKR_OK ) { goto cleanup; } cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_getObjectAttributes return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv; }