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)
665 buf_printf(&pass_prompt,
"Please enter '%s' token PIN or 'cancel': ", token->display);
673 if (!strcmp(pin,
"cancel"))
684show_pkcs11_ids(
const char *
const provider,
bool cert_private)
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.
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