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_slotevent_terminate (void) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_slotevent_terminate entry" ); if (_g_pkcs11h_data->slotevent.initialized) { _g_pkcs11h_data->slotevent.should_terminate = TRUE; _pkcs11h_slotevent_notify (); if (_g_pkcs11h_data->slotevent.thread != PKCS11H_THREAD_NULL) { _pkcs11h_threading_threadJoin (&_g_pkcs11h_data->slotevent.thread); } _pkcs11h_slotevent_terminate_force (); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_slotevent_terminate 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" ); }
static PKCS11H_BOOL __pkcs11h_openssl_session_setRSA( IN const pkcs11h_openssl_session_t openssl_session, IN EVP_PKEY * evp ) { PKCS11H_BOOL ret = FALSE; RSA *rsa = NULL; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_session_setRSA - entered openssl_session=%p, evp=%p", (void *)openssl_session, (void *)evp ); if ( (rsa = EVP_PKEY_get1_RSA (evp)) == NULL ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key"); goto cleanup; } RSA_set_method (rsa, __openssl_methods.rsa); RSA_set_ex_data (rsa, __openssl_methods.rsa_index, openssl_session); #if OPENSSL_VERSION_NUMBER < 0x10100001L rsa->flags |= RSA_FLAG_SIGN_VER; #endif #ifdef BROKEN_OPENSSL_ENGINE if (!rsa->engine) { rsa->engine = ENGINE_get_default_RSA (); } ENGINE_set_RSA(ENGINE_get_default_RSA (), &openssl_session->rsa); _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled"); #endif ret = TRUE; cleanup: if (rsa != NULL) { RSA_free (rsa); rsa = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_session_setRSA - return ret=%d", ret ); return ret; }
CK_RV _pkcs11h_session_release ( IN const _pkcs11h_session_t session ) { #if defined(ENABLE_PKCS11H_THREADING) PKCS11H_BOOL mutex_locked = TRUE; #endif CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (session!=NULL); _PKCS11H_ASSERT (session->reference_count>=0); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_release entry session=%p", (void *)session ); #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock (&session->mutex)) != CKR_OK) { goto cleanup; } mutex_locked = TRUE; #endif /* * Never logout for now */ if (session->reference_count > 0) { session->reference_count--; } rv = CKR_OK; #if defined(ENABLE_PKCS11H_THREADING) cleanup: if (mutex_locked) { _pkcs11h_threading_mutexRelease (&session->mutex); mutex_locked = FALSE; } #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_session_release return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); 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; }
PKCS11H_BOOL _pkcs11h_openssl_terminate (void) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_openssl_terminate" ); #ifndef OPENSSL_NO_RSA if (__openssl_methods.rsa != NULL) { RSA_meth_free (__openssl_methods.rsa); __openssl_methods.rsa = NULL; } #endif #ifndef OPENSSL_NO_DSA if (__openssl_methods.dsa != NULL) { DSA_meth_free (__openssl_methods.dsa); __openssl_methods.dsa = NULL; } #endif #ifdef __ENABLE_EC if (__openssl_methods.ecdsa != NULL) { ECDSA_METHOD_free(__openssl_methods.ecdsa); __openssl_methods.ecdsa = NULL; } #endif return TRUE; }
static PKCS11H_BOOL __pkcs11h_hooks_default_pin_prompt ( IN void * const global_data, IN void * const user_data, IN const pkcs11h_token_id_t token, IN const unsigned retry, OUT char * const pin, IN const size_t pin_max ) { /*_PKCS11H_ASSERT (global_data) NOT NEEDED */ /*_PKCS11H_ASSERT (user_data) NOT NEEDED */ _PKCS11H_ASSERT (token!=NULL); (void)global_data; (void)user_data; (void)retry; (void)pin; (void)pin_max; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_hooks_default_pin_prompt global_data=%p, user_data=%p, display='%s'", global_data, user_data, token->display ); return FALSE; }
static void __pkcs11h_openssl_ex_data_free ( void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp ) { pkcs11h_openssl_session_t openssl_session = (pkcs11h_openssl_session_t)ptr; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_ex_data_free entered - parent=%p, ptr=%p, ad=%p, idx=%d, argl=%ld, argp=%p", parent, ptr, (void *)ad, idx, argl, argp ); if (openssl_session != NULL) { pkcs11h_openssl_freeSession (openssl_session); } }
static int __pkcs11h_openssl_ex_data_dup ( CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, int idx, long argl, void *argp ) { #else int __pkcs11h_openssl_ex_data_dup ( CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, void *from_d, int idx, long argl, void *argp ) { #endif pkcs11h_openssl_session_t openssl_session; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_ex_data_dup entered - to=%p, from=%p, from_d=%p, idx=%d, argl=%ld, argp=%p", (void *)to, (void *)from, from_d, idx, argl, argp ); _PKCS11H_ASSERT (from_d!=NULL); if ((openssl_session = *(pkcs11h_openssl_session_t *)from_d) != NULL) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_ex_data_dup session refcount=%d", openssl_session->reference_count ); openssl_session->reference_count++; } return 1; }
X509 * pkcs11h_openssl_session_getX509 ( IN const pkcs11h_openssl_session_t openssl_session ) { X509 *x509 = NULL; PKCS11H_BOOL ok = FALSE; _PKCS11H_ASSERT (openssl_session!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_session_getX509 - entry openssl_session=%p", (void *)openssl_session ); if ( openssl_session->x509 == NULL && (openssl_session->x509 = pkcs11h_openssl_getX509 (openssl_session->certificate)) == NULL ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object"); goto cleanup; } if ((x509 = X509_dup (openssl_session->x509)) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot duplicate certificate object"); goto cleanup; } ok = TRUE; cleanup: if (!ok) { if (x509 != NULL) { X509_free (x509); x509 = NULL; } } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_session_getX509 - return x509=%p", (void *)x509 ); return x509; }
CK_RV pkcs11h_token_duplicateTokenId ( OUT pkcs11h_token_id_t * const to, IN const pkcs11h_token_id_t from ) { CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (_g_pkcs11h_data!=NULL); _PKCS11H_ASSERT (_g_pkcs11h_data->initialized); _PKCS11H_ASSERT (to!=NULL); _PKCS11H_ASSERT (from!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_duplicateTokenId entry to=%p form=%p", (void *)to, (void *)from ); *to = NULL; if ( (rv = _pkcs11h_mem_duplicate ( (void*)to, NULL, from, sizeof (struct pkcs11h_token_id_s) )) != CKR_OK ) { goto cleanup; } rv = CKR_OK; cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_duplicateTokenId return rv=%lu-'%s', *to=%p", rv, pkcs11h_getMessage (rv), (void *)*to ); return rv; }
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 PKCS11H_BOOL __pkcs11h_openssl_session_setDSA( IN const pkcs11h_openssl_session_t openssl_session, IN EVP_PKEY * evp ) { PKCS11H_BOOL ret = FALSE; DSA *dsa = NULL; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_session_setDSA - entered openssl_session=%p, evp=%p", (void *)openssl_session, (void *)evp ); if ( (dsa = EVP_PKEY_get1_DSA (evp)) == NULL ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get DSA key"); goto cleanup; } DSA_set_method (dsa, __openssl_methods.dsa); DSA_set_ex_data (dsa, __openssl_methods.dsa_index, openssl_session); ret = TRUE; cleanup: if (dsa != NULL) { DSA_free (dsa); dsa = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_session_setDSA - return ret=%d", ret ); return ret; }
static PKCS11H_BOOL __pkcs11h_openssl_session_setECDSA( IN const pkcs11h_openssl_session_t openssl_session, IN EVP_PKEY * evp ) { PKCS11H_BOOL ret = FALSE; EC_KEY *ec = NULL; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_session_setECDSA - entered openssl_session=%p, evp=%p", (void *)openssl_session, (void *)evp ); if ( (ec = EVP_PKEY_get1_EC_KEY (evp)) == NULL ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get EC key"); goto cleanup; } ECDSA_set_method (ec, __openssl_methods.ecdsa); ECDSA_set_ex_data (ec, __openssl_methods.ecdsa_index, openssl_session); ret = TRUE; cleanup: if (ec != NULL) { EC_KEY_free (ec); ec = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_session_setECDSA - return ret=%d", ret ); return ret; }
CK_RV _pkcs11h_slotevent_notify (void) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_slotevent_notify entry" ); if (_g_pkcs11h_data->slotevent.initialized) { _g_pkcs11h_data->slotevent.skip_event = TRUE; _pkcs11h_threading_condSignal (&_g_pkcs11h_data->slotevent.cond_event); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_slotevent_notify return" ); return CKR_OK; }
CK_RV _pkcs11h_slotevent_init (void) { CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_slotevent_init entry" ); if (!_g_pkcs11h_data->slotevent.initialized) { if ((rv = _pkcs11h_threading_condInit (&_g_pkcs11h_data->slotevent.cond_event)) != CKR_OK) { goto cleanup; } if ( (rv = _pkcs11h_threading_threadStart ( &_g_pkcs11h_data->slotevent.thread, __pkcs11h_slotevent_manager, NULL )) != CKR_OK ) { goto cleanup; } _g_pkcs11h_data->slotevent.initialized = TRUE; } rv = CKR_OK; cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_slotevent_init return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); 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; }
EVP_PKEY * pkcs11h_openssl_session_getEVP ( IN const pkcs11h_openssl_session_t openssl_session ) { X509 *x509 = NULL; EVP_PKEY *evp = NULL; EVP_PKEY *ret = NULL; _PKCS11H_ASSERT (openssl_session!=NULL); _PKCS11H_ASSERT (!openssl_session->initialized); _PKCS11H_ASSERT (openssl_session!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_session_getEVP - entry openssl_session=%p", (void *)openssl_session ); /* * Dup x509 so RSA will not hold session x509 */ if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object"); goto cleanup; } if ((evp = X509_get_pubkey (x509)) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key"); goto cleanup; } if (0) { } #ifndef OPENSSL_NO_RSA else if (EVP_PKEY_id (evp) == EVP_PKEY_RSA) { if (!__pkcs11h_openssl_session_setRSA(openssl_session, evp)) { goto cleanup; } } #endif #ifndef OPENSSL_NO_RSA else if (EVP_PKEY_id (evp) == EVP_PKEY_DSA) { if (!__pkcs11h_openssl_session_setDSA(openssl_session, evp)) { goto cleanup; } } #endif #ifdef __ENABLE_EC else if (evp->type == EVP_PKEY_EC) { if (!__pkcs11h_openssl_session_setECDSA(openssl_session, evp)) { goto cleanup; } } #endif else { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm %d", EVP_PKEY_id (evp)); goto cleanup; } #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock); #endif openssl_session->reference_count++; #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock); #endif openssl_session->initialized = TRUE; ret = evp; evp = NULL; cleanup: /* * openssl objects have reference * count, so release them */ if (evp != NULL) { EVP_PKEY_free (evp); evp = NULL; } if (x509 != NULL) { X509_free (x509); x509 = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_session_getEVP - return ret=%p", (void *)ret ); 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; }
PKCS11H_BOOL _pkcs11h_openssl_initialize (void) { PKCS11H_BOOL ret = FALSE; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_openssl_initialize - entered" ); #ifndef OPENSSL_NO_RSA if (__openssl_methods.rsa != NULL) { RSA_meth_free (__openssl_methods.rsa); } if ((__openssl_methods.rsa = RSA_meth_dup (RSA_get_default_method ())) == NULL) { goto cleanup; } RSA_meth_set1_name (__openssl_methods.rsa, "pkcs11h"); RSA_meth_set_priv_dec (__openssl_methods.rsa, __pkcs11h_openssl_rsa_dec); RSA_meth_set_priv_enc (__openssl_methods.rsa, __pkcs11h_openssl_rsa_enc); RSA_meth_set_flags (__openssl_methods.rsa, RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY); __openssl_methods.rsa_index = RSA_get_ex_new_index ( 0, "pkcs11h", NULL, __pkcs11h_openssl_ex_data_dup, __pkcs11h_openssl_ex_data_free ); #endif #ifndef OPENSSL_NO_DSA if (__openssl_methods.dsa != NULL) { DSA_meth_free (__openssl_methods.dsa); } __openssl_methods.dsa = DSA_meth_dup (DSA_get_default_method ()); DSA_meth_set1_name (__openssl_methods.dsa, "pkcs11h"); DSA_meth_set_sign (__openssl_methods.dsa, __pkcs11h_openssl_dsa_do_sign); __openssl_methods.dsa_index = DSA_get_ex_new_index ( 0, "pkcs11h", NULL, __pkcs11h_openssl_ex_data_dup, __pkcs11h_openssl_ex_data_free ); #endif #ifdef __ENABLE_EC if (__openssl_methods.ecdsa != NULL) { ECDSA_METHOD_free(__openssl_methods.ecdsa); } __openssl_methods.ecdsa = ECDSA_METHOD_new ((ECDSA_METHOD *)ECDSA_get_default_method ()); ECDSA_METHOD_set_name(__openssl_methods.ecdsa, "pkcs11h"); ECDSA_METHOD_set_sign(__openssl_methods.ecdsa, __pkcs11h_openssl_ecdsa_do_sign); __openssl_methods.ecdsa_index = ECDSA_get_ex_new_index ( 0, "pkcs11h", NULL, __pkcs11h_openssl_ex_data_dup, __pkcs11h_openssl_ex_data_free ); #endif ret = TRUE; cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: _pkcs11h_openssl_initialize - return %d", ret ); return ret; }
static void * __pkcs11h_slotevent_manager ( IN void *p ) { PKCS11H_BOOL first_time = TRUE; (void)p; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_slotevent_manager entry" ); /* * Trigger hook, so application may * depend on initial slot change */ _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Calling slotevent hook" ); _g_pkcs11h_data->hooks.slotevent (_g_pkcs11h_data->hooks.slotevent_data); while ( first_time || /* Must enter wait or mutex will never be free */ !_g_pkcs11h_data->slotevent.should_terminate ) { _pkcs11h_provider_t current_provider; first_time = FALSE; /* * Start each provider thread * if not already started. * This is required in order to allow * adding new providers. */ _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_slotevent_manager examine provider list" ); for ( current_provider = _g_pkcs11h_data->providers; current_provider != NULL; current_provider = current_provider->next ) { if (current_provider->enabled) { if (current_provider->slotevent_thread == PKCS11H_THREAD_NULL) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_slotevent_manager found enabled provider without thread" ); _pkcs11h_threading_threadStart ( ¤t_provider->slotevent_thread, __pkcs11h_slotevent_provider, current_provider ); } } else { if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_slotevent_manager found disabled provider with thread" ); _pkcs11h_threading_threadJoin (¤t_provider->slotevent_thread); } } } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_slotevent_manager waiting for slotevent" ); _pkcs11h_threading_condWait (&_g_pkcs11h_data->slotevent.cond_event, PKCS11H_COND_INFINITE); if (_g_pkcs11h_data->slotevent.skip_event) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Slotevent skipping event" ); _g_pkcs11h_data->slotevent.skip_event = FALSE; } else { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Calling slotevent hook" ); _g_pkcs11h_data->hooks.slotevent (_g_pkcs11h_data->hooks.slotevent_data); } } { _pkcs11h_provider_t current_provider; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_slotevent_manager joining threads" ); for ( current_provider = _g_pkcs11h_data->providers; current_provider != NULL; current_provider = current_provider->next ) { if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) { _pkcs11h_threading_threadJoin (¤t_provider->slotevent_thread); } } } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_slotevent_manager return" ); return NULL; }
CK_RV pkcs11h_plugAndPlay (void) { #if defined(ENABLE_PKCS11H_DEBUG) #if defined(_WIN32) int mypid = 0; #else pid_t mypid = getpid (); #endif #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_plugAndPlay entry pid=%d", mypid ); if (_g_pkcs11h_data != NULL && _g_pkcs11h_data->initialized) { _pkcs11h_provider_t current; #if defined(ENABLE_PKCS11H_SLOTEVENT) PKCS11H_BOOL slot_event_active = FALSE; #endif #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global); #endif for ( current = _g_pkcs11h_data->providers; current != NULL; current = current->next ) { if (current->enabled) { current->f->C_Finalize (NULL); } } #if defined(ENABLE_PKCS11H_SLOTEVENT) if (_g_pkcs11h_data->slotevent.initialized) { slot_event_active = TRUE; _pkcs11h_slotevent_terminate (); } #endif for ( current = _g_pkcs11h_data->providers; current != NULL; current = current->next ) { if (current->enabled) { current->f->C_Initialize (NULL); } } #if defined(ENABLE_PKCS11H_SLOTEVENT) if (slot_event_active) { _pkcs11h_slotevent_init (); } #endif #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.global); #endif } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_plugAndPlay 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 int __pkcs11h_openssl_rsa_dec ( IN int flen, IN unsigned char *from, OUT unsigned char *to, IN OUT RSA *rsa, IN int padding ) { #else static int __pkcs11h_openssl_rsa_dec ( IN int flen, IN const unsigned char *from, OUT unsigned char *to, IN OUT RSA *rsa, IN int padding ) { #endif pkcs11h_certificate_t certificate = __pkcs11h_openssl_rsa_get_pkcs11h_certificate (rsa); PKCS11H_BOOL session_locked = FALSE; CK_MECHANISM_TYPE mech = CKM_RSA_PKCS; CK_RV rv = CKR_FUNCTION_FAILED; size_t tlen = (size_t)flen; _PKCS11H_ASSERT (from!=NULL); _PKCS11H_ASSERT (to!=NULL); _PKCS11H_ASSERT (rsa!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_rsa_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d", flen, from, to, (void *)rsa, padding ); switch (padding) { case RSA_PKCS1_PADDING: mech = CKM_RSA_PKCS; break; case RSA_PKCS1_OAEP_PADDING: mech = CKM_RSA_PKCS_OAEP; break; case RSA_SSLV23_PADDING: rv = CKR_MECHANISM_INVALID; break; case RSA_NO_PADDING: rv = CKR_MECHANISM_INVALID; break; } if (rv == CKR_MECHANISM_INVALID) goto cleanup; if ((rv = pkcs11h_certificate_lockSession (certificate)) != CKR_OK) { goto cleanup; } session_locked = TRUE; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Performing decryption" ); if ( (rv = pkcs11h_certificate_decryptAny ( certificate, mech, from, flen, to, &tlen )) != CKR_OK ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform decryption %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } rv = CKR_OK; cleanup: if (session_locked) { pkcs11h_certificate_releaseSession (certificate); session_locked = FALSE; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_rsa_dec - return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv == CKR_OK ? (int)tlen : -1; }
RSA * pkcs11h_openssl_session_getRSA ( IN const pkcs11h_openssl_session_t openssl_session ) { #ifndef OPENSSL_NO_RSA RSA *rsa = NULL; RSA *ret = NULL; EVP_PKEY *evp = NULL; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_session_getRSA - entry openssl_session=%p", (void *)openssl_session ); if ((evp = pkcs11h_openssl_session_getEVP(openssl_session)) == NULL) { goto cleanup; } if (EVP_PKEY_id (evp) != EVP_PKEY_RSA) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm"); goto cleanup; } if ( (rsa = EVP_PKEY_get1_RSA (evp)) == NULL ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key"); goto cleanup; } ret = rsa; rsa = NULL; cleanup: /* * openssl objects have reference * count, so release them */ if (rsa != NULL) { RSA_free (rsa); rsa = NULL; } if (evp != NULL) { EVP_PKEY_free (evp); evp = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_session_getRSA - return ret=%p", (void *)rsa ); return ret; #else return NULL; #endif }
static int __pkcs11h_openssl_rsa_enc ( IN int flen, IN unsigned char *from, OUT unsigned char *to, IN OUT RSA *rsa, IN int padding ) { #else static int __pkcs11h_openssl_rsa_enc ( IN int flen, IN const unsigned char *from, OUT unsigned char *to, IN OUT RSA *rsa, IN int padding ) { #endif pkcs11h_certificate_t certificate = __pkcs11h_openssl_rsa_get_pkcs11h_certificate (rsa); PKCS11H_BOOL session_locked = FALSE; CK_RV rv = CKR_FUNCTION_FAILED; size_t tlen; _PKCS11H_ASSERT (from!=NULL); _PKCS11H_ASSERT (to!=NULL); _PKCS11H_ASSERT (rsa!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_rsa_enc entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d", flen, from, to, (void *)rsa, padding ); if (padding != RSA_PKCS1_PADDING) { rv = CKR_MECHANISM_INVALID; goto cleanup; } tlen = (size_t)RSA_size(rsa); if ((rv = pkcs11h_certificate_lockSession (certificate)) != CKR_OK) { goto cleanup; } session_locked = TRUE; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Performing signature" ); if ( (rv = pkcs11h_certificate_signAny ( certificate, CKM_RSA_PKCS, from, flen, to, &tlen )) != CKR_OK ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } rv = CKR_OK; cleanup: if (session_locked) { pkcs11h_certificate_releaseSession (certificate); session_locked = FALSE; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_rsa_enc - return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv == CKR_OK ? (int)tlen : -1; }
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; }
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; }