29#if defined(ENABLE_PKCS11)
31#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
50__mygettimeofday(
struct timeval *tv)
52 return gettimeofday(tv, NULL);
56#if defined(__GNUC__) || defined(__clang__)
57#pragma GCC diagnostic push
58#pragma GCC diagnostic ignored "-Wconversion"
62__mysleep(
const unsigned long usec)
72static pkcs11h_engine_system_t s_pkcs11h_sys_engine = { malloc, free, __mytime, __mysleep,
81_pkcs11_msg_pkcs112openvpn(
const unsigned flags)
87 case PKCS11H_LOG_DEBUG2:
91 case PKCS11H_LOG_DEBUG1:
95 case PKCS11H_LOG_INFO:
99 case PKCS11H_LOG_WARN:
103 case PKCS11H_LOG_ERROR:
112#if defined(ENABLE_PKCS11_FORCE_DEBUG)
116 return openvpn_flags;
120_pkcs11_msg_openvpn2pkcs11(
const msglvl_t flags)
122 unsigned pkcs11_flags;
126 pkcs11_flags = PKCS11H_LOG_DEBUG2;
130 pkcs11_flags = PKCS11H_LOG_DEBUG1;
132 else if ((flags &
M_INFO) != 0)
134 pkcs11_flags = PKCS11H_LOG_INFO;
136 else if ((flags &
M_WARN) != 0)
138 pkcs11_flags = PKCS11H_LOG_WARN;
140 else if ((flags &
M_FATAL) != 0)
142 pkcs11_flags = PKCS11H_LOG_ERROR;
146 pkcs11_flags = PKCS11H_LOG_ERROR;
149#if defined(ENABLE_PKCS11_FORCE_DEBUG)
150 pkcs11_flags = PKCS11H_LOG_DEBUG2;
157_pkcs11_openvpn_log(
void *
const global_data,
unsigned flags,
const char *
const szFormat,
160 char Buffer[10 * 1024];
164 vsnprintf(Buffer,
sizeof(Buffer), szFormat, args);
165 Buffer[
sizeof(Buffer) - 1] = 0;
167 msg(_pkcs11_msg_pkcs112openvpn(flags),
"%s", Buffer);
171_pkcs11_openvpn_token_prompt(
void *
const global_data,
void *
const user_data,
172 const pkcs11h_token_id_t token,
const unsigned retry)
183 token_resp.defined =
false;
184 token_resp.nocache =
true;
185 snprintf(token_resp.username,
sizeof(token_resp.username),
"Please insert %s token",
188 if (!
get_user_pass(&token_resp, NULL,
"token-insertion-request",
195 return strcmp(token_resp.password,
"ok") == 0;
200_pkcs11_openvpn_pin_prompt(
void *
const global_data,
void *
const user_data,
201 const pkcs11h_token_id_t token,
const unsigned retry,
char *
const pin,
202 const size_t pin_max)
214 snprintf(prompt,
sizeof(prompt),
"%s token", token->label);
216 token_pass.defined =
false;
217 token_pass.nocache =
true;
227 strncpynt(pin, token_pass.password, pin_max);
230 if (strlen(pin) == 0)
242pkcs11_initialize(
const bool protected_auth,
const int nPINCachePeriod)
244 CK_RV rv = CKR_FUNCTION_FAILED;
248 if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK)
250 msg(
M_FATAL,
"PKCS#11: Cannot initialize system engine %ld-'%s'", rv,
251 pkcs11h_getMessage(rv));
255 if ((rv = pkcs11h_initialize()) != CKR_OK)
257 msg(
M_FATAL,
"PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
261 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
263 msg(
M_FATAL,
"PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
269 if ((rv = pkcs11h_setForkMode(FALSE)) != CKR_OK)
271 msg(
M_FATAL,
"PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage(rv));
275 if ((rv = pkcs11h_setTokenPromptHook(_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK)
277 msg(
M_FATAL,
"PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
281 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK)
283 msg(
M_FATAL,
"PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
287 if ((rv = pkcs11h_setProtectedAuthentication(protected_auth)) != CKR_OK)
289 msg(
M_FATAL,
"PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv,
290 pkcs11h_getMessage(rv));
294 if ((rv = pkcs11h_setPINCachePeriod(nPINCachePeriod)) != CKR_OK)
296 msg(
M_FATAL,
"PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage(rv));
304 pkcs11h_getMessage(rv));
310pkcs11_terminate(
void)
320pkcs11_addProvider(
const char *
const provider,
const bool protected_auth,
321 const unsigned private_mode,
const bool cert_private)
327 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x",
328 provider, private_mode);
330 msg(
M_INFO,
"PKCS#11: Adding PKCS#11 provider '%s'", provider);
332#if PKCS11H_VERSION >= ((1 << 16) | (28 << 8) | (0 << 0))
333 if ((rv = pkcs11h_registerProvider(provider)) != CKR_OK)
335 msg(
M_WARN,
"PKCS#11: Cannot register provider '%s' %ld-'%s'", provider, rv,
336 pkcs11h_getMessage(rv));
340 PKCS11H_BOOL allow_protected_auth = protected_auth;
341 PKCS11H_BOOL cert_is_private = cert_private;
343 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOCATION, provider,
344 strlen(provider) + 1);
348 rv = pkcs11h_setProviderProperty(provider,
349 PKCS11H_PROVIDER_PROPERTY_ALLOW_PROTECTED_AUTH,
350 &allow_protected_auth,
sizeof(allow_protected_auth));
354 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_MASK_PRIVATE_MODE,
355 &private_mode,
sizeof(private_mode));
359 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_CERT_IS_PRIVATE,
360 &cert_is_private,
sizeof(cert_is_private));
362#if defined(WIN32) && defined(PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS)
365 unsigned loader_flags =
366 LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
367 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS,
368 &loader_flags,
sizeof(loader_flags));
372 if (rv != CKR_OK || (rv = pkcs11h_initializeProvider(provider)) != CKR_OK)
374 msg(
M_WARN,
"PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
375 pkcs11h_getMessage(rv));
376 pkcs11h_removeProvider(provider);
380 if ((rv = pkcs11h_addProvider(provider, provider, protected_auth, private_mode,
381 PKCS11H_SLOTEVENT_METHOD_AUTO, 0, cert_private))
384 msg(
M_WARN,
"PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
385 pkcs11h_getMessage(rv));
390 pkcs11h_getMessage(rv));
398 return pkcs11h_logout() == CKR_OK;
402pkcs11_management_id_count(
void)
404 pkcs11h_certificate_id_list_t id_list = NULL;
405 pkcs11h_certificate_id_list_t t = NULL;
411 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
412 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
415 msg(
M_WARN,
"PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
419 for (count = 0, t = id_list; t != NULL; t = t->next)
426 pkcs11h_certificate_freeCertificateIdList(id_list);
435pkcs11_management_id_get(
const int index,
char **
id,
char **base64)
437 pkcs11h_certificate_id_list_t id_list = NULL;
438 pkcs11h_certificate_id_list_t entry = NULL;
440 pkcs11h_certificate_id_t certificate_id = NULL;
442 pkcs11h_certificate_t certificate = NULL;
444 unsigned char *certificate_blob = NULL;
445 size_t certificate_blob_size = 0;
447 char *internal_id = NULL;
448 char *internal_base64 = NULL;
450 bool success =
false;
460 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
461 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
464 msg(
M_WARN,
"PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
470 while (entry != NULL && count != index)
478 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
483 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &max, entry->certificate_id))
486 msg(
M_WARN,
"PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
487 pkcs11h_getMessage(rv));
491 if ((internal_id = (
char *)malloc(max)) == NULL)
493 msg(
M_FATAL,
"PKCS#11: Cannot allocate memory");
497 if ((rv = pkcs11h_certificate_serializeCertificateId(internal_id, &max, entry->certificate_id))
500 msg(
M_WARN,
"PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
501 pkcs11h_getMessage(rv));
505 if ((rv = pkcs11h_certificate_create(entry->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
506 PKCS11H_PIN_CACHE_INFINITE, &certificate))
509 msg(
M_WARN,
"PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
513 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, NULL, &certificate_blob_size))
516 msg(
M_WARN,
"PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
520 if ((certificate_blob = (
unsigned char *)malloc(certificate_blob_size)) == NULL)
522 msg(
M_FATAL,
"PKCS#11: Cannot allocate memory");
526 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, certificate_blob,
527 &certificate_blob_size))
530 msg(
M_WARN,
"PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
536 msg(
M_WARN,
"PKCS#11: Cannot encode certificate");
542 *base64 = internal_base64;
543 internal_base64 = NULL;
548 pkcs11h_certificate_freeCertificateIdList(id_list);
554 free(internal_base64);
555 internal_base64 = NULL;
557 free(certificate_blob);
558 certificate_blob = NULL;
560 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
561 success ? 1 : 0, *id);
566#if defined(__GNUC__) || defined(__clang__)
567#pragma GCC diagnostic pop
572 const char *
const pkcs11_id)
574 pkcs11h_certificate_id_t certificate_id = NULL;
575 pkcs11h_certificate_t certificate = NULL;
585 "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
594 id_resp.defined =
false;
595 id_resp.nocache =
true;
596 snprintf(id_resp.username,
sizeof(id_resp.username),
"Please specify PKCS#11 id to use");
605 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, id_resp.password))
608 msg(
M_WARN,
"PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
614 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, pkcs11_id))
617 msg(
M_WARN,
"PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
622 if ((rv = pkcs11h_certificate_create(certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
623 PKCS11H_PIN_CACHE_INFINITE, &certificate))
626 msg(
M_WARN,
"PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
630 if ((pkcs11_init_tls_session(certificate, ssl_ctx)))
642 if (certificate != NULL)
644 pkcs11h_certificate_freeCertificate(certificate);
648 if (certificate_id != NULL)
650 pkcs11h_certificate_freeCertificateId(certificate_id);
651 certificate_id = NULL;
654 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld", ok ? 1 : 0, rv);
660_pkcs11_openvpn_show_pkcs11_ids_pin_prompt(
void *
const global_data,
void *
const user_data,
661 const pkcs11h_token_id_t token,
const unsigned retry,
662 char *
const pin,
const size_t pin_max)
695 pkcs11h_certificate_id_list_t user_certificates = NULL;
696 pkcs11h_certificate_id_list_t current = NULL;
697 CK_RV rv = CKR_FUNCTION_FAILED;
699 if ((rv = pkcs11h_initialize()) != CKR_OK)
701 msg(
M_FATAL,
"PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
705 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
707 msg(
M_FATAL,
"PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
713 if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
715 msg(
M_FATAL,
"PKCS#11: Cannot set protected authentication %ld-'%s'", rv,
716 pkcs11h_getMessage(rv));
720 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
722 msg(
M_FATAL,
"PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
726 if (!pkcs11_addProvider(provider, TRUE, 0, cert_private ? TRUE : FALSE))
728 msg(
M_FATAL,
"Failed to add PKCS#11 provider '%s", provider);
732 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
733 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL,
737 msg(
M_FATAL,
"PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
743 "The following objects are available for use.\n"
744 "Each object shown below may be used as parameter to\n"
745 "--pkcs11-id option please remember to use single quote mark.\n"));
746 for (current = user_certificates; current != NULL; current = current->next)
748 pkcs11h_certificate_t certificate = NULL;
750 char serial[1024] = { 0 };
754 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &ser_len,
755 current->certificate_id))
758 msg(
M_FATAL,
"PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
759 pkcs11h_getMessage(rv));
763 if (rv == CKR_OK && (ser = (
char *)malloc(ser_len)) == NULL)
765 msg(
M_FATAL,
"PKCS#11: Cannot allocate memory");
770 pkcs11h_certificate_serializeCertificateId(ser, &ser_len, current->certificate_id))
773 msg(
M_FATAL,
"PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
774 pkcs11h_getMessage(rv));
778 if ((rv = pkcs11h_certificate_create(current->certificate_id, NULL,
779 PKCS11H_PROMPT_MASK_ALLOW_ALL,
780 PKCS11H_PIN_CACHE_INFINITE, &certificate)))
782 msg(
M_FATAL,
"PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
786 if ((dn = pkcs11_certificate_dn(certificate, &
gc)) == NULL)
791 if ((pkcs11_certificate_serial(certificate, serial,
sizeof(serial))))
801 " Serialized id: %s\n"),
806 if (certificate != NULL)
808 pkcs11h_certificate_freeCertificate(certificate);
817 pkcs11h_certificate_freeCertificateIdList(user_certificates);
818 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
msglvl_t 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