29#if defined(ENABLE_PKCS11)
31#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
50__mygettimeofday(
struct timeval *tv)
52 return gettimeofday(tv, NULL);
57__mysleep(
const unsigned long usec)
67static pkcs11h_engine_system_t s_pkcs11h_sys_engine = { malloc, free, __mytime, __mysleep,
76_pkcs11_msg_pkcs112openvpn(
const unsigned flags)
78 unsigned openvpn_flags;
82 case PKCS11H_LOG_DEBUG2:
86 case PKCS11H_LOG_DEBUG1:
90 case PKCS11H_LOG_INFO:
94 case PKCS11H_LOG_WARN:
98 case PKCS11H_LOG_ERROR:
107#if defined(ENABLE_PKCS11_FORCE_DEBUG)
111 return openvpn_flags;
115_pkcs11_msg_openvpn2pkcs11(
const unsigned flags)
117 unsigned pkcs11_flags;
121 pkcs11_flags = PKCS11H_LOG_DEBUG2;
125 pkcs11_flags = PKCS11H_LOG_DEBUG1;
127 else if ((flags &
M_INFO) != 0)
129 pkcs11_flags = PKCS11H_LOG_INFO;
131 else if ((flags &
M_WARN) != 0)
133 pkcs11_flags = PKCS11H_LOG_WARN;
135 else if ((flags &
M_FATAL) != 0)
137 pkcs11_flags = PKCS11H_LOG_ERROR;
141 pkcs11_flags = PKCS11H_LOG_ERROR;
144#if defined(ENABLE_PKCS11_FORCE_DEBUG)
145 pkcs11_flags = PKCS11H_LOG_DEBUG2;
152_pkcs11_openvpn_log(
void *
const global_data,
unsigned flags,
const char *
const szFormat,
155 char Buffer[10 * 1024];
159 vsnprintf(Buffer,
sizeof(Buffer), szFormat, args);
160 Buffer[
sizeof(Buffer) - 1] = 0;
162 msg(_pkcs11_msg_pkcs112openvpn(flags),
"%s", Buffer);
166_pkcs11_openvpn_token_prompt(
void *
const global_data,
void *
const user_data,
167 const pkcs11h_token_id_t token,
const unsigned retry)
178 token_resp.defined =
false;
179 token_resp.nocache =
true;
180 snprintf(token_resp.username,
sizeof(token_resp.username),
"Please insert %s token",
183 if (!
get_user_pass(&token_resp, NULL,
"token-insertion-request",
190 return strcmp(token_resp.password,
"ok") == 0;
195_pkcs11_openvpn_pin_prompt(
void *
const global_data,
void *
const user_data,
196 const pkcs11h_token_id_t token,
const unsigned retry,
char *
const pin,
197 const size_t pin_max)
209 snprintf(prompt,
sizeof(prompt),
"%s token", token->label);
211 token_pass.defined =
false;
212 token_pass.nocache =
true;
222 strncpynt(pin, token_pass.password, pin_max);
225 if (strlen(pin) == 0)
237pkcs11_initialize(
const bool protected_auth,
const int nPINCachePeriod)
239 CK_RV rv = CKR_FUNCTION_FAILED;
243 if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK)
245 msg(
M_FATAL,
"PKCS#11: Cannot initialize system engine %ld-'%s'", rv,
246 pkcs11h_getMessage(rv));
250 if ((rv = pkcs11h_initialize()) != CKR_OK)
252 msg(
M_FATAL,
"PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
256 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
258 msg(
M_FATAL,
"PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
264 if ((rv = pkcs11h_setForkMode(FALSE)) != CKR_OK)
266 msg(
M_FATAL,
"PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage(rv));
270 if ((rv = pkcs11h_setTokenPromptHook(_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK)
272 msg(
M_FATAL,
"PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
276 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK)
278 msg(
M_FATAL,
"PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
282 if ((rv = pkcs11h_setProtectedAuthentication(protected_auth)) != CKR_OK)
284 msg(
M_FATAL,
"PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv,
285 pkcs11h_getMessage(rv));
289 if ((rv = pkcs11h_setPINCachePeriod(nPINCachePeriod)) != CKR_OK)
291 msg(
M_FATAL,
"PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage(rv));
299 pkcs11h_getMessage(rv));
305pkcs11_terminate(
void)
315pkcs11_addProvider(
const char *
const provider,
const bool protected_auth,
316 const unsigned private_mode,
const bool cert_private)
322 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x",
323 provider, private_mode);
325 msg(
M_INFO,
"PKCS#11: Adding PKCS#11 provider '%s'", provider);
327#if PKCS11H_VERSION >= ((1 << 16) | (28 << 8) | (0 << 0))
328 if ((rv = pkcs11h_registerProvider(provider)) != CKR_OK)
330 msg(
M_WARN,
"PKCS#11: Cannot register provider '%s' %ld-'%s'", provider, rv,
331 pkcs11h_getMessage(rv));
335 PKCS11H_BOOL allow_protected_auth = protected_auth;
336 PKCS11H_BOOL cert_is_private = cert_private;
338 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOCATION, provider,
339 strlen(provider) + 1);
343 rv = pkcs11h_setProviderProperty(provider,
344 PKCS11H_PROVIDER_PROPERTY_ALLOW_PROTECTED_AUTH,
345 &allow_protected_auth,
sizeof(allow_protected_auth));
349 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_MASK_PRIVATE_MODE,
350 &private_mode,
sizeof(private_mode));
354 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_CERT_IS_PRIVATE,
355 &cert_is_private,
sizeof(cert_is_private));
357#if defined(WIN32) && defined(PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS)
360 unsigned loader_flags =
361 LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
362 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS,
363 &loader_flags,
sizeof(loader_flags));
367 if (rv != CKR_OK || (rv = pkcs11h_initializeProvider(provider)) != CKR_OK)
369 msg(
M_WARN,
"PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
370 pkcs11h_getMessage(rv));
371 pkcs11h_removeProvider(provider);
375 if ((rv = pkcs11h_addProvider(provider, provider, protected_auth, private_mode,
376 PKCS11H_SLOTEVENT_METHOD_AUTO, 0, cert_private))
379 msg(
M_WARN,
"PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
380 pkcs11h_getMessage(rv));
385 pkcs11h_getMessage(rv));
393 return pkcs11h_logout() == CKR_OK;
397pkcs11_management_id_count(
void)
399 pkcs11h_certificate_id_list_t id_list = NULL;
400 pkcs11h_certificate_id_list_t t = NULL;
406 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
407 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
410 msg(
M_WARN,
"PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
414 for (count = 0, t = id_list; t != NULL; t = t->next)
421 pkcs11h_certificate_freeCertificateIdList(id_list);
430pkcs11_management_id_get(
const int index,
char **
id,
char **base64)
432 pkcs11h_certificate_id_list_t id_list = NULL;
433 pkcs11h_certificate_id_list_t entry = NULL;
435 pkcs11h_certificate_id_t certificate_id = NULL;
437 pkcs11h_certificate_t certificate = NULL;
439 unsigned char *certificate_blob = NULL;
440 size_t certificate_blob_size = 0;
442 char *internal_id = NULL;
443 char *internal_base64 = NULL;
445 bool success =
false;
455 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
456 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
459 msg(
M_WARN,
"PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
465 while (entry != NULL && count != index)
473 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
478 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &max, entry->certificate_id))
481 msg(
M_WARN,
"PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
482 pkcs11h_getMessage(rv));
486 if ((internal_id = (
char *)malloc(max)) == NULL)
488 msg(
M_FATAL,
"PKCS#11: Cannot allocate memory");
492 if ((rv = pkcs11h_certificate_serializeCertificateId(internal_id, &max, entry->certificate_id))
495 msg(
M_WARN,
"PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
496 pkcs11h_getMessage(rv));
500 if ((rv = pkcs11h_certificate_create(entry->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
501 PKCS11H_PIN_CACHE_INFINITE, &certificate))
504 msg(
M_WARN,
"PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
508 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, NULL, &certificate_blob_size))
511 msg(
M_WARN,
"PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
515 if ((certificate_blob = (
unsigned char *)malloc(certificate_blob_size)) == NULL)
517 msg(
M_FATAL,
"PKCS#11: Cannot allocate memory");
521 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, certificate_blob,
522 &certificate_blob_size))
525 msg(
M_WARN,
"PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
531 msg(
M_WARN,
"PKCS#11: Cannot encode certificate");
537 *base64 = internal_base64;
538 internal_base64 = NULL;
543 pkcs11h_certificate_freeCertificateIdList(id_list);
549 free(internal_base64);
550 internal_base64 = NULL;
552 free(certificate_blob);
553 certificate_blob = NULL;
555 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
556 success ? 1 : 0, *id);
563 const char *
const pkcs11_id)
565 pkcs11h_certificate_id_t certificate_id = NULL;
566 pkcs11h_certificate_t certificate = NULL;
576 "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
585 id_resp.defined =
false;
586 id_resp.nocache =
true;
587 snprintf(id_resp.username,
sizeof(id_resp.username),
"Please specify PKCS#11 id to use");
596 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, id_resp.password))
599 msg(
M_WARN,
"PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
605 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, pkcs11_id))
608 msg(
M_WARN,
"PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
613 if ((rv = pkcs11h_certificate_create(certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
614 PKCS11H_PIN_CACHE_INFINITE, &certificate))
617 msg(
M_WARN,
"PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
621 if ((pkcs11_init_tls_session(certificate, ssl_ctx)))
633 if (certificate != NULL)
635 pkcs11h_certificate_freeCertificate(certificate);
639 if (certificate_id != NULL)
641 pkcs11h_certificate_freeCertificateId(certificate_id);
642 certificate_id = NULL;
645 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld", ok ? 1 : 0, rv);
651_pkcs11_openvpn_show_pkcs11_ids_pin_prompt(
void *
const global_data,
void *
const user_data,
652 const pkcs11h_token_id_t token,
const unsigned retry,
653 char *
const pin,
const size_t pin_max)
686 pkcs11h_certificate_id_list_t user_certificates = NULL;
687 pkcs11h_certificate_id_list_t current = NULL;
688 CK_RV rv = CKR_FUNCTION_FAILED;
690 if ((rv = pkcs11h_initialize()) != CKR_OK)
692 msg(
M_FATAL,
"PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
696 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
698 msg(
M_FATAL,
"PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
704 if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
706 msg(
M_FATAL,
"PKCS#11: Cannot set protected authentication %ld-'%s'", rv,
707 pkcs11h_getMessage(rv));
711 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
713 msg(
M_FATAL,
"PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
717 if (!pkcs11_addProvider(provider, TRUE, 0, cert_private ? TRUE : FALSE))
719 msg(
M_FATAL,
"Failed to add PKCS#11 provider '%s", provider);
723 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
724 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL,
728 msg(
M_FATAL,
"PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
734 "The following objects are available for use.\n"
735 "Each object shown below may be used as parameter to\n"
736 "--pkcs11-id option please remember to use single quote mark.\n"));
737 for (current = user_certificates; current != NULL; current = current->next)
739 pkcs11h_certificate_t certificate = NULL;
741 char serial[1024] = { 0 };
745 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &ser_len,
746 current->certificate_id))
749 msg(
M_FATAL,
"PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
750 pkcs11h_getMessage(rv));
754 if (rv == CKR_OK && (ser = (
char *)malloc(ser_len)) == NULL)
756 msg(
M_FATAL,
"PKCS#11: Cannot allocate memory");
761 pkcs11h_certificate_serializeCertificateId(ser, &ser_len, current->certificate_id))
764 msg(
M_FATAL,
"PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
765 pkcs11h_getMessage(rv));
769 if ((rv = pkcs11h_certificate_create(current->certificate_id, NULL,
770 PKCS11H_PROMPT_MASK_ALLOW_ALL,
771 PKCS11H_PIN_CACHE_INFINITE, &certificate)))
773 msg(
M_FATAL,
"PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
777 if ((dn = pkcs11_certificate_dn(certificate, &
gc)) == NULL)
782 if ((pkcs11_certificate_serial(certificate, serial,
sizeof(serial))))
792 " Serialized id: %s\n"),
797 if (certificate != NULL)
799 pkcs11h_certificate_freeCertificate(certificate);
808 pkcs11h_certificate_freeCertificateIdList(user_certificates);
809 user_certificates = NULL;
bool buf_printf(struct buffer *buf, const char *format,...)
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
static void strncpynt(char *dest, const char *src, size_t maxlen)
static void gc_free(struct gc_arena *a)
static struct gc_arena gc_new(void)
static bool query_user_SINGLE(char *prompt, size_t prompt_len, char *resp, size_t resp_len, bool echo)
A plain "make Gert happy" wrapper.
void purge_user_pass(struct user_pass *up, const bool force)
#define GET_USER_PASS_MANAGEMENT
#define GET_USER_PASS_PASSWORD_ONLY
#define GET_USER_PASS_NEED_OK
#define GET_USER_PASS_NOFATAL
static bool get_user_pass(struct user_pass *up, const char *auth_file, const char *prefix, const unsigned int flags)
Retrieves the user credentials from various sources depending on the flags.
#define GET_USER_PASS_NEED_STR
int get_debug_level(void)
static time_t openvpn_time(time_t *t)
PKCS #11 SSL library-specific backend.
int openvpn_base64_encode(const void *data, int size, char **str)
Wrapper structure for dynamically allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
Garbage collection arena used to keep track of dynamically allocated memory.
Structure that wraps the TLS context.
static int cleanup(void **state)
static bool pkcs11_id_management