29#if defined(ENABLE_PKCS11)
31#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
51__mygettimeofday(
struct timeval *tv)
53 return gettimeofday(tv, NULL);
58__mysleep(
unsigned long usec)
67 usleep((useconds_t)usec);
72static pkcs11h_engine_system_t s_pkcs11h_sys_engine = { malloc, free, __mytime, __mysleep,
81_pkcs11_msg_pkcs112openvpn(
const unsigned flags)
83#ifdef ENABLE_PKCS11_FORCE_DEBUG
90 case PKCS11H_LOG_DEBUG2:
94 case PKCS11H_LOG_DEBUG1:
98 case PKCS11H_LOG_INFO:
102 case PKCS11H_LOG_WARN:
106 case PKCS11H_LOG_ERROR:
115 return openvpn_flags;
120_pkcs11_msg_openvpn2pkcs11(
const msglvl_t flags)
122#ifdef ENABLE_PKCS11_FORCE_DEBUG
123 return PKCS11H_LOG_DEBUG2;
125 unsigned pkcs11_flags;
129 pkcs11_flags = PKCS11H_LOG_DEBUG2;
133 pkcs11_flags = PKCS11H_LOG_DEBUG1;
135 else if ((flags &
M_INFO) != 0)
137 pkcs11_flags = PKCS11H_LOG_INFO;
139 else if ((flags &
M_WARN) != 0)
141 pkcs11_flags = PKCS11H_LOG_WARN;
143 else if ((flags &
M_FATAL) != 0)
145 pkcs11_flags = PKCS11H_LOG_ERROR;
149 pkcs11_flags = PKCS11H_LOG_ERROR;
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 strlcpy(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 ((rv = pkcs11h_registerProvider(provider)) != CKR_OK)
334 msg(
M_WARN,
"PKCS#11: Cannot register provider '%s' %ld-'%s'", provider, rv,
335 pkcs11h_getMessage(rv));
339 PKCS11H_BOOL allow_protected_auth = protected_auth;
340 PKCS11H_BOOL cert_is_private = cert_private;
342 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOCATION, provider,
343 strlen(provider) + 1);
347 rv = pkcs11h_setProviderProperty(provider,
348 PKCS11H_PROVIDER_PROPERTY_ALLOW_PROTECTED_AUTH,
349 &allow_protected_auth,
sizeof(allow_protected_auth));
353 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_MASK_PRIVATE_MODE,
354 &private_mode,
sizeof(private_mode));
358 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_CERT_IS_PRIVATE,
359 &cert_is_private,
sizeof(cert_is_private));
361#if defined(WIN32) && defined(PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS)
364 unsigned loader_flags =
365 LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
366 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS,
367 &loader_flags,
sizeof(loader_flags));
371 if (rv != CKR_OK || (rv = pkcs11h_initializeProvider(provider)) != CKR_OK)
373 msg(
M_WARN,
"PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
374 pkcs11h_getMessage(rv));
375 pkcs11h_removeProvider(provider);
380 pkcs11h_getMessage(rv));
388 return pkcs11h_logout() == CKR_OK;
392pkcs11_management_id_count(
void)
394 pkcs11h_certificate_id_list_t id_list = NULL;
395 pkcs11h_certificate_id_list_t t = NULL;
401 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
402 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
405 msg(
M_WARN,
"PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
409 for (count = 0, t = id_list; t != NULL; t = t->next)
416 pkcs11h_certificate_freeCertificateIdList(id_list);
425pkcs11_management_id_get(
const int index,
char **
id,
char **base64)
427 pkcs11h_certificate_id_list_t id_list = NULL;
428 pkcs11h_certificate_id_list_t entry = NULL;
429 pkcs11h_certificate_t certificate = NULL;
431 unsigned char *certificate_blob = NULL;
432 size_t certificate_blob_size = 0;
434 char *internal_id = NULL;
435 char *internal_base64 = NULL;
437 bool success =
false;
447 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
448 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
451 msg(
M_WARN,
"PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
457 while (entry != NULL && count != index)
465 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
470 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &max, entry->certificate_id))
473 msg(
M_WARN,
"PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
474 pkcs11h_getMessage(rv));
478 if ((internal_id = (
char *)malloc(max)) == NULL)
480 msg(
M_FATAL,
"PKCS#11: Cannot allocate memory");
484 if ((rv = pkcs11h_certificate_serializeCertificateId(internal_id, &max, entry->certificate_id))
487 msg(
M_WARN,
"PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
488 pkcs11h_getMessage(rv));
492 if ((rv = pkcs11h_certificate_create(entry->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
493 PKCS11H_PIN_CACHE_INFINITE, &certificate))
496 msg(
M_WARN,
"PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
500 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, NULL, &certificate_blob_size))
503 msg(
M_WARN,
"PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
507 if ((certificate_blob = (
unsigned char *)malloc(certificate_blob_size)) == NULL)
509 msg(
M_FATAL,
"PKCS#11: Cannot allocate memory");
513 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, certificate_blob,
514 &certificate_blob_size))
517 msg(
M_WARN,
"PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
521 if (certificate_blob_size > INT_MAX)
523 msg(
M_WARN,
"PKCS#11: Invalid certificate size %zu", certificate_blob_size);
529 msg(
M_WARN,
"PKCS#11: Cannot encode certificate");
535 *base64 = internal_base64;
536 internal_base64 = NULL;
541 pkcs11h_certificate_freeCertificateIdList(id_list);
544 pkcs11h_certificate_freeCertificate(certificate);
550 free(internal_base64);
551 internal_base64 = NULL;
553 free(certificate_blob);
554 certificate_blob = NULL;
556 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
557 success ? 1 : 0, *id);
564 const char *
const pkcs11_id)
566 pkcs11h_certificate_id_t certificate_id = NULL;
567 pkcs11h_certificate_t certificate = NULL;
577 "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
586 id_resp.defined =
false;
587 id_resp.nocache =
true;
588 snprintf(id_resp.username,
sizeof(id_resp.username),
"Please specify PKCS#11 id to use");
597 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, id_resp.password))
600 msg(
M_WARN,
"PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
606 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, pkcs11_id))
609 msg(
M_WARN,
"PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
614 if ((rv = pkcs11h_certificate_create(certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
615 PKCS11H_PIN_CACHE_INFINITE, &certificate))
618 msg(
M_WARN,
"PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
622 if ((pkcs11_init_tls_session(certificate, ssl_ctx)))
634 if (certificate != NULL)
636 pkcs11h_certificate_freeCertificate(certificate);
640 if (certificate_id != NULL)
642 pkcs11h_certificate_freeCertificateId(certificate_id);
643 certificate_id = NULL;
646 dmsg(
D_PKCS11_DEBUG,
"PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld", ok ? 1 : 0, rv);
652_pkcs11_openvpn_show_pkcs11_ids_pin_prompt(
void *
const global_data,
void *
const user_data,
653 const pkcs11h_token_id_t token,
const unsigned retry,
654 char *
const pin,
const size_t pin_max)
687 pkcs11h_certificate_id_list_t user_certificates = NULL;
688 pkcs11h_certificate_id_list_t current = NULL;
689 CK_RV rv = CKR_FUNCTION_FAILED;
691 if ((rv = pkcs11h_initialize()) != CKR_OK)
693 msg(
M_FATAL,
"PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
697 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
699 msg(
M_FATAL,
"PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
705 if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
707 msg(
M_FATAL,
"PKCS#11: Cannot set protected authentication %ld-'%s'", rv,
708 pkcs11h_getMessage(rv));
712 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
714 msg(
M_FATAL,
"PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
718 if (!pkcs11_addProvider(provider, TRUE, 0, cert_private ? TRUE : FALSE))
720 msg(
M_FATAL,
"Failed to add PKCS#11 provider '%s", provider);
724 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
725 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL,
729 msg(
M_FATAL,
"PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
735 "The following objects are available for use.\n"
736 "Each object shown below may be used as parameter to\n"
737 "--pkcs11-id option please remember to use single quote mark.\n"));
738 for (current = user_certificates; current != NULL; current = current->next)
740 pkcs11h_certificate_t certificate = NULL;
742 char serial[1024] = { 0 };
746 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &ser_len,
747 current->certificate_id))
750 msg(
M_FATAL,
"PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
751 pkcs11h_getMessage(rv));
755 if (rv == CKR_OK && (ser = (
char *)malloc(ser_len)) == NULL)
757 msg(
M_FATAL,
"PKCS#11: Cannot allocate memory");
762 pkcs11h_certificate_serializeCertificateId(ser, &ser_len, current->certificate_id))
765 msg(
M_FATAL,
"PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
766 pkcs11h_getMessage(rv));
770 if ((rv = pkcs11h_certificate_create(current->certificate_id, NULL,
771 PKCS11H_PROMPT_MASK_ALLOW_ALL,
772 PKCS11H_PIN_CACHE_INFINITE, &certificate)))
774 msg(
M_FATAL,
"PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
778 if ((dn = pkcs11_certificate_dn(certificate, &
gc)) == NULL)
783 if ((pkcs11_certificate_serial(certificate, serial,
sizeof(serial))))
793 " Serialized id: %s\n"),
798 if (certificate != NULL)
800 pkcs11h_certificate_freeCertificate(certificate);
809 pkcs11h_certificate_freeCertificateIdList(user_certificates);
810 user_certificates = NULL;
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
#define BSTR(buf)
Return the buffer content pointer cast to char *.
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
size_t strlcpy(char *dest, const char *src, size_t maxlen)
static bool query_user_SINGLE(char *prompt, char *resp, int 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 void update_time(void)
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