void pkcs11h_openssl_freeSession ( IN const pkcs11h_openssl_session_t openssl_session ) { CK_RV rv; _PKCS11H_ASSERT (openssl_session!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_freeSession - entry openssl_session=%p, count=%d", (void *)openssl_session, openssl_session->reference_count ); #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock)) != CKR_OK) { _PKCS11H_LOG (PKCS11H_LOG_ERROR, "PKCS#11: Cannot lock mutex %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } #endif openssl_session->reference_count--; #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock); #endif _PKCS11H_ASSERT (openssl_session->reference_count>=0); if (openssl_session->reference_count == 0) { #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexFree(&openssl_session->reference_count_lock); #endif if (openssl_session->cleanup_hook != NULL) { openssl_session->cleanup_hook (openssl_session->certificate); } if (openssl_session->x509 != NULL) { X509_free (openssl_session->x509); openssl_session->x509 = NULL; } if (openssl_session->certificate != NULL) { pkcs11h_certificate_freeCertificate (openssl_session->certificate); openssl_session->certificate = NULL; } _pkcs11h_mem_free ((void *)&openssl_session); } cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_freeSession - return" ); }
CK_RV _pkcs11h_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; }
bool pkcs11_addProvider( const char *const provider, const bool protected_auth, const unsigned private_mode, const bool cert_private ) { CK_RV rv = CKR_OK; ASSERT(provider!=NULL); dmsg( D_PKCS11_DEBUG, "PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x", provider, private_mode ); msg( M_INFO, "PKCS#11: Adding PKCS#11 provider '%s'", provider ); if ( (rv = pkcs11h_addProvider( provider, provider, protected_auth, private_mode, PKCS11H_SLOTEVENT_METHOD_AUTO, 0, cert_private )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage(rv)); } dmsg( D_PKCS11_DEBUG, "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'", rv, pkcs11h_getMessage(rv) ); return rv == CKR_OK; }
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; }
int pkcs11_management_id_count() { pkcs11h_certificate_id_list_t id_list = NULL; pkcs11h_certificate_id_list_t t = NULL; CK_RV rv = CKR_OK; int count = 0; dmsg( D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_count - entered" ); if ( (rv = pkcs11h_certificate_enumCertificateIds( PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } for (count = 0, t = id_list; t != NULL; t = t->next) { count++; } cleanup: if (id_list != NULL) { pkcs11h_certificate_freeCertificateIdList(id_list); id_list = NULL; } dmsg( D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_count - return count=%d", count ); return count; }
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; }
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; }
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; }
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; }
CK_RV pkcs11h_token_serializeTokenId ( OUT char * const sz, IN OUT size_t *max, IN const pkcs11h_token_id_t token_id ) { const char *sources[5]; CK_RV rv = CKR_FUNCTION_FAILED; size_t n; int e; /*_PKCS11H_ASSERT (sz!=NULL); Not required*/ _PKCS11H_ASSERT (max!=NULL); _PKCS11H_ASSERT (token_id!=NULL); { /* Must be after assert */ sources[0] = token_id->manufacturerID; sources[1] = token_id->model; sources[2] = token_id->serialNumber; sources[3] = token_id->label; sources[4] = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_serializeTokenId entry sz=%p, *max="P_Z", token_id=%p", sz, sz != NULL ? *max : 0, (void *)token_id ); n = 0; for (e=0;sources[e] != NULL;e++) { size_t t; if ( (rv = _pkcs11h_util_escapeString ( NULL, sources[e], &t, __PKCS11H_SERIALIZE_INVALID_CHARS )) != CKR_OK ) { goto cleanup; } n+=t; } if (sz != NULL) { if (*max < n) { rv = CKR_ATTRIBUTE_VALUE_INVALID; goto cleanup; } n = 0; for (e=0;sources[e] != NULL;e++) { size_t t = *max-n; if ( (rv = _pkcs11h_util_escapeString ( sz+n, sources[e], &t, __PKCS11H_SERIALIZE_INVALID_CHARS )) != CKR_OK ) { goto cleanup; } n+=t; sz[n-1] = '/'; } sz[n-1] = '\x0'; } *max = n; rv = CKR_OK; cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_serializeTokenId return rv=%lu-'%s', *max="P_Z", sz='%s'", rv, pkcs11h_getMessage (rv), *max, sz ); 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_token_logout ( IN const pkcs11h_token_id_t token_id ) { #if defined(ENABLE_PKCS11H_THREADING) PKCS11H_BOOL mutex_locked = FALSE; #endif CK_RV rv = CKR_FUNCTION_FAILED; _pkcs11h_session_t session = NULL; _PKCS11H_ASSERT (token_id!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_logout entry token_id=%p\n", (void *)token_id ); if ( (rv = _pkcs11h_session_getSessionByTokenId ( token_id, &session )) != CKR_OK ) { goto cleanup; } #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock (&session->mutex)) != CKR_OK) { goto cleanup; } mutex_locked = TRUE; #endif if ( (rv = _pkcs11h_session_logout (session)) != CKR_OK ) { goto cleanup; } rv = CKR_OK; cleanup: #if defined(ENABLE_PKCS11H_THREADING) if (mutex_locked) { _pkcs11h_threading_mutexRelease (&session->mutex); mutex_locked = FALSE; } #endif if (session != NULL) { _pkcs11h_session_release (session); session = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_logout 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; }
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; }
bool pkcs11_initialize( const bool protected_auth, const int nPINCachePeriod ) { CK_RV rv = CKR_FUNCTION_FAILED; dmsg( D_PKCS11_DEBUG, "PKCS#11: pkcs11_initialize - entered" ); if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((rv = pkcs11h_initialize()) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level())); if ((rv = pkcs11h_setForkMode(TRUE)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((rv = pkcs11h_setTokenPromptHook(_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((rv = pkcs11h_setProtectedAuthentication(protected_auth)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((rv = pkcs11h_setPINCachePeriod(nPINCachePeriod)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } rv = CKR_OK; cleanup: dmsg( D_PKCS11_DEBUG, "PKCS#11: pkcs11_initialize - return %ld-'%s'", rv, pkcs11h_getMessage(rv) ); return rv == CKR_OK; }
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_logout (void) { _pkcs11h_session_t current_session = NULL; CK_RV rv = CKR_OK; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_logout entry" ); if (_g_pkcs11h_data == NULL || !_g_pkcs11h_data->initialized) { goto cleanup; } for ( current_session = _g_pkcs11h_data->sessions; current_session != NULL; current_session = current_session->next ) { CK_RV _rv; #if defined(ENABLE_PKCS11H_THREADING) if ((_rv = _pkcs11h_threading_mutexLock (¤t_session->mutex)) == CKR_OK) { #else { #endif _rv = _pkcs11h_session_logout (current_session); #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexRelease (¤t_session->mutex); #endif } if (_rv != CKR_OK) { rv = _rv; } } cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_logout return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv; } /*======================================================================* * COMMON INTERNAL INTERFACE *======================================================================*/ void _pkcs11h_log ( IN const unsigned flags, IN const char * const format, IN ... ) { va_list args; _PKCS11H_ASSERT (format!=NULL); va_start (args, format); if ( _g_pkcs11h_data != NULL && _g_pkcs11h_data->initialized ) { if (__PKCS11H_MSG_LEVEL_TEST (flags)) { if (_g_pkcs11h_data->hooks.log == NULL) { __pkcs11h_hooks_default_log ( NULL, flags, format, args ); } else { _g_pkcs11h_data->hooks.log ( _g_pkcs11h_data->hooks.log_data, flags, format, args ); } } } va_end (args); }
CK_RV pkcs11h_token_login ( IN const pkcs11h_token_id_t token_id, IN const PKCS11H_BOOL readonly, IN const char * const pin ) { #if defined(ENABLE_PKCS11H_THREADING) PKCS11H_BOOL mutex_locked = FALSE; #endif CK_SLOT_ID slot = _PKCS11H_INVALID_SLOT_ID; CK_ULONG pin_size = 0; CK_RV rv = CKR_FUNCTION_FAILED; _pkcs11h_session_t session = NULL; _PKCS11H_ASSERT (token_id!=NULL); /*_PKCS11H_ASSERT (pin!=NULL); NOT NEEDED*/ _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_login entry token_id=%p, readonly=%d\n", (void *)token_id, readonly ? 1 : 0 ); if (pin != NULL) { pin_size = strlen (pin); } if ( (rv = _pkcs11h_session_getSessionByTokenId ( token_id, &session )) != CKR_OK ) { goto cleanup; } #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock (&session->mutex)) != CKR_OK) { goto cleanup; } mutex_locked = TRUE; #endif if ( (rv = _pkcs11h_session_logout (session)) != CKR_OK || (rv = _pkcs11h_session_reset (session, NULL, 0, &slot)) != CKR_OK || (rv = __pkcs11h_session_touch (session)) != CKR_OK || (rv = session->provider->f->C_OpenSession ( slot, ( CKF_SERIAL_SESSION | (readonly ? 0 : CKF_RW_SESSION) ), NULL_PTR, NULL_PTR, &session->session_handle )) != CKR_OK ) { goto cleanup; } if ( (rv = session->provider->f->C_Login ( session->session_handle, CKU_USER, (CK_UTF8CHAR_PTR)pin, pin_size )) != CKR_OK ) { if (rv != CKR_USER_ALREADY_LOGGED_IN) { goto cleanup; } } rv = CKR_OK; cleanup: #if defined(ENABLE_PKCS11H_THREADING) if (mutex_locked) { _pkcs11h_threading_mutexRelease (&session->mutex); mutex_locked = FALSE; } #endif if (session != NULL) { _pkcs11h_session_release (session); session = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_login 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_token_ensureAccess ( IN const pkcs11h_token_id_t token_id, IN void * const user_data, IN const unsigned mask_prompt ) { #if defined(ENABLE_PKCS11H_THREADING) PKCS11H_BOOL mutex_locked = FALSE; #endif _pkcs11h_session_t session = NULL; CK_RV rv = CKR_FUNCTION_FAILED; CK_SLOT_ID slot; _PKCS11H_ASSERT (_g_pkcs11h_data!=NULL); _PKCS11H_ASSERT (_g_pkcs11h_data->initialized); _PKCS11H_ASSERT (token_id!=NULL); /*_PKCS11H_ASSERT (user_data) NOT NEEDED */ _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_ensureAccess entry token_id=%p, user_data=%p, mask_prompt=%08x", (void *)token_id, user_data, mask_prompt ); if ( (rv = _pkcs11h_session_getSessionByTokenId ( token_id, &session )) != CKR_OK ) { goto cleanup; } #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock (&session->mutex)) != CKR_OK) { goto cleanup; } mutex_locked = TRUE; #endif if ( (rv = _pkcs11h_session_reset ( session, user_data, mask_prompt, &slot )) != CKR_OK ) { goto cleanup; } rv = CKR_OK; cleanup: #if defined(ENABLE_PKCS11H_THREADING) if (mutex_locked) { _pkcs11h_threading_mutexRelease (&session->mutex); mutex_locked = FALSE; } #endif if (session != NULL) { _pkcs11h_session_release (session); session = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_token_ensureAccess return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv; }
int tls_ctx_use_pkcs11( struct tls_root_ctx *const ssl_ctx, bool pkcs11_id_management, const char *const pkcs11_id ) { pkcs11h_certificate_id_t certificate_id = NULL; pkcs11h_certificate_t certificate = NULL; CK_RV rv = CKR_OK; bool ok = false; ASSERT(ssl_ctx!=NULL); ASSERT(pkcs11_id_management || pkcs11_id!=NULL); dmsg( D_PKCS11_DEBUG, "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'", (void *)ssl_ctx, pkcs11_id_management ? 1 : 0, pkcs11_id ); if (pkcs11_id_management) { struct user_pass id_resp; CLEAR(id_resp); id_resp.defined = false; id_resp.nocache = true; openvpn_snprintf( id_resp.username, sizeof(id_resp.username), "Please specify PKCS#11 id to use" ); if ( !get_user_pass( &id_resp, NULL, "pkcs11-id-request", GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_STR|GET_USER_PASS_NOFATAL ) ) { goto cleanup; } if ( (rv = pkcs11h_certificate_deserializeCertificateId( &certificate_id, id_resp.password )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } } else { if ( (rv = pkcs11h_certificate_deserializeCertificateId( &certificate_id, pkcs11_id )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } } if ( (rv = pkcs11h_certificate_create( certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, PKCS11H_PIN_CACHE_INFINITE, &certificate )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ( (pkcs11_init_tls_session( certificate, ssl_ctx )) ) { /* Handled by SSL context free */ certificate = NULL; goto cleanup; } /* Handled by SSL context free */ certificate = NULL; ok = true; cleanup: if (certificate != NULL) { pkcs11h_certificate_freeCertificate(certificate); certificate = NULL; } if (certificate_id != NULL) { pkcs11h_certificate_freeCertificateId(certificate_id); certificate_id = NULL; } dmsg( D_PKCS11_DEBUG, "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld", ok ? 1 : 0, rv ); return ok ? 1 : 0; }
CK_RV pkcs11h_certificate_serializeCertificateId ( OUT char * const sz, IN OUT size_t *max, IN const pkcs11h_certificate_id_t certificate_id ) { CK_RV rv = CKR_FUNCTION_FAILED; size_t saved_max = 0; size_t n = 0; size_t _max = 0; /*_PKCS11H_ASSERT (sz!=NULL); Not required */ _PKCS11H_ASSERT (max!=NULL); _PKCS11H_ASSERT (certificate_id!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_certificate_serializeCertificateId entry sz=%p, *max="P_Z", certificate_id=%p", sz, sz != NULL ? *max : 0, (void *)certificate_id ); if (sz != NULL) { saved_max = n = *max; } *max = 0; if ( (rv = pkcs11h_token_serializeTokenId ( sz, &n, certificate_id->token_id )) != CKR_OK ) { goto cleanup; } _max = n + certificate_id->attrCKA_ID_size*2 + 1; if (sz != NULL) { if (saved_max < _max) { rv = CKR_ATTRIBUTE_VALUE_INVALID; goto cleanup; } sz[n-1] = '/'; if (certificate_id->attrCKA_ID) { rv = _pkcs11h_util_binaryToHex ( sz+n, saved_max-n, certificate_id->attrCKA_ID, certificate_id->attrCKA_ID_size ); } } *max = _max; rv = CKR_OK; cleanup: _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_certificate_serializeCertificateId return rv=%lu-'%s', *max="P_Z", sz='%s'", rv, pkcs11h_getMessage (rv), *max, sz ); 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; }
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; }
bool pkcs11_management_id_get( const int index, char **id, char **base64 ) { pkcs11h_certificate_id_list_t id_list = NULL; pkcs11h_certificate_id_list_t entry = NULL; #if 0 /* certificate_id seems to be unused -- JY */ pkcs11h_certificate_id_t certificate_id = NULL; #endif pkcs11h_certificate_t certificate = NULL; CK_RV rv = CKR_OK; unsigned char *certificate_blob = NULL; size_t certificate_blob_size = 0; size_t max; char *internal_id = NULL; char *internal_base64 = NULL; int count = 0; bool success = false; ASSERT(id!=NULL); ASSERT(base64!=NULL); dmsg( D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - entered index=%d", index ); *id = NULL; *base64 = NULL; if ( (rv = pkcs11h_certificate_enumCertificateIds( PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } entry = id_list; count = 0; while (entry != NULL && count != index) { count++; entry = entry->next; } if (entry == NULL) { dmsg( D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - no certificate at index=%d", index ); goto cleanup; } if ( (rv = pkcs11h_certificate_serializeCertificateId( NULL, &max, entry->certificate_id )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((internal_id = (char *)malloc(max)) == NULL) { msg(M_FATAL, "PKCS#11: Cannot allocate memory"); goto cleanup; } if ( (rv = pkcs11h_certificate_serializeCertificateId( internal_id, &max, entry->certificate_id )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ( (rv = pkcs11h_certificate_create( entry->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, PKCS11H_PIN_CACHE_INFINITE, &certificate )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ( (rv = pkcs11h_certificate_getCertificateBlob( certificate, NULL, &certificate_blob_size )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((certificate_blob = (unsigned char *)malloc(certificate_blob_size)) == NULL) { msg(M_FATAL, "PKCS#11: Cannot allocate memory"); goto cleanup; } if ( (rv = pkcs11h_certificate_getCertificateBlob( certificate, certificate_blob, &certificate_blob_size )) != CKR_OK ) { msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if (openvpn_base64_encode(certificate_blob, certificate_blob_size, &internal_base64) == -1) { msg(M_WARN, "PKCS#11: Cannot encode certificate"); goto cleanup; } *id = internal_id; internal_id = NULL; *base64 = internal_base64; internal_base64 = NULL; success = true; cleanup: if (id_list != NULL) { pkcs11h_certificate_freeCertificateIdList(id_list); id_list = NULL; } if (internal_id != NULL) { free(internal_id); internal_id = NULL; } if (internal_base64 != NULL) { free(internal_base64); internal_base64 = NULL; } if (certificate_blob != NULL) { free(certificate_blob); certificate_blob = NULL; } dmsg( D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'", success ? 1 : 0, *id ); return success; }
CK_RV pkcs11h_removeProvider ( IN const char * const reference ) { #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_session_t current_session = NULL; PKCS11H_BOOL has_mutex_global = FALSE; PKCS11H_BOOL has_mutex_cache = FALSE; PKCS11H_BOOL has_mutex_session = FALSE; #endif _pkcs11h_provider_t provider = NULL; CK_RV rv = CKR_FUNCTION_FAILED; _PKCS11H_ASSERT (reference!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_removeProvider entry reference='%s'", reference ); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Removing provider '%s'", reference ); #if defined(ENABLE_PKCS11H_THREADING) if ((rv = _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.cache)) != CKR_OK) { goto cleanup; } has_mutex_cache = TRUE; if ((rv = _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.session)) != CKR_OK) { goto cleanup; } has_mutex_session = TRUE; if ((rv = _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global)) != CKR_OK) { goto cleanup; } has_mutex_global = TRUE; for ( current_session = _g_pkcs11h_data->sessions; current_session != NULL; current_session = current_session->next ) { _pkcs11h_threading_mutexLock (¤t_session->mutex); } #endif provider = _g_pkcs11h_data->providers; while ( provider != NULL && strcmp (reference, provider->reference) ) { provider = provider->next; } if (provider == NULL) { rv = CKR_OBJECT_HANDLE_INVALID; goto cleanup; } provider->enabled = FALSE; provider->reference[0] = '\0'; if (provider->should_finalize) { provider->f->C_Finalize (NULL); provider->should_finalize = FALSE; } #if defined(ENABLE_PKCS11H_SLOTEVENT) _pkcs11h_slotevent_notify (); /* * Wait until manager join this thread * this happens saldom so I can poll */ while (provider->slotevent_thread != PKCS11H_THREAD_NULL) { _pkcs11h_threading_sleep (500); } #endif if (provider->f != NULL) { provider->f = NULL; } if (provider->handle != NULL) { #if defined(_WIN32) FreeLibrary (provider->handle); #else dlclose (provider->handle); #endif provider->handle = NULL; } rv = CKR_OK; cleanup: #if defined(ENABLE_PKCS11H_THREADING) for ( current_session = _g_pkcs11h_data->sessions; current_session != NULL; current_session = current_session->next ) { _pkcs11h_threading_mutexRelease (¤t_session->mutex); } if (has_mutex_cache) { _pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.cache); has_mutex_cache = FALSE; } if (has_mutex_session) { _pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.session); has_mutex_session = FALSE; } if (has_mutex_global) { _pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.global); has_mutex_global = FALSE; } #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_removeProvider return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv; }
void show_pkcs11_ids( const char *const provider, bool cert_private ) { struct gc_arena gc = gc_new(); pkcs11h_certificate_id_list_t user_certificates = NULL; pkcs11h_certificate_id_list_t current = NULL; CK_RV rv = CKR_FUNCTION_FAILED; if ((rv = pkcs11h_initialize()) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level())); if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK) { msg(M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } if ( (rv = pkcs11h_addProvider( provider, provider, TRUE, 0, FALSE, 0, cert_private ? TRUE : FALSE )) != CKR_OK ) { msg(M_FATAL, "PKCS#11: Cannot add provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage(rv)); goto cleanup; } if ( (rv = pkcs11h_certificate_enumCertificateIds( PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &user_certificates )) != CKR_OK ) { msg(M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup; } msg( M_INFO|M_NOPREFIX|M_NOLF, ( "\n" "The following objects are available for use.\n" "Each object shown below may be used as parameter to\n" "--pkcs11-id option please remember to use single quote mark.\n" ) ); for (current = user_certificates; current != NULL; current = current->next) { pkcs11h_certificate_t certificate = NULL; char *dn = NULL; char serial[1024] = {0}; char *ser = NULL; size_t ser_len = 0; if ( (rv = pkcs11h_certificate_serializeCertificateId( NULL, &ser_len, current->certificate_id )) != CKR_OK ) { msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup1; } if ( rv == CKR_OK && (ser = (char *)malloc(ser_len)) == NULL ) { msg(M_FATAL, "PKCS#11: Cannot allocate memory"); goto cleanup1; } if ( (rv = pkcs11h_certificate_serializeCertificateId( ser, &ser_len, current->certificate_id )) != CKR_OK ) { msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup1; } if ( (rv = pkcs11h_certificate_create( current->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, PKCS11H_PIN_CACHE_INFINITE, &certificate )) ) { msg(M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv)); goto cleanup1; } if ( (dn = pkcs11_certificate_dn( certificate, &gc )) == NULL ) { goto cleanup1; } if ( (pkcs11_certificate_serial( certificate, serial, sizeof(serial) )) ) { goto cleanup1; } msg( M_INFO|M_NOPREFIX|M_NOLF, ( "\n" "Certificate\n" " DN: %s\n" " Serial: %s\n" " Serialized id: %s\n" ), dn, serial, ser ); cleanup1: if (certificate != NULL) { pkcs11h_certificate_freeCertificate(certificate); certificate = NULL; } if (ser != NULL) { free(ser); ser = NULL; } } cleanup: if (user_certificates != NULL) { pkcs11h_certificate_freeCertificateIdList(user_certificates); user_certificates = NULL; } pkcs11h_terminate(); gc_free(&gc); }
static void fatal (const char * const m, CK_RV rv) { fprintf (stderr, "%s - %lu - %s\n", m, rv, pkcs11h_getMessage (rv)); exit (1); }