gpg_error_t cmd_getinfo (assuan_context_t ctx, char *line) { cmd_data_t *data = (cmd_data_t *)assuan_get_pointer (ctx); gpg_err_code_t error = GPG_ERR_GENERAL; if (!strcmp (line, "version")) { char *s = PACKAGE_VERSION; error = assuan_send_data(ctx, s, strlen (s)); } else if (!strcmp (line, "pid")) { char buf[50]; snprintf (buf, sizeof (buf), "%lu", (unsigned long)getpid()); error = assuan_send_data(ctx, buf, strlen (buf)); } else if (!strcmp (line, "socket_name")) { const char *s = data->socket_name; if (s == NULL) { error = GPG_ERR_INV_DATA; } else { error = assuan_send_data(ctx, s, strlen (s)); } } else if (!strcmp (line, "status")) { pkcs11h_certificate_id_list_t user_certificates = NULL; char flag = 'r'; if ( common_map_pkcs11_error ( pkcs11h_certificate_enumCertificateIds ( PKCS11H_ENUM_METHOD_CACHE_EXIST, ctx, PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &user_certificates ) ) == GPG_ERR_NO_ERROR ) { if (user_certificates != NULL) { flag = 'u'; pkcs11h_certificate_freeCertificateIdList (user_certificates); user_certificates = NULL; } } error = assuan_send_data(ctx, &flag, 1); } else if (!strcmp (line, "reader_list")) { error = GPG_ERR_NO_DATA; } else { error = GPG_ERR_INV_DATA; } return gpg_error (error); }
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; }
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); }
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; }
/** TODO: handle --force option! */ gpg_error_t cmd_learn (assuan_context_t ctx, char *line) { gpg_err_code_t error = GPG_ERR_GENERAL; pkcs11h_certificate_id_list_t user_certificates = NULL; pkcs11h_certificate_id_list_t issuer_certificates = NULL; char *serial = NULL; (void)line; if ( (error = get_serial(ctx, &serial)) != GPG_ERR_NO_ERROR ) { goto cleanup; } if ( (error = assuan_write_status ( ctx, "SERIALNO", serial )) != GPG_ERR_NO_ERROR || (error = assuan_write_status ( ctx, "APPTYPE", "PKCS11" )) != GPG_ERR_NO_ERROR ) { goto cleanup; } if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_enumCertificateIds ( PKCS11H_ENUM_METHOD_CACHE_EXIST, ctx, PKCS11H_PROMPT_MASK_ALLOW_ALL, &issuer_certificates, &user_certificates ) )) != GPG_ERR_NO_ERROR || (error = send_certificate_list ( ctx, user_certificates, 0 )) != GPG_ERR_NO_ERROR || (error = send_certificate_list ( ctx, issuer_certificates, 1 )) != GPG_ERR_NO_ERROR ) { goto cleanup; } error = GPG_ERR_NO_ERROR; cleanup: if (issuer_certificates != NULL) { pkcs11h_certificate_freeCertificateIdList (issuer_certificates); issuer_certificates = NULL; } if (user_certificates != NULL) { pkcs11h_certificate_freeCertificateIdList (user_certificates); user_certificates = NULL; } if (serial != NULL) { free(serial); serial = NULL; } return gpg_error (error); }
int _get_certificate_by_name (assuan_context_t ctx, char *name, int typehint, pkcs11h_certificate_id_t *p_cert_id, char **p_key) { cmd_data_t *data = (cmd_data_t *)assuan_get_pointer (ctx); gpg_err_code_t error = GPG_ERR_BAD_KEY; pkcs11h_certificate_id_list_t user_certificates = NULL; pkcs11h_certificate_id_list_t curr_cert; pkcs11h_certificate_id_t cert_id = NULL; char *key_hexgrip = NULL; gcry_sexp_t sexp = NULL; char *key = NULL; int type; *p_cert_id = NULL; if (p_key != NULL) { *p_key = NULL; } if (name == NULL) { type = typehint; } else if ( /* gnupg-2.0 mode */ data->config->openpgp_sign != NULL || data->config->openpgp_encr != NULL || data->config->openpgp_auth != NULL ) { type = typehint; } else if (strncmp (name, OPENPGP_KEY_NAME_PREFIX, strlen (OPENPGP_KEY_NAME_PREFIX))) { return common_map_pkcs11_error ( pkcs11h_certificate_deserializeCertificateId (p_cert_id, name) ); } else { type = atoi(name + strlen (OPENPGP_KEY_NAME_PREFIX)); } switch (type) { case OPENPGP_SIGN: key = data->config->openpgp_sign; break; case OPENPGP_ENCR: key = data->config->openpgp_encr; break; case OPENPGP_AUTH: key = data->config->openpgp_auth; break; default: error = GPG_ERR_BAD_KEY; goto cleanup; } if (key == NULL) { error = GPG_ERR_BAD_KEY; goto cleanup; } if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_enumCertificateIds ( PKCS11H_ENUM_METHOD_CACHE_EXIST, ctx, PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &user_certificates ) )) != GPG_ERR_NO_ERROR ) { goto cleanup; } for ( curr_cert = user_certificates; curr_cert != NULL && cert_id == NULL; curr_cert = curr_cert->next ) { if ((error = get_cert_sexp (ctx, curr_cert->certificate_id, &sexp)) != GPG_ERR_NO_ERROR) { goto cleanup; } if ((key_hexgrip = keyutil_get_cert_hexgrip (sexp)) == NULL) { error = GPG_ERR_ENOMEM; goto cleanup; } if (!strcmp (key_hexgrip, key)) { if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_duplicateCertificateId ( &cert_id, curr_cert->certificate_id ) )) != GPG_ERR_NO_ERROR ) { goto cleanup; } } } if (cert_id == NULL) { error = GPG_ERR_BAD_KEY; goto cleanup; } *p_cert_id = cert_id; cert_id = NULL; if (p_key != NULL) { *p_key = key; } error = GPG_ERR_NO_ERROR; cleanup: if (sexp != NULL) { gcry_sexp_release(sexp); sexp = NULL; } if (key_hexgrip != NULL) { free (key_hexgrip); key_hexgrip = NULL; } if (user_certificates != NULL) { pkcs11h_certificate_freeCertificateIdList (user_certificates); user_certificates = NULL; } if (cert_id != NULL) { pkcs11h_certificate_freeCertificateId (cert_id); cert_id = NULL; } return error; }
gpg_error_t cmd_getattr (assuan_context_t ctx, char *line) { pkcs11h_certificate_id_list_t user_certificates = NULL; char *serial = NULL; gpg_err_code_t error = GPG_ERR_GENERAL; if (!strcmp (line, "SERIALNO")) { if ( (error = get_serial(ctx, &serial)) != GPG_ERR_NO_ERROR ) { goto cleanup; } if (serial != NULL) { if ( (error = assuan_write_status ( ctx, "SERIALNO", serial )) != GPG_ERR_NO_ERROR ) { goto cleanup; } } } else if (!strcmp (line, "KEY-FPR")) { if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_enumCertificateIds ( PKCS11H_ENUM_METHOD_CACHE_EXIST, ctx, PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &user_certificates ) )) != GPG_ERR_NO_ERROR || (error = send_certificate_list ( ctx, user_certificates, 0 )) != GPG_ERR_NO_ERROR ) { goto cleanup; } } else if (!strcmp (line, "CHV-STATUS")) { if ( (error = assuan_write_status( ctx, "CHV-STATUS", "1 1 1 1 1 1 1" )) != GPG_ERR_NO_ERROR ) { goto cleanup; } } else if (!strcmp (line, "DISP-NAME")) { if ( (error = assuan_write_status( ctx, "DISP-NAME", "PKCS#11" )) != GPG_ERR_NO_ERROR ) { goto cleanup; } } else if (!strcmp (line, "KEY-ATTR")) { int i; for (i=0;i<3;i++) { char buffer[1024]; /* I am not sure 2048 is right here... */ snprintf(buffer, sizeof(buffer), "%d 1 %u %u %d", i+1, GCRY_PK_RSA, 2048, 0); if ( (error = assuan_write_status( ctx, "KEY-ATTR", buffer )) != GPG_ERR_NO_ERROR ) { goto cleanup; } } } else if (!strcmp (line, "EXTCAP")) { int i; for (i=0;i<3;i++) { char buffer[1024]; /* I am not sure what these are... */ snprintf(buffer, sizeof(buffer), "gc=%d ki=%d fc=%d pd=%d mcl3=%u aac=%d sm=%d", 0, 0, 0, 0, 2048, 0, 0); if ( (error = assuan_write_status( ctx, "EXTCAP", buffer )) != GPG_ERR_NO_ERROR ) { goto cleanup; } } } else { error = GPG_ERR_INV_DATA; goto cleanup; } error = GPG_ERR_NO_ERROR; cleanup: if (user_certificates != NULL) { pkcs11h_certificate_freeCertificateIdList (user_certificates); user_certificates = NULL; } if (serial != NULL) { free(serial); serial = NULL; } return gpg_error (error); }
int main () { pkcs11h_certificate_id_list_t issuers, certs, temp; pkcs11h_certificate_t cert; CK_RV rv; printf ("Initializing pkcs11-helper\n"); if ((rv = pkcs11h_initialize ()) != CKR_OK) { fatal ("pkcs11h_initialize failed", rv); } printf ("Registering pkcs11-helper hooks\n"); if ((rv = pkcs11h_setLogHook (_pkcs11h_hooks_log, NULL)) != CKR_OK) { fatal ("pkcs11h_setLogHook failed", rv); } pkcs11h_setLogLevel (TEST_LOG_LEVEL); if ((rv = pkcs11h_setTokenPromptHook (_pkcs11h_hooks_token_prompt, NULL)) != CKR_OK) { fatal ("pkcs11h_setTokenPromptHook failed", rv); } if ((rv = pkcs11h_setPINPromptHook (_pkcs11h_hooks_pin_prompt, NULL)) != CKR_OK) { fatal ("pkcs11h_setPINPromptHook failed", rv); } printf ("Adding provider '%s'\n", TEST_PROVIDER); if ( (rv = pkcs11h_addProvider ( TEST_PROVIDER, TEST_PROVIDER, FALSE, PKCS11H_PRIVATEMODE_MASK_AUTO, PKCS11H_SLOTEVENT_METHOD_AUTO, 0, FALSE )) != CKR_OK ) { fatal ("pkcs11h_addProvider failed", rv); } mypause ("Please remove all tokens, press <Enter>: "); printf ("Enumerating token certificate (list should be empty, no prompt)\n"); if ( (rv = pkcs11h_certificate_enumCertificateIds ( PKCS11H_ENUM_METHOD_CACHE, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, &issuers, &certs )) != CKR_OK ) { fatal ("pkcs11h_certificate_enumCertificateIds failed", rv); } if (issuers != NULL || certs != NULL) { fatal ("No certificates should be found", rv); } mypause ("Please insert token, press <Enter>: "); printf ("Getting certificate cache, should be available certificates\n"); if ( (rv = pkcs11h_certificate_enumCertificateIds ( PKCS11H_ENUM_METHOD_CACHE, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, &issuers, &certs )) != CKR_OK ) { fatal ("pkcs11h_certificate_enumCertificateIds failed", rv); } for (temp = issuers;temp != NULL;temp = temp->next) { printf ("Issuer: %s\n", temp->certificate_id->displayName); } for (temp = certs;temp != NULL;temp = temp->next) { printf ("Certificate: %s\n", temp->certificate_id->displayName); } if (certs == NULL) { fatal ("No certificates found", rv); } pkcs11h_certificate_freeCertificateIdList (issuers); pkcs11h_certificate_freeCertificateIdList (certs); mypause ("Please remove token, press <Enter>: "); printf ("Getting certificate cache, should be similar to last\n"); if ( (rv = pkcs11h_certificate_enumCertificateIds ( PKCS11H_ENUM_METHOD_CACHE, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, &issuers, &certs )) != CKR_OK ) { fatal ("pkcs11h_certificate_enumCertificateIds failed", rv); } for (temp = issuers;temp != NULL;temp = temp->next) { printf ("Issuer: %s\n", temp->certificate_id->displayName); } for (temp = certs;temp != NULL;temp = temp->next) { printf ("Certificate: %s\n", temp->certificate_id->displayName); } if (certs == NULL) { fatal ("No certificates found", rv); } printf ("Creating certificate context\n"); if ( (rv = pkcs11h_certificate_create ( certs->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, PKCS11H_PIN_CACHE_INFINITE, &cert )) != CKR_OK ) { fatal ("pkcs11h_certificate_create failed", rv); } printf ("Perforing signature #1 (you should be prompt for token and PIN)\n"); sign_test (cert); printf ("Perforing signature #2 (you should NOT be prompt for anything)\n"); sign_test (cert); mypause ("Please remove and insert token, press <Enter>: "); printf ("Perforing signature #3 (you should be prompt only for PIN)\n"); sign_test (cert); printf ("Perforing signature #4 (you should NOT be prompt for anything)\n"); if ((rv = pkcs11h_certificate_freeCertificate (cert)) != CKR_OK) { fatal ("pkcs11h_certificate_free failed", rv); } if ( (rv = pkcs11h_certificate_create ( certs->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL, PKCS11H_PIN_CACHE_INFINITE, &cert )) != CKR_OK ) { fatal ("pkcs11h_certificate_create failed", rv); } sign_test (cert); printf ("Terminating pkcs11-helper\n"); if ((rv = pkcs11h_certificate_freeCertificate (cert)) != CKR_OK) { fatal ("pkcs11h_certificate_free failed", rv); } pkcs11h_certificate_freeCertificateIdList (issuers); pkcs11h_certificate_freeCertificateIdList (certs); if ((rv = pkcs11h_terminate ()) != CKR_OK) { fatal ("pkcs11h_terminate failed", rv); } exit (0); return 0; }
CK_RV pkcs11h_terminate (void) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_terminate entry" ); if (_g_pkcs11h_data != NULL) { _pkcs11h_provider_t current_provider = NULL; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Removing providers" ); for ( current_provider = _g_pkcs11h_data->providers; current_provider != NULL; current_provider = current_provider->next ) { pkcs11h_removeProvider (current_provider->reference); } #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.cache); _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.session); _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global); #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Releasing sessions" ); while (_g_pkcs11h_data->sessions != NULL) { _pkcs11h_session_t current = _g_pkcs11h_data->sessions; _g_pkcs11h_data->sessions = _g_pkcs11h_data->sessions->next; #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexLock (¤t->mutex); #endif current->valid = FALSE; if (current->reference_count != 0) { _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Warning: Found session with references" ); } if (current->token_id != NULL) { pkcs11h_token_freeTokenId (current->token_id); current->token_id = NULL; } #if defined(ENABLE_PKCS11H_CERTIFICATE) pkcs11h_certificate_freeCertificateIdList (current->cached_certs); #endif current->provider = NULL; #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexFree (¤t->mutex); #endif _pkcs11h_mem_free ((void *)¤t); } #if defined(ENABLE_PKCS11H_SLOTEVENT) _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Terminating slotevent" ); _pkcs11h_slotevent_terminate (); #endif _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Marking as uninitialized" ); _g_pkcs11h_data->initialized = FALSE; while (_g_pkcs11h_data->providers != NULL) { _pkcs11h_provider_t current = _g_pkcs11h_data->providers; _g_pkcs11h_data->providers = _g_pkcs11h_data->providers->next; _pkcs11h_mem_free ((void *)¤t); } #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.global); _pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.cache); _pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.session); #endif _g_pkcs11h_crypto_engine.uninitialize (_g_pkcs11h_crypto_engine.global_data); _pkcs11h_mem_free ((void *)&_g_pkcs11h_data); } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_terminate return" ); return CKR_OK; }