From 3a2bbdb05ca6a6996e424c9fb225cb0d53804125 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Iniesta Date: Tue, 27 Dec 2016 18:25:47 +0100 Subject: New upstream version 2.4.0 --- src/openvpn/pkcs11.c | 1668 ++++++++++++++++++++++++++------------------------ 1 file changed, 869 insertions(+), 799 deletions(-) (limited to 'src/openvpn/pkcs11.c') diff --git a/src/openvpn/pkcs11.c b/src/openvpn/pkcs11.c index 2621058..6858846 100644 --- a/src/openvpn/pkcs11.c +++ b/src/openvpn/pkcs11.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. + * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -45,898 +45,968 @@ static time_t -__mytime (void) { - return openvpn_time (NULL); +__mytime(void) { + return openvpn_time(NULL); } #if !defined(_WIN32) static int -__mygettimeofday (struct timeval *tv) { - return gettimeofday (tv, NULL); +__mygettimeofday(struct timeval *tv) { + return gettimeofday(tv, NULL); } #endif static void -__mysleep (const unsigned long usec) { +__mysleep(const unsigned long usec) { #if defined(_WIN32) - Sleep (usec/1000); + Sleep(usec/1000); #else - usleep (usec); + usleep(usec); #endif } static pkcs11h_engine_system_t s_pkcs11h_sys_engine = { - malloc, - free, - __mytime, - __mysleep, + malloc, + free, + __mytime, + __mysleep, #if defined(_WIN32) - NULL + NULL #else - __mygettimeofday + __mygettimeofday #endif }; static unsigned -_pkcs11_msg_pkcs112openvpn ( - const unsigned flags -) { - unsigned openvpn_flags; - - switch (flags) { - case PKCS11H_LOG_DEBUG2: - openvpn_flags = D_PKCS11_DEBUG; - break; - case PKCS11H_LOG_DEBUG1: - openvpn_flags = D_SHOW_PKCS11; - break; - case PKCS11H_LOG_INFO: - openvpn_flags = M_INFO; - break; - case PKCS11H_LOG_WARN: - openvpn_flags = M_WARN; - break; - case PKCS11H_LOG_ERROR: - openvpn_flags = M_FATAL; - break; - default: - openvpn_flags = M_FATAL; - break; - } +_pkcs11_msg_pkcs112openvpn( + const unsigned flags + ) { + unsigned openvpn_flags; + + switch (flags) { + case PKCS11H_LOG_DEBUG2: + openvpn_flags = D_PKCS11_DEBUG; + break; + + case PKCS11H_LOG_DEBUG1: + openvpn_flags = D_SHOW_PKCS11; + break; + + case PKCS11H_LOG_INFO: + openvpn_flags = M_INFO; + break; + + case PKCS11H_LOG_WARN: + openvpn_flags = M_WARN; + break; + + case PKCS11H_LOG_ERROR: + openvpn_flags = M_FATAL; + break; + + default: + openvpn_flags = M_FATAL; + break; + } #if defined(ENABLE_PKCS11_FORCE_DEBUG) - openvpn_flags=M_INFO; + openvpn_flags = M_INFO; #endif - return openvpn_flags; + return openvpn_flags; } static unsigned -_pkcs11_msg_openvpn2pkcs11 ( - const unsigned flags -) { - unsigned pkcs11_flags; - - if ((flags & D_PKCS11_DEBUG) != 0) { - pkcs11_flags = PKCS11H_LOG_DEBUG2; - } - else if ((flags & D_SHOW_PKCS11) != 0) { - pkcs11_flags = PKCS11H_LOG_DEBUG1; - } - else if ((flags & M_INFO) != 0) { - pkcs11_flags = PKCS11H_LOG_INFO; - } - else if ((flags & M_WARN) != 0) { - pkcs11_flags = PKCS11H_LOG_WARN; - } - else if ((flags & M_FATAL) != 0) { - pkcs11_flags = PKCS11H_LOG_ERROR; - } - else { - pkcs11_flags = PKCS11H_LOG_ERROR; - } +_pkcs11_msg_openvpn2pkcs11( + const unsigned flags + ) { + unsigned pkcs11_flags; + + if ((flags & D_PKCS11_DEBUG) != 0) + { + pkcs11_flags = PKCS11H_LOG_DEBUG2; + } + else if ((flags & D_SHOW_PKCS11) != 0) + { + pkcs11_flags = PKCS11H_LOG_DEBUG1; + } + else if ((flags & M_INFO) != 0) + { + pkcs11_flags = PKCS11H_LOG_INFO; + } + else if ((flags & M_WARN) != 0) + { + pkcs11_flags = PKCS11H_LOG_WARN; + } + else if ((flags & M_FATAL) != 0) + { + pkcs11_flags = PKCS11H_LOG_ERROR; + } + else + { + pkcs11_flags = PKCS11H_LOG_ERROR; + } #if defined(ENABLE_PKCS11_FORCE_DEBUG) - pkcs11_flags = PKCS11H_LOG_DEBUG2; + pkcs11_flags = PKCS11H_LOG_DEBUG2; #endif - return pkcs11_flags; + return pkcs11_flags; } static void -_pkcs11_openvpn_log ( - void * const global_data, - unsigned flags, - const char * const szFormat, - va_list args -) { - char Buffer[10*1024]; - - (void)global_data; - - vsnprintf (Buffer, sizeof (Buffer), szFormat, args); - Buffer[sizeof (Buffer)-1] = 0; - - msg (_pkcs11_msg_pkcs112openvpn (flags), "%s", Buffer); +_pkcs11_openvpn_log( + void *const global_data, + unsigned flags, + const char *const szFormat, + va_list args + ) { + char Buffer[10*1024]; + + (void)global_data; + + vsnprintf(Buffer, sizeof(Buffer), szFormat, args); + Buffer[sizeof(Buffer)-1] = 0; + + msg(_pkcs11_msg_pkcs112openvpn(flags), "%s", Buffer); } static PKCS11H_BOOL -_pkcs11_openvpn_token_prompt ( - void * const global_data, - void * const user_data, - const pkcs11h_token_id_t token, - const unsigned retry -) { - struct user_pass token_resp; - - (void)global_data; - (void)user_data; - (void)retry; - - ASSERT (token!=NULL); - - CLEAR (token_resp); - token_resp.defined = false; - token_resp.nocache = true; - openvpn_snprintf ( - token_resp.username, - sizeof (token_resp.username), - "Please insert %s token", - token->label - ); - - if ( - !get_user_pass ( - &token_resp, - NULL, - "token-insertion-request", - GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK|GET_USER_PASS_NOFATAL - ) - ) { - return false; - } - else { - return strcmp (token_resp.password, "ok") == 0; - } +_pkcs11_openvpn_token_prompt( + void *const global_data, + void *const user_data, + const pkcs11h_token_id_t token, + const unsigned retry + ) { + struct user_pass token_resp; + + (void)global_data; + (void)user_data; + (void)retry; + + ASSERT(token!=NULL); + + CLEAR(token_resp); + token_resp.defined = false; + token_resp.nocache = true; + openvpn_snprintf( + token_resp.username, + sizeof(token_resp.username), + "Please insert %s token", + token->label + ); + + if ( + !get_user_pass( + &token_resp, + NULL, + "token-insertion-request", + GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK|GET_USER_PASS_NOFATAL + ) + ) + { + return false; + } + else + { + return strcmp(token_resp.password, "ok") == 0; + } } static PKCS11H_BOOL -_pkcs11_openvpn_pin_prompt ( - void * const global_data, - void * const user_data, - const pkcs11h_token_id_t token, - const unsigned retry, - char * const pin, - const size_t pin_max -) { - struct user_pass token_pass; - char prompt[1024]; - - (void)global_data; - (void)user_data; - (void)retry; - - ASSERT (token!=NULL); - - openvpn_snprintf (prompt, sizeof (prompt), "%s token", token->label); - - token_pass.defined = false; - token_pass.nocache = true; - - if ( - !get_user_pass ( - &token_pass, - NULL, - prompt, - GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL - ) - ) { - return false; - } - else { - strncpynt (pin, token_pass.password, pin_max); - purge_user_pass (&token_pass, true); - - if (strlen (pin) == 0) { - return false; - } - else { - return true; - } - } +_pkcs11_openvpn_pin_prompt( + void *const global_data, + void *const user_data, + const pkcs11h_token_id_t token, + const unsigned retry, + char *const pin, + const size_t pin_max + ) { + struct user_pass token_pass; + char prompt[1024]; + + (void)global_data; + (void)user_data; + (void)retry; + + ASSERT(token!=NULL); + + openvpn_snprintf(prompt, sizeof(prompt), "%s token", token->label); + + token_pass.defined = false; + token_pass.nocache = true; + + if ( + !get_user_pass( + &token_pass, + NULL, + prompt, + GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL + ) + ) + { + return false; + } + else + { + strncpynt(pin, token_pass.password, pin_max); + purge_user_pass(&token_pass, true); + + if (strlen(pin) == 0) + { + return false; + } + else + { + return true; + } + } } 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; +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; + dmsg( + D_PKCS11_DEBUG, + "PKCS#11: pkcs11_initialize - return %ld-'%s'", + rv, + pkcs11h_getMessage(rv) + ); + + return rv == CKR_OK; } void -pkcs11_terminate () { - dmsg ( - D_PKCS11_DEBUG, - "PKCS#11: pkcs11_terminate - entered" - ); - - pkcs11h_terminate (); - - dmsg ( - D_PKCS11_DEBUG, - "PKCS#11: pkcs11_terminate - return" - ); +pkcs11_terminate() { + dmsg( + D_PKCS11_DEBUG, + "PKCS#11: pkcs11_terminate - entered" + ); + + pkcs11h_terminate(); + + dmsg( + D_PKCS11_DEBUG, + "PKCS#11: pkcs11_terminate - return" + ); } 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; +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; } int pkcs11_logout() { - return pkcs11h_logout () == CKR_OK; + return pkcs11h_logout() == CKR_OK; } 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++; - } +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; - } + 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 - ); + dmsg( + D_PKCS11_DEBUG, + "PKCS#11: pkcs11_management_id_count - return count=%d", + count + ); - return count; + return count; } 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; +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; + 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; - + 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; + 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; } 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; +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; + 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; } static PKCS11H_BOOL -_pkcs11_openvpn_show_pkcs11_ids_pin_prompt ( - void * const global_data, - void * const user_data, - const pkcs11h_token_id_t token, - const unsigned retry, - char * const pin, - const size_t pin_max -) { - struct gc_arena gc = gc_new (); - struct buffer pass_prompt = alloc_buf_gc (128, &gc); - - (void)global_data; - (void)user_data; - (void)retry; - - ASSERT (token!=NULL); - - buf_printf (&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display); - if (!query_user_SINGLE(BSTR(&pass_prompt), BLEN(&pass_prompt), - pin, pin_max, false)) - { - msg (M_FATAL, "Could not retrieve the PIN"); - } - - gc_free (&gc); - - if (!strcmp (pin, "cancel")) { - return FALSE; - } - else { - return TRUE; - } +_pkcs11_openvpn_show_pkcs11_ids_pin_prompt( + void *const global_data, + void *const user_data, + const pkcs11h_token_id_t token, + const unsigned retry, + char *const pin, + const size_t pin_max + ) { + struct gc_arena gc = gc_new(); + struct buffer pass_prompt = alloc_buf_gc(128, &gc); + + (void)global_data; + (void)user_data; + (void)retry; + + ASSERT(token!=NULL); + + buf_printf(&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display); + if (!query_user_SINGLE(BSTR(&pass_prompt), BLEN(&pass_prompt), + pin, pin_max, false)) + { + msg(M_FATAL, "Could not retrieve the PIN"); + } + + gc_free(&gc); + + if (!strcmp(pin, "cancel")) + { + return FALSE; + } + else + { + return TRUE; + } } 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; - } - } +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); + if (user_certificates != NULL) + { + pkcs11h_certificate_freeCertificateIdList(user_certificates); + user_certificates = NULL; + } + + pkcs11h_terminate(); + gc_free(&gc); } -#else +#else /* if defined(ENABLE_PKCS11) */ #ifdef _MSC_VER /* Dummy function needed to avoid empty file compiler warning in Microsoft VC */ -static void dummy (void) {} +static void +dummy(void) { +} #endif #endif /* ENABLE_PKCS11 */ -- cgit v1.2.3