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; }
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; }