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-2025 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{
45 return openvpn_time(NULL);
46}
47
48#if !defined(_WIN32)
49static int
50__mygettimeofday(struct timeval *tv)
51{
52 return gettimeofday(tv, NULL);
53}
54#endif
55
56#if defined(__GNUC__) || defined(__clang__)
57#pragma GCC diagnostic push
58#pragma GCC diagnostic ignored "-Wconversion"
59#endif
60
61static void
62__mysleep(const unsigned long usec)
63{
64#if defined(_WIN32)
65 Sleep(usec / 1000);
66#else
67 usleep(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 msglvl_t openvpn_flags;
84
85 switch (flags)
86 {
87 case PKCS11H_LOG_DEBUG2:
88 openvpn_flags = D_PKCS11_DEBUG;
89 break;
90
91 case PKCS11H_LOG_DEBUG1:
92 openvpn_flags = D_SHOW_PKCS11;
93 break;
94
95 case PKCS11H_LOG_INFO:
96 openvpn_flags = M_INFO;
97 break;
98
99 case PKCS11H_LOG_WARN:
100 openvpn_flags = M_WARN;
101 break;
102
103 case PKCS11H_LOG_ERROR:
104 openvpn_flags = M_FATAL;
105 break;
106
107 default:
108 openvpn_flags = M_FATAL;
109 break;
110 }
111
112#if defined(ENABLE_PKCS11_FORCE_DEBUG)
113 openvpn_flags = M_INFO;
114#endif
115
116 return openvpn_flags;
117}
118
119static unsigned
120_pkcs11_msg_openvpn2pkcs11(const msglvl_t flags)
121{
122 unsigned pkcs11_flags;
123
124 if ((flags & D_PKCS11_DEBUG) != 0)
125 {
126 pkcs11_flags = PKCS11H_LOG_DEBUG2;
127 }
128 else if ((flags & D_SHOW_PKCS11) != 0)
129 {
130 pkcs11_flags = PKCS11H_LOG_DEBUG1;
131 }
132 else if ((flags & M_INFO) != 0)
133 {
134 pkcs11_flags = PKCS11H_LOG_INFO;
135 }
136 else if ((flags & M_WARN) != 0)
137 {
138 pkcs11_flags = PKCS11H_LOG_WARN;
139 }
140 else if ((flags & M_FATAL) != 0)
141 {
142 pkcs11_flags = PKCS11H_LOG_ERROR;
143 }
144 else
145 {
146 pkcs11_flags = PKCS11H_LOG_ERROR;
147 }
148
149#if defined(ENABLE_PKCS11_FORCE_DEBUG)
150 pkcs11_flags = PKCS11H_LOG_DEBUG2;
151#endif
152
153 return pkcs11_flags;
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 strncpynt(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 PKCS11H_VERSION >= ((1 << 16) | (28 << 8) | (0 << 0))
333 if ((rv = pkcs11h_registerProvider(provider)) != CKR_OK)
334 {
335 msg(M_WARN, "PKCS#11: Cannot register provider '%s' %ld-'%s'", provider, rv,
336 pkcs11h_getMessage(rv));
337 }
338 else
339 {
340 PKCS11H_BOOL allow_protected_auth = protected_auth;
341 PKCS11H_BOOL cert_is_private = cert_private;
342
343 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOCATION, provider,
344 strlen(provider) + 1);
345
346 if (rv == CKR_OK)
347 {
348 rv = pkcs11h_setProviderProperty(provider,
349 PKCS11H_PROVIDER_PROPERTY_ALLOW_PROTECTED_AUTH,
350 &allow_protected_auth, sizeof(allow_protected_auth));
351 }
352 if (rv == CKR_OK)
353 {
354 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_MASK_PRIVATE_MODE,
355 &private_mode, sizeof(private_mode));
356 }
357 if (rv == CKR_OK)
358 {
359 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_CERT_IS_PRIVATE,
360 &cert_is_private, sizeof(cert_is_private));
361 }
362#if defined(WIN32) && defined(PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS)
363 if (rv == CKR_OK && platform_absolute_pathname(provider))
364 {
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));
369 }
370#endif
371
372 if (rv != CKR_OK || (rv = pkcs11h_initializeProvider(provider)) != CKR_OK)
373 {
374 msg(M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
375 pkcs11h_getMessage(rv));
376 pkcs11h_removeProvider(provider);
377 }
378 }
379#else /* if PKCS11H_VERSION >= ((1<<16) | (28<<8) | (0<<0)) */
380 if ((rv = pkcs11h_addProvider(provider, provider, protected_auth, private_mode,
381 PKCS11H_SLOTEVENT_METHOD_AUTO, 0, cert_private))
382 != CKR_OK)
383 {
384 msg(M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
385 pkcs11h_getMessage(rv));
386 }
387#endif /* if PKCS11H_VERSION >= ((1<<16) | (28<<8) | (0<<0)) */
388
389 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'", rv,
390 pkcs11h_getMessage(rv));
391
392 return rv == CKR_OK;
393}
394
395int
396pkcs11_logout(void)
397{
398 return pkcs11h_logout() == CKR_OK;
399}
400
401int
402pkcs11_management_id_count(void)
403{
404 pkcs11h_certificate_id_list_t id_list = NULL;
405 pkcs11h_certificate_id_list_t t = NULL;
406 CK_RV rv = CKR_OK;
407 int count = 0;
408
409 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_count - entered");
410
411 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
412 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
413 != CKR_OK)
414 {
415 msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
416 goto cleanup;
417 }
418
419 for (count = 0, t = id_list; t != NULL; t = t->next)
420 {
421 count++;
422 }
423
424cleanup:
425
426 pkcs11h_certificate_freeCertificateIdList(id_list);
427 id_list = NULL;
428
429 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_count - return count=%d", count);
430
431 return count;
432}
433
434bool
435pkcs11_management_id_get(const int index, char **id, char **base64)
436{
437 pkcs11h_certificate_id_list_t id_list = NULL;
438 pkcs11h_certificate_id_list_t entry = NULL;
439#if 0 /* certificate_id seems to be unused -- JY */
440 pkcs11h_certificate_id_t certificate_id = NULL;
441#endif
442 pkcs11h_certificate_t certificate = NULL;
443 CK_RV rv = CKR_OK;
444 unsigned char *certificate_blob = NULL;
445 size_t certificate_blob_size = 0;
446 size_t max;
447 char *internal_id = NULL;
448 char *internal_base64 = NULL;
449 int count = 0;
450 bool success = false;
451
452 ASSERT(id != NULL);
453 ASSERT(base64 != NULL);
454
455 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - entered index=%d", index);
456
457 *id = NULL;
458 *base64 = NULL;
459
460 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
461 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
462 != CKR_OK)
463 {
464 msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
465 goto cleanup;
466 }
467
468 entry = id_list;
469 count = 0;
470 while (entry != NULL && count != index)
471 {
472 count++;
473 entry = entry->next;
474 }
475
476 if (entry == NULL)
477 {
478 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
479 index);
480 goto cleanup;
481 }
482
483 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &max, entry->certificate_id))
484 != CKR_OK)
485 {
486 msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
487 pkcs11h_getMessage(rv));
488 goto cleanup;
489 }
490
491 if ((internal_id = (char *)malloc(max)) == NULL)
492 {
493 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
494 goto cleanup;
495 }
496
497 if ((rv = pkcs11h_certificate_serializeCertificateId(internal_id, &max, entry->certificate_id))
498 != CKR_OK)
499 {
500 msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
501 pkcs11h_getMessage(rv));
502 goto cleanup;
503 }
504
505 if ((rv = pkcs11h_certificate_create(entry->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
506 PKCS11H_PIN_CACHE_INFINITE, &certificate))
507 != CKR_OK)
508 {
509 msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
510 goto cleanup;
511 }
512
513 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, NULL, &certificate_blob_size))
514 != CKR_OK)
515 {
516 msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
517 goto cleanup;
518 }
519
520 if ((certificate_blob = (unsigned char *)malloc(certificate_blob_size)) == NULL)
521 {
522 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
523 goto cleanup;
524 }
525
526 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, certificate_blob,
527 &certificate_blob_size))
528 != CKR_OK)
529 {
530 msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
531 goto cleanup;
532 }
533
534 if (openvpn_base64_encode(certificate_blob, certificate_blob_size, &internal_base64) == -1)
535 {
536 msg(M_WARN, "PKCS#11: Cannot encode certificate");
537 goto cleanup;
538 }
539
540 *id = internal_id;
541 internal_id = NULL;
542 *base64 = internal_base64;
543 internal_base64 = NULL;
544 success = true;
545
546cleanup:
547
548 pkcs11h_certificate_freeCertificateIdList(id_list);
549 id_list = NULL;
550
551 free(internal_id);
552 internal_id = NULL;
553
554 free(internal_base64);
555 internal_base64 = NULL;
556
557 free(certificate_blob);
558 certificate_blob = NULL;
559
560 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
561 success ? 1 : 0, *id);
562
563 return success;
564}
565
566#if defined(__GNUC__) || defined(__clang__)
567#pragma GCC diagnostic pop
568#endif
569
570int
571tls_ctx_use_pkcs11(struct tls_root_ctx *const ssl_ctx, bool pkcs11_id_management,
572 const char *const pkcs11_id)
573{
574 pkcs11h_certificate_id_t certificate_id = NULL;
575 pkcs11h_certificate_t certificate = NULL;
576 CK_RV rv = CKR_OK;
577
578 bool ok = false;
579
580 ASSERT(ssl_ctx != NULL);
581 ASSERT(pkcs11_id_management || pkcs11_id != NULL);
582
583 dmsg(
585 "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
586 (void *)ssl_ctx, pkcs11_id_management ? 1 : 0, pkcs11_id);
587
589 {
590 struct user_pass id_resp;
591
592 CLEAR(id_resp);
593
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");
597
598 if (!get_user_pass(&id_resp, NULL, "pkcs11-id-request",
601 {
602 goto cleanup;
603 }
604
605 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, id_resp.password))
606 != CKR_OK)
607 {
608 msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
609 goto cleanup;
610 }
611 }
612 else
613 {
614 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, pkcs11_id))
615 != CKR_OK)
616 {
617 msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
618 goto cleanup;
619 }
620 }
621
622 if ((rv = pkcs11h_certificate_create(certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
623 PKCS11H_PIN_CACHE_INFINITE, &certificate))
624 != CKR_OK)
625 {
626 msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
627 goto cleanup;
628 }
629
630 if ((pkcs11_init_tls_session(certificate, ssl_ctx)))
631 {
632 /* Handled by SSL context free */
633 certificate = NULL;
634 goto cleanup;
635 }
636
637 /* Handled by SSL context free */
638 certificate = NULL;
639 ok = true;
640
641cleanup:
642 if (certificate != NULL)
643 {
644 pkcs11h_certificate_freeCertificate(certificate);
645 certificate = NULL;
646 }
647
648 if (certificate_id != NULL)
649 {
650 pkcs11h_certificate_freeCertificateId(certificate_id);
651 certificate_id = NULL;
652 }
653
654 dmsg(D_PKCS11_DEBUG, "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld", ok ? 1 : 0, rv);
655
656 return ok ? 1 : 0;
657}
658
659static PKCS11H_BOOL
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)
663{
664 struct gc_arena gc = gc_new();
665 struct buffer pass_prompt = alloc_buf_gc(128, &gc);
666
669 (void)retry;
670
671 ASSERT(token != NULL);
672
673 buf_printf(&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display);
675 {
676 msg(M_FATAL, "Could not retrieve the PIN");
677 }
678
679 gc_free(&gc);
680
681 if (!strcmp(pin, "cancel"))
682 {
683 return FALSE;
684 }
685 else
686 {
687 return TRUE;
688 }
689}
690
691void
692show_pkcs11_ids(const char *const provider, bool cert_private)
693{
694 struct gc_arena gc = gc_new();
695 pkcs11h_certificate_id_list_t user_certificates = NULL;
696 pkcs11h_certificate_id_list_t current = NULL;
697 CK_RV rv = CKR_FUNCTION_FAILED;
698
699 if ((rv = pkcs11h_initialize()) != CKR_OK)
700 {
701 msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
702 goto cleanup;
703 }
704
705 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
706 {
707 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
708 goto cleanup;
709 }
710
711 pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));
712
713 if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
714 {
715 msg(M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv,
716 pkcs11h_getMessage(rv));
717 goto cleanup;
718 }
719
720 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
721 {
722 msg(M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
723 goto cleanup;
724 }
725
726 if (!pkcs11_addProvider(provider, TRUE, 0, cert_private ? TRUE : FALSE))
727 {
728 msg(M_FATAL, "Failed to add PKCS#11 provider '%s", provider);
729 goto cleanup;
730 }
731
732 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
733 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL,
734 &user_certificates))
735 != CKR_OK)
736 {
737 msg(M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
738 goto cleanup;
739 }
740
742 ("\n"
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)
747 {
748 pkcs11h_certificate_t certificate = NULL;
749 char *dn = NULL;
750 char serial[1024] = { 0 };
751 char *ser = NULL;
752 size_t ser_len = 0;
753
754 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &ser_len,
755 current->certificate_id))
756 != CKR_OK)
757 {
758 msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
759 pkcs11h_getMessage(rv));
760 goto cleanup1;
761 }
762
763 if (rv == CKR_OK && (ser = (char *)malloc(ser_len)) == NULL)
764 {
765 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
766 goto cleanup1;
767 }
768
769 if ((rv =
770 pkcs11h_certificate_serializeCertificateId(ser, &ser_len, current->certificate_id))
771 != CKR_OK)
772 {
773 msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
774 pkcs11h_getMessage(rv));
775 goto cleanup1;
776 }
777
778 if ((rv = pkcs11h_certificate_create(current->certificate_id, NULL,
779 PKCS11H_PROMPT_MASK_ALLOW_ALL,
780 PKCS11H_PIN_CACHE_INFINITE, &certificate)))
781 {
782 msg(M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
783 goto cleanup1;
784 }
785
786 if ((dn = pkcs11_certificate_dn(certificate, &gc)) == NULL)
787 {
788 goto cleanup1;
789 }
790
791 if ((pkcs11_certificate_serial(certificate, serial, sizeof(serial))))
792 {
793 goto cleanup1;
794 }
795
797 ("\n"
798 "Certificate\n"
799 " DN: %s\n"
800 " Serial: %s\n"
801 " Serialized id: %s\n"),
802 dn, serial, ser);
803
804cleanup1:
805
806 if (certificate != NULL)
807 {
808 pkcs11h_certificate_freeCertificate(certificate);
809 certificate = NULL;
810 }
811
812 free(ser);
813 ser = NULL;
814 }
815
816cleanup:
817 pkcs11h_certificate_freeCertificateIdList(user_certificates);
818 user_certificates = NULL;
819
820 pkcs11h_terminate();
821 gc_free(&gc);
822}
823#endif /* ENABLE_PKCS11 */
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:89
#define BSTR(buf)
Definition buffer.h:128
#define BLEN(buf)
Definition buffer.h:126
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:361
static void gc_free(struct gc_arena *a)
Definition buffer.h:1015
static struct gc_arena gc_new(void)
Definition buffer.h:1007
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.
Definition console.h:120
#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:474
#define GET_USER_PASS_MANAGEMENT
Definition misc.h:110
#define GET_USER_PASS_PASSWORD_ONLY
Definition misc.h:112
#define GET_USER_PASS_NEED_OK
Definition misc.h:113
#define GET_USER_PASS_NOFATAL
Definition misc.h:114
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:150
#define GET_USER_PASS_NEED_STR
Definition misc.h:115
#define CLEAR(x)
Definition basic.h:32
msglvl_t get_debug_level(void)
Definition error.c:134
#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:172
#define msg(flags,...)
Definition error.h:152
unsigned int msglvl_t
Definition error.h:77
#define ASSERT(x)
Definition error.h:219
#define M_WARN
Definition error.h:92
static time_t openvpn_time(time_t *t)
Definition otime.h:94
PKCS #11 SSL library-specific backend.
bool platform_absolute_pathname(const char *pathname)
Return true if pathname is absolute.
Definition platform.c:640
int openvpn_base64_encode(const void *data, int size, char **str)
Definition base64.c:51
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
Structure that wraps the TLS context.
static int cleanup(void **state)
static bool pkcs11_id_management
struct gc_arena gc
Definition test_ssl.c:131