OpenVPN
pkcs11.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2026 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#if defined(ENABLE_PKCS11)
30
31#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
32#include "basic.h"
33#include "error.h"
34#include "manage.h"
35#include "base64.h"
36#include "pkcs11.h"
37#include "misc.h"
38#include "otime.h"
39#include "console.h"
40#include "pkcs11_backend.h"
41
42static time_t
43__mytime(void)
44{
46 return now;
47}
48
49#if !defined(_WIN32)
50static int
51__mygettimeofday(struct timeval *tv)
52{
53 return gettimeofday(tv, NULL);
54}
55#endif
56
57static void
58__mysleep(unsigned long usec)
59{
60#if defined(_WIN32)
61 Sleep(usec / 1000);
62#else
63 if (usec > UINT_MAX)
64 {
65 usec = UINT_MAX;
66 }
67 usleep((useconds_t)usec);
68#endif
69}
70
71
72static pkcs11h_engine_system_t s_pkcs11h_sys_engine = { malloc, free, __mytime, __mysleep,
73#if defined(_WIN32)
74 NULL
75#else
76 __mygettimeofday
77#endif
78};
79
80static msglvl_t
81_pkcs11_msg_pkcs112openvpn(const unsigned flags)
82{
83#ifdef ENABLE_PKCS11_FORCE_DEBUG
84 return M_INFO;
85#else
86 msglvl_t openvpn_flags;
87
88 switch (flags)
89 {
90 case PKCS11H_LOG_DEBUG2:
91 openvpn_flags = D_PKCS11_DEBUG;
92 break;
93
94 case PKCS11H_LOG_DEBUG1:
95 openvpn_flags = D_SHOW_PKCS11;
96 break;
97
98 case PKCS11H_LOG_INFO:
99 openvpn_flags = M_INFO;
100 break;
101
102 case PKCS11H_LOG_WARN:
103 openvpn_flags = M_WARN;
104 break;
105
106 case PKCS11H_LOG_ERROR:
107 openvpn_flags = M_FATAL;
108 break;
109
110 default:
111 openvpn_flags = M_FATAL;
112 break;
113 }
114
115 return openvpn_flags;
116#endif
117}
118
119static unsigned
120_pkcs11_msg_openvpn2pkcs11(const msglvl_t flags)
121{
122#ifdef ENABLE_PKCS11_FORCE_DEBUG
123 return PKCS11H_LOG_DEBUG2;
124#else
125 unsigned pkcs11_flags;
126
127 if ((flags & D_PKCS11_DEBUG) != 0)
128 {
129 pkcs11_flags = PKCS11H_LOG_DEBUG2;
130 }
131 else if ((flags & D_SHOW_PKCS11) != 0)
132 {
133 pkcs11_flags = PKCS11H_LOG_DEBUG1;
134 }
135 else if ((flags & M_INFO) != 0)
136 {
137 pkcs11_flags = PKCS11H_LOG_INFO;
138 }
139 else if ((flags & M_WARN) != 0)
140 {
141 pkcs11_flags = PKCS11H_LOG_WARN;
142 }
143 else if ((flags & M_FATAL) != 0)
144 {
145 pkcs11_flags = PKCS11H_LOG_ERROR;
146 }
147 else
148 {
149 pkcs11_flags = PKCS11H_LOG_ERROR;
150 }
151
152 return pkcs11_flags;
153#endif
154}
155
156static void
157_pkcs11_openvpn_log(void *const global_data, unsigned flags, const char *const szFormat,
158 va_list args)
159{
160 char Buffer[10 * 1024];
161
162 (void)global_data;
163
164 vsnprintf(Buffer, sizeof(Buffer), szFormat, args);
165 Buffer[sizeof(Buffer) - 1] = 0;
166
167 msg(_pkcs11_msg_pkcs112openvpn(flags), "%s", Buffer);
168}
169
170static PKCS11H_BOOL
171_pkcs11_openvpn_token_prompt(void *const global_data, void *const user_data,
172 const pkcs11h_token_id_t token, const unsigned retry)
173{
174 struct user_pass token_resp;
175
176 (void)global_data;
177 (void)user_data;
178 (void)retry;
179
180 ASSERT(token != NULL);
181
182 CLEAR(token_resp);
183 token_resp.defined = false;
184 token_resp.nocache = true;
185 snprintf(token_resp.username, sizeof(token_resp.username), "Please insert %s token",
186 token->label);
187
188 if (!get_user_pass(&token_resp, NULL, "token-insertion-request",
190 {
191 return false;
192 }
193 else
194 {
195 return strcmp(token_resp.password, "ok") == 0;
196 }
197}
198
199static PKCS11H_BOOL
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)
203{
204 struct user_pass token_pass;
205 char prompt[1024];
206 CLEAR(token_pass);
207
208 (void)global_data;
209 (void)user_data;
210 (void)retry;
211
212 ASSERT(token != NULL);
213
214 snprintf(prompt, sizeof(prompt), "%s token", token->label);
215
216 token_pass.defined = false;
217 token_pass.nocache = true;
218
219 if (!get_user_pass(&token_pass, NULL, prompt,
222 {
223 return false;
224 }
225 else
226 {
227 strlcpy(pin, token_pass.password, pin_max);
228 purge_user_pass(&token_pass, true);
229
230 if (strlen(pin) == 0)
231 {
232 return false;
233 }
234 else
235 {
236 return true;
237 }
238 }
239}
240
241bool
242pkcs11_initialize(const bool protected_auth, const int nPINCachePeriod)
243{
244 CK_RV rv = CKR_FUNCTION_FAILED;
245
246 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_initialize - entered");
247
248 if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK)
249 {
250 msg(M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv,
251 pkcs11h_getMessage(rv));
252 goto cleanup;
253 }
254
255 if ((rv = pkcs11h_initialize()) != CKR_OK)
256 {
257 msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
258 goto cleanup;
259 }
260
261 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
262 {
263 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
264 goto cleanup;
265 }
266
267 pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));
268
269 if ((rv = pkcs11h_setForkMode(FALSE)) != CKR_OK)
270 {
271 msg(M_FATAL, "PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage(rv));
272 goto cleanup;
273 }
274
275 if ((rv = pkcs11h_setTokenPromptHook(_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK)
276 {
277 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
278 goto cleanup;
279 }
280
281 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK)
282 {
283 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
284 goto cleanup;
285 }
286
287 if ((rv = pkcs11h_setProtectedAuthentication(protected_auth)) != CKR_OK)
288 {
289 msg(M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv,
290 pkcs11h_getMessage(rv));
291 goto cleanup;
292 }
293
294 if ((rv = pkcs11h_setPINCachePeriod(nPINCachePeriod)) != CKR_OK)
295 {
296 msg(M_FATAL, "PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage(rv));
297 goto cleanup;
298 }
299
300 rv = CKR_OK;
301
302cleanup:
303 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_initialize - return %ld-'%s'", rv,
304 pkcs11h_getMessage(rv));
305
306 return rv == CKR_OK;
307}
308
309void
310pkcs11_terminate(void)
311{
312 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_terminate - entered");
313
314 pkcs11h_terminate();
315
316 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_terminate - return");
317}
318
319bool
320pkcs11_addProvider(const char *const provider, const bool protected_auth,
321 const unsigned private_mode, const bool cert_private)
322{
323 CK_RV rv = CKR_OK;
324
325 ASSERT(provider != NULL);
326
327 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x",
328 provider, private_mode);
329
330 msg(M_INFO, "PKCS#11: Adding PKCS#11 provider '%s'", provider);
331
332 if ((rv = pkcs11h_registerProvider(provider)) != CKR_OK)
333 {
334 msg(M_WARN, "PKCS#11: Cannot register provider '%s' %ld-'%s'", provider, rv,
335 pkcs11h_getMessage(rv));
336 }
337 else
338 {
339 PKCS11H_BOOL allow_protected_auth = protected_auth;
340 PKCS11H_BOOL cert_is_private = cert_private;
341
342 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOCATION, provider,
343 strlen(provider) + 1);
344
345 if (rv == CKR_OK)
346 {
347 rv = pkcs11h_setProviderProperty(provider,
348 PKCS11H_PROVIDER_PROPERTY_ALLOW_PROTECTED_AUTH,
349 &allow_protected_auth, sizeof(allow_protected_auth));
350 }
351 if (rv == CKR_OK)
352 {
353 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_MASK_PRIVATE_MODE,
354 &private_mode, sizeof(private_mode));
355 }
356 if (rv == CKR_OK)
357 {
358 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_CERT_IS_PRIVATE,
359 &cert_is_private, sizeof(cert_is_private));
360 }
361#if defined(WIN32) && defined(PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS)
362 if (rv == CKR_OK && platform_absolute_pathname(provider))
363 {
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));
368 }
369#endif
370
371 if (rv != CKR_OK || (rv = pkcs11h_initializeProvider(provider)) != CKR_OK)
372 {
373 msg(M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
374 pkcs11h_getMessage(rv));
375 pkcs11h_removeProvider(provider);
376 }
377 }
378
379 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'", rv,
380 pkcs11h_getMessage(rv));
381
382 return rv == CKR_OK;
383}
384
385int
386pkcs11_logout(void)
387{
388 return pkcs11h_logout() == CKR_OK;
389}
390
391int
392pkcs11_management_id_count(void)
393{
394 pkcs11h_certificate_id_list_t id_list = NULL;
395 pkcs11h_certificate_id_list_t t = NULL;
396 CK_RV rv = CKR_OK;
397 int count = 0;
398
399 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_count - entered");
400
401 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
402 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
403 != CKR_OK)
404 {
405 msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
406 goto cleanup;
407 }
408
409 for (count = 0, t = id_list; t != NULL; t = t->next)
410 {
411 count++;
412 }
413
414cleanup:
415
416 pkcs11h_certificate_freeCertificateIdList(id_list);
417 id_list = NULL;
418
419 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_count - return count=%d", count);
420
421 return count;
422}
423
424bool
425pkcs11_management_id_get(const int index, char **id, char **base64)
426{
427 pkcs11h_certificate_id_list_t id_list = NULL;
428 pkcs11h_certificate_id_list_t entry = NULL;
429 pkcs11h_certificate_t certificate = NULL;
430 CK_RV rv = CKR_OK;
431 unsigned char *certificate_blob = NULL;
432 size_t certificate_blob_size = 0;
433 size_t max;
434 char *internal_id = NULL;
435 char *internal_base64 = NULL;
436 int count = 0;
437 bool success = false;
438
439 ASSERT(id != NULL);
440 ASSERT(base64 != NULL);
441
442 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - entered index=%d", index);
443
444 *id = NULL;
445 *base64 = NULL;
446
447 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
448 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
449 != CKR_OK)
450 {
451 msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
452 goto cleanup;
453 }
454
455 entry = id_list;
456 count = 0;
457 while (entry != NULL && count != index)
458 {
459 count++;
460 entry = entry->next;
461 }
462
463 if (entry == NULL)
464 {
465 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
466 index);
467 goto cleanup;
468 }
469
470 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &max, entry->certificate_id))
471 != CKR_OK)
472 {
473 msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
474 pkcs11h_getMessage(rv));
475 goto cleanup;
476 }
477
478 if ((internal_id = (char *)malloc(max)) == NULL)
479 {
480 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
481 goto cleanup;
482 }
483
484 if ((rv = pkcs11h_certificate_serializeCertificateId(internal_id, &max, entry->certificate_id))
485 != CKR_OK)
486 {
487 msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
488 pkcs11h_getMessage(rv));
489 goto cleanup;
490 }
491
492 if ((rv = pkcs11h_certificate_create(entry->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
493 PKCS11H_PIN_CACHE_INFINITE, &certificate))
494 != CKR_OK)
495 {
496 msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
497 goto cleanup;
498 }
499
500 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, NULL, &certificate_blob_size))
501 != CKR_OK)
502 {
503 msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
504 goto cleanup;
505 }
506
507 if ((certificate_blob = (unsigned char *)malloc(certificate_blob_size)) == NULL)
508 {
509 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
510 goto cleanup;
511 }
512
513 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, certificate_blob,
514 &certificate_blob_size))
515 != CKR_OK)
516 {
517 msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
518 goto cleanup;
519 }
520
521 if (certificate_blob_size > INT_MAX)
522 {
523 msg(M_WARN, "PKCS#11: Invalid certificate size %zu", certificate_blob_size);
524 goto cleanup;
525 }
526
527 if (openvpn_base64_encode(certificate_blob, (int)certificate_blob_size, &internal_base64) == -1)
528 {
529 msg(M_WARN, "PKCS#11: Cannot encode certificate");
530 goto cleanup;
531 }
532
533 *id = internal_id;
534 internal_id = NULL;
535 *base64 = internal_base64;
536 internal_base64 = NULL;
537 success = true;
538
539cleanup:
540
541 pkcs11h_certificate_freeCertificateIdList(id_list);
542 id_list = NULL;
543
544 pkcs11h_certificate_freeCertificate(certificate);
545 certificate = NULL;
546
547 free(internal_id);
548 internal_id = NULL;
549
550 free(internal_base64);
551 internal_base64 = NULL;
552
553 free(certificate_blob);
554 certificate_blob = NULL;
555
556 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
557 success ? 1 : 0, *id);
558
559 return success;
560}
561
562int
563tls_ctx_use_pkcs11(struct tls_root_ctx *const ssl_ctx, bool pkcs11_id_management,
564 const char *const pkcs11_id)
565{
566 pkcs11h_certificate_id_t certificate_id = NULL;
567 pkcs11h_certificate_t certificate = NULL;
568 CK_RV rv = CKR_OK;
569
570 bool ok = false;
571
572 ASSERT(ssl_ctx != NULL);
573 ASSERT(pkcs11_id_management || pkcs11_id != NULL);
574
575 dmsg(
577 "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
578 (void *)ssl_ctx, pkcs11_id_management ? 1 : 0, pkcs11_id);
579
581 {
582 struct user_pass id_resp;
583
584 CLEAR(id_resp);
585
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");
589
590 if (!get_user_pass(&id_resp, NULL, "pkcs11-id-request",
593 {
594 goto cleanup;
595 }
596
597 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, id_resp.password))
598 != CKR_OK)
599 {
600 msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
601 goto cleanup;
602 }
603 }
604 else
605 {
606 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, pkcs11_id))
607 != CKR_OK)
608 {
609 msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
610 goto cleanup;
611 }
612 }
613
614 if ((rv = pkcs11h_certificate_create(certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
615 PKCS11H_PIN_CACHE_INFINITE, &certificate))
616 != CKR_OK)
617 {
618 msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
619 goto cleanup;
620 }
621
622 if ((pkcs11_init_tls_session(certificate, ssl_ctx)))
623 {
624 /* Handled by SSL context free */
625 certificate = NULL;
626 goto cleanup;
627 }
628
629 /* Handled by SSL context free */
630 certificate = NULL;
631 ok = true;
632
633cleanup:
634 if (certificate != NULL)
635 {
636 pkcs11h_certificate_freeCertificate(certificate);
637 certificate = NULL;
638 }
639
640 if (certificate_id != NULL)
641 {
642 pkcs11h_certificate_freeCertificateId(certificate_id);
643 certificate_id = NULL;
644 }
645
646 dmsg(D_PKCS11_DEBUG, "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld", ok ? 1 : 0, rv);
647
648 return ok ? 1 : 0;
649}
650
651static PKCS11H_BOOL
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)
655{
656 struct gc_arena gc = gc_new();
657 struct buffer pass_prompt = alloc_buf_gc(128, &gc);
658
659 (void)global_data;
660 (void)user_data;
661 (void)retry;
662
663 ASSERT(token != NULL);
664
665 buf_printf(&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display);
666 if (!query_user_SINGLE(BSTR(&pass_prompt), pin, (int)pin_max, false))
667 {
668 msg(M_FATAL, "Could not retrieve the PIN");
669 }
670
671 gc_free(&gc);
672
673 if (!strcmp(pin, "cancel"))
674 {
675 return FALSE;
676 }
677 else
678 {
679 return TRUE;
680 }
681}
682
683void
684show_pkcs11_ids(const char *const provider, bool cert_private)
685{
686 struct gc_arena gc = gc_new();
687 pkcs11h_certificate_id_list_t user_certificates = NULL;
688 pkcs11h_certificate_id_list_t current = NULL;
689 CK_RV rv = CKR_FUNCTION_FAILED;
690
691 if ((rv = pkcs11h_initialize()) != CKR_OK)
692 {
693 msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
694 goto cleanup;
695 }
696
697 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
698 {
699 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
700 goto cleanup;
701 }
702
703 pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));
704
705 if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
706 {
707 msg(M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv,
708 pkcs11h_getMessage(rv));
709 goto cleanup;
710 }
711
712 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
713 {
714 msg(M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
715 goto cleanup;
716 }
717
718 if (!pkcs11_addProvider(provider, TRUE, 0, cert_private ? TRUE : FALSE))
719 {
720 msg(M_FATAL, "Failed to add PKCS#11 provider '%s", provider);
721 goto cleanup;
722 }
723
724 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
725 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL,
726 &user_certificates))
727 != CKR_OK)
728 {
729 msg(M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
730 goto cleanup;
731 }
732
734 ("\n"
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)
739 {
740 pkcs11h_certificate_t certificate = NULL;
741 char *dn = NULL;
742 char serial[1024] = { 0 };
743 char *ser = NULL;
744 size_t ser_len = 0;
745
746 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &ser_len,
747 current->certificate_id))
748 != CKR_OK)
749 {
750 msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
751 pkcs11h_getMessage(rv));
752 goto cleanup1;
753 }
754
755 if (rv == CKR_OK && (ser = (char *)malloc(ser_len)) == NULL)
756 {
757 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
758 goto cleanup1;
759 }
760
761 if ((rv =
762 pkcs11h_certificate_serializeCertificateId(ser, &ser_len, current->certificate_id))
763 != CKR_OK)
764 {
765 msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
766 pkcs11h_getMessage(rv));
767 goto cleanup1;
768 }
769
770 if ((rv = pkcs11h_certificate_create(current->certificate_id, NULL,
771 PKCS11H_PROMPT_MASK_ALLOW_ALL,
772 PKCS11H_PIN_CACHE_INFINITE, &certificate)))
773 {
774 msg(M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
775 goto cleanup1;
776 }
777
778 if ((dn = pkcs11_certificate_dn(certificate, &gc)) == NULL)
779 {
780 goto cleanup1;
781 }
782
783 if ((pkcs11_certificate_serial(certificate, serial, sizeof(serial))))
784 {
785 goto cleanup1;
786 }
787
789 ("\n"
790 "Certificate\n"
791 " DN: %s\n"
792 " Serial: %s\n"
793 " Serialized id: %s\n"),
794 dn, serial, ser);
795
796cleanup1:
797
798 if (certificate != NULL)
799 {
800 pkcs11h_certificate_freeCertificate(certificate);
801 certificate = NULL;
802 }
803
804 free(ser);
805 ser = NULL;
806 }
807
808cleanup:
809 pkcs11h_certificate_freeCertificateIdList(user_certificates);
810 user_certificates = NULL;
811
812 pkcs11h_terminate();
813 gc_free(&gc);
814}
815#endif /* ENABLE_PKCS11 */
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
Definition buffer.c:226
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
Definition buffer.c:77
#define BSTR(buf)
Return the buffer content pointer cast to char *.
Definition buffer.h:157
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1965
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1949
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.
Definition console.h:118
#define D_PKCS11_DEBUG
Definition errlevel.h:173
#define D_SHOW_PKCS11
Definition errlevel.h:140
#define M_INFO
Definition errlevel.h:54
void purge_user_pass(struct user_pass *up, const bool force)
Definition misc.c:468
#define GET_USER_PASS_MANAGEMENT
Definition misc.h:113
#define GET_USER_PASS_PASSWORD_ONLY
Definition misc.h:115
#define GET_USER_PASS_NEED_OK
Definition misc.h:116
#define GET_USER_PASS_NOFATAL
Definition misc.h:117
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.
Definition misc.h:155
#define GET_USER_PASS_NEED_STR
Definition misc.h:118
#define CLEAR(x)
Definition basic.h:32
msglvl_t get_debug_level(void)
Definition error.c:133
#define M_NOPREFIX
Definition error.h:98
#define M_FATAL
Definition error.h:90
#define M_NOLF
Definition error.h:102
#define dmsg(flags,...)
Definition error.h:164
#define msg(flags,...)
Definition error.h:152
unsigned int msglvl_t
Definition error.h:77
#define ASSERT(x)
Definition error.h:221
#define M_WARN
Definition error.h:92
time_t now
Definition otime.c:33
static void update_time(void)
Definition otime.h:84
PKCS #11 SSL library-specific backend.
bool platform_absolute_pathname(const char *pathname)
Return true if pathname is absolute.
Definition platform.c:662
int openvpn_base64_encode(const void *data, int size, char **str)
Definition base64.c:51
Wrapper structure for dynamically allocated memory.
Definition buffer.h:71
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
Structure that wraps the TLS context.
static int cleanup(void **state)
static bool pkcs11_id_management
struct gc_arena gc
Definition test_ssl.c:122