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
56static void
57__mysleep(const unsigned long usec)
58{
59#if defined(_WIN32)
60 Sleep(usec / 1000);
61#else
62 usleep(usec);
63#endif
64}
65
66
67static pkcs11h_engine_system_t s_pkcs11h_sys_engine = { malloc, free, __mytime, __mysleep,
68#if defined(_WIN32)
69 NULL
70#else
71 __mygettimeofday
72#endif
73};
74
75static unsigned
76_pkcs11_msg_pkcs112openvpn(const unsigned flags)
77{
78 unsigned openvpn_flags;
79
80 switch (flags)
81 {
82 case PKCS11H_LOG_DEBUG2:
83 openvpn_flags = D_PKCS11_DEBUG;
84 break;
85
86 case PKCS11H_LOG_DEBUG1:
87 openvpn_flags = D_SHOW_PKCS11;
88 break;
89
90 case PKCS11H_LOG_INFO:
91 openvpn_flags = M_INFO;
92 break;
93
94 case PKCS11H_LOG_WARN:
95 openvpn_flags = M_WARN;
96 break;
97
98 case PKCS11H_LOG_ERROR:
99 openvpn_flags = M_FATAL;
100 break;
101
102 default:
103 openvpn_flags = M_FATAL;
104 break;
105 }
106
107#if defined(ENABLE_PKCS11_FORCE_DEBUG)
108 openvpn_flags = M_INFO;
109#endif
110
111 return openvpn_flags;
112}
113
114static unsigned
115_pkcs11_msg_openvpn2pkcs11(const unsigned flags)
116{
117 unsigned pkcs11_flags;
118
119 if ((flags & D_PKCS11_DEBUG) != 0)
120 {
121 pkcs11_flags = PKCS11H_LOG_DEBUG2;
122 }
123 else if ((flags & D_SHOW_PKCS11) != 0)
124 {
125 pkcs11_flags = PKCS11H_LOG_DEBUG1;
126 }
127 else if ((flags & M_INFO) != 0)
128 {
129 pkcs11_flags = PKCS11H_LOG_INFO;
130 }
131 else if ((flags & M_WARN) != 0)
132 {
133 pkcs11_flags = PKCS11H_LOG_WARN;
134 }
135 else if ((flags & M_FATAL) != 0)
136 {
137 pkcs11_flags = PKCS11H_LOG_ERROR;
138 }
139 else
140 {
141 pkcs11_flags = PKCS11H_LOG_ERROR;
142 }
143
144#if defined(ENABLE_PKCS11_FORCE_DEBUG)
145 pkcs11_flags = PKCS11H_LOG_DEBUG2;
146#endif
147
148 return pkcs11_flags;
149}
150
151static void
152_pkcs11_openvpn_log(void *const global_data, unsigned flags, const char *const szFormat,
153 va_list args)
154{
155 char Buffer[10 * 1024];
156
157 (void)global_data;
158
159 vsnprintf(Buffer, sizeof(Buffer), szFormat, args);
160 Buffer[sizeof(Buffer) - 1] = 0;
161
162 msg(_pkcs11_msg_pkcs112openvpn(flags), "%s", Buffer);
163}
164
165static PKCS11H_BOOL
166_pkcs11_openvpn_token_prompt(void *const global_data, void *const user_data,
167 const pkcs11h_token_id_t token, const unsigned retry)
168{
169 struct user_pass token_resp;
170
171 (void)global_data;
172 (void)user_data;
173 (void)retry;
174
175 ASSERT(token != NULL);
176
177 CLEAR(token_resp);
178 token_resp.defined = false;
179 token_resp.nocache = true;
180 snprintf(token_resp.username, sizeof(token_resp.username), "Please insert %s token",
181 token->label);
182
183 if (!get_user_pass(&token_resp, NULL, "token-insertion-request",
185 {
186 return false;
187 }
188 else
189 {
190 return strcmp(token_resp.password, "ok") == 0;
191 }
192}
193
194static PKCS11H_BOOL
195_pkcs11_openvpn_pin_prompt(void *const global_data, void *const user_data,
196 const pkcs11h_token_id_t token, const unsigned retry, char *const pin,
197 const size_t pin_max)
198{
199 struct user_pass token_pass;
200 char prompt[1024];
201 CLEAR(token_pass);
202
203 (void)global_data;
204 (void)user_data;
205 (void)retry;
206
207 ASSERT(token != NULL);
208
209 snprintf(prompt, sizeof(prompt), "%s token", token->label);
210
211 token_pass.defined = false;
212 token_pass.nocache = true;
213
214 if (!get_user_pass(&token_pass, NULL, prompt,
217 {
218 return false;
219 }
220 else
221 {
222 strncpynt(pin, token_pass.password, pin_max);
223 purge_user_pass(&token_pass, true);
224
225 if (strlen(pin) == 0)
226 {
227 return false;
228 }
229 else
230 {
231 return true;
232 }
233 }
234}
235
236bool
237pkcs11_initialize(const bool protected_auth, const int nPINCachePeriod)
238{
239 CK_RV rv = CKR_FUNCTION_FAILED;
240
241 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_initialize - entered");
242
243 if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK)
244 {
245 msg(M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv,
246 pkcs11h_getMessage(rv));
247 goto cleanup;
248 }
249
250 if ((rv = pkcs11h_initialize()) != CKR_OK)
251 {
252 msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
253 goto cleanup;
254 }
255
256 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
257 {
258 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
259 goto cleanup;
260 }
261
262 pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));
263
264 if ((rv = pkcs11h_setForkMode(FALSE)) != CKR_OK)
265 {
266 msg(M_FATAL, "PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage(rv));
267 goto cleanup;
268 }
269
270 if ((rv = pkcs11h_setTokenPromptHook(_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK)
271 {
272 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
273 goto cleanup;
274 }
275
276 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK)
277 {
278 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
279 goto cleanup;
280 }
281
282 if ((rv = pkcs11h_setProtectedAuthentication(protected_auth)) != CKR_OK)
283 {
284 msg(M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv,
285 pkcs11h_getMessage(rv));
286 goto cleanup;
287 }
288
289 if ((rv = pkcs11h_setPINCachePeriod(nPINCachePeriod)) != CKR_OK)
290 {
291 msg(M_FATAL, "PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage(rv));
292 goto cleanup;
293 }
294
295 rv = CKR_OK;
296
297cleanup:
298 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_initialize - return %ld-'%s'", rv,
299 pkcs11h_getMessage(rv));
300
301 return rv == CKR_OK;
302}
303
304void
305pkcs11_terminate(void)
306{
307 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_terminate - entered");
308
309 pkcs11h_terminate();
310
311 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_terminate - return");
312}
313
314bool
315pkcs11_addProvider(const char *const provider, const bool protected_auth,
316 const unsigned private_mode, const bool cert_private)
317{
318 CK_RV rv = CKR_OK;
319
320 ASSERT(provider != NULL);
321
322 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x",
323 provider, private_mode);
324
325 msg(M_INFO, "PKCS#11: Adding PKCS#11 provider '%s'", provider);
326
327#if PKCS11H_VERSION >= ((1 << 16) | (28 << 8) | (0 << 0))
328 if ((rv = pkcs11h_registerProvider(provider)) != CKR_OK)
329 {
330 msg(M_WARN, "PKCS#11: Cannot register provider '%s' %ld-'%s'", provider, rv,
331 pkcs11h_getMessage(rv));
332 }
333 else
334 {
335 PKCS11H_BOOL allow_protected_auth = protected_auth;
336 PKCS11H_BOOL cert_is_private = cert_private;
337
338 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOCATION, provider,
339 strlen(provider) + 1);
340
341 if (rv == CKR_OK)
342 {
343 rv = pkcs11h_setProviderProperty(provider,
344 PKCS11H_PROVIDER_PROPERTY_ALLOW_PROTECTED_AUTH,
345 &allow_protected_auth, sizeof(allow_protected_auth));
346 }
347 if (rv == CKR_OK)
348 {
349 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_MASK_PRIVATE_MODE,
350 &private_mode, sizeof(private_mode));
351 }
352 if (rv == CKR_OK)
353 {
354 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_CERT_IS_PRIVATE,
355 &cert_is_private, sizeof(cert_is_private));
356 }
357#if defined(WIN32) && defined(PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS)
358 if (rv == CKR_OK && platform_absolute_pathname(provider))
359 {
360 unsigned loader_flags =
361 LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
362 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS,
363 &loader_flags, sizeof(loader_flags));
364 }
365#endif
366
367 if (rv != CKR_OK || (rv = pkcs11h_initializeProvider(provider)) != CKR_OK)
368 {
369 msg(M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
370 pkcs11h_getMessage(rv));
371 pkcs11h_removeProvider(provider);
372 }
373 }
374#else /* if PKCS11H_VERSION >= ((1<<16) | (28<<8) | (0<<0)) */
375 if ((rv = pkcs11h_addProvider(provider, provider, protected_auth, private_mode,
376 PKCS11H_SLOTEVENT_METHOD_AUTO, 0, cert_private))
377 != CKR_OK)
378 {
379 msg(M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv,
380 pkcs11h_getMessage(rv));
381 }
382#endif /* if PKCS11H_VERSION >= ((1<<16) | (28<<8) | (0<<0)) */
383
384 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'", rv,
385 pkcs11h_getMessage(rv));
386
387 return rv == CKR_OK;
388}
389
390int
391pkcs11_logout(void)
392{
393 return pkcs11h_logout() == CKR_OK;
394}
395
396int
397pkcs11_management_id_count(void)
398{
399 pkcs11h_certificate_id_list_t id_list = NULL;
400 pkcs11h_certificate_id_list_t t = NULL;
401 CK_RV rv = CKR_OK;
402 int count = 0;
403
404 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_count - entered");
405
406 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
407 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
408 != CKR_OK)
409 {
410 msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
411 goto cleanup;
412 }
413
414 for (count = 0, t = id_list; t != NULL; t = t->next)
415 {
416 count++;
417 }
418
419cleanup:
420
421 pkcs11h_certificate_freeCertificateIdList(id_list);
422 id_list = NULL;
423
424 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_count - return count=%d", count);
425
426 return count;
427}
428
429bool
430pkcs11_management_id_get(const int index, char **id, char **base64)
431{
432 pkcs11h_certificate_id_list_t id_list = NULL;
433 pkcs11h_certificate_id_list_t entry = NULL;
434#if 0 /* certificate_id seems to be unused -- JY */
435 pkcs11h_certificate_id_t certificate_id = NULL;
436#endif
437 pkcs11h_certificate_t certificate = NULL;
438 CK_RV rv = CKR_OK;
439 unsigned char *certificate_blob = NULL;
440 size_t certificate_blob_size = 0;
441 size_t max;
442 char *internal_id = NULL;
443 char *internal_base64 = NULL;
444 int count = 0;
445 bool success = false;
446
447 ASSERT(id != NULL);
448 ASSERT(base64 != NULL);
449
450 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - entered index=%d", index);
451
452 *id = NULL;
453 *base64 = NULL;
454
455 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
456 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL, &id_list))
457 != CKR_OK)
458 {
459 msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
460 goto cleanup;
461 }
462
463 entry = id_list;
464 count = 0;
465 while (entry != NULL && count != index)
466 {
467 count++;
468 entry = entry->next;
469 }
470
471 if (entry == NULL)
472 {
473 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
474 index);
475 goto cleanup;
476 }
477
478 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &max, entry->certificate_id))
479 != CKR_OK)
480 {
481 msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
482 pkcs11h_getMessage(rv));
483 goto cleanup;
484 }
485
486 if ((internal_id = (char *)malloc(max)) == NULL)
487 {
488 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
489 goto cleanup;
490 }
491
492 if ((rv = pkcs11h_certificate_serializeCertificateId(internal_id, &max, entry->certificate_id))
493 != CKR_OK)
494 {
495 msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv,
496 pkcs11h_getMessage(rv));
497 goto cleanup;
498 }
499
500 if ((rv = pkcs11h_certificate_create(entry->certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
501 PKCS11H_PIN_CACHE_INFINITE, &certificate))
502 != CKR_OK)
503 {
504 msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
505 goto cleanup;
506 }
507
508 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, NULL, &certificate_blob_size))
509 != CKR_OK)
510 {
511 msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
512 goto cleanup;
513 }
514
515 if ((certificate_blob = (unsigned char *)malloc(certificate_blob_size)) == NULL)
516 {
517 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
518 goto cleanup;
519 }
520
521 if ((rv = pkcs11h_certificate_getCertificateBlob(certificate, certificate_blob,
522 &certificate_blob_size))
523 != CKR_OK)
524 {
525 msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
526 goto cleanup;
527 }
528
529 if (openvpn_base64_encode(certificate_blob, certificate_blob_size, &internal_base64) == -1)
530 {
531 msg(M_WARN, "PKCS#11: Cannot encode certificate");
532 goto cleanup;
533 }
534
535 *id = internal_id;
536 internal_id = NULL;
537 *base64 = internal_base64;
538 internal_base64 = NULL;
539 success = true;
540
541cleanup:
542
543 pkcs11h_certificate_freeCertificateIdList(id_list);
544 id_list = NULL;
545
546 free(internal_id);
547 internal_id = NULL;
548
549 free(internal_base64);
550 internal_base64 = NULL;
551
552 free(certificate_blob);
553 certificate_blob = NULL;
554
555 dmsg(D_PKCS11_DEBUG, "PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
556 success ? 1 : 0, *id);
557
558 return success;
559}
560
561int
562tls_ctx_use_pkcs11(struct tls_root_ctx *const ssl_ctx, bool pkcs11_id_management,
563 const char *const pkcs11_id)
564{
565 pkcs11h_certificate_id_t certificate_id = NULL;
566 pkcs11h_certificate_t certificate = NULL;
567 CK_RV rv = CKR_OK;
568
569 bool ok = false;
570
571 ASSERT(ssl_ctx != NULL);
572 ASSERT(pkcs11_id_management || pkcs11_id != NULL);
573
574 dmsg(
576 "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
577 (void *)ssl_ctx, pkcs11_id_management ? 1 : 0, pkcs11_id);
578
580 {
581 struct user_pass id_resp;
582
583 CLEAR(id_resp);
584
585 id_resp.defined = false;
586 id_resp.nocache = true;
587 snprintf(id_resp.username, sizeof(id_resp.username), "Please specify PKCS#11 id to use");
588
589 if (!get_user_pass(&id_resp, NULL, "pkcs11-id-request",
592 {
593 goto cleanup;
594 }
595
596 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, id_resp.password))
597 != CKR_OK)
598 {
599 msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
600 goto cleanup;
601 }
602 }
603 else
604 {
605 if ((rv = pkcs11h_certificate_deserializeCertificateId(&certificate_id, pkcs11_id))
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
613 if ((rv = pkcs11h_certificate_create(certificate_id, NULL, PKCS11H_PROMPT_MASK_ALLOW_ALL,
614 PKCS11H_PIN_CACHE_INFINITE, &certificate))
615 != CKR_OK)
616 {
617 msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
618 goto cleanup;
619 }
620
621 if ((pkcs11_init_tls_session(certificate, ssl_ctx)))
622 {
623 /* Handled by SSL context free */
624 certificate = NULL;
625 goto cleanup;
626 }
627
628 /* Handled by SSL context free */
629 certificate = NULL;
630 ok = true;
631
632cleanup:
633 if (certificate != NULL)
634 {
635 pkcs11h_certificate_freeCertificate(certificate);
636 certificate = NULL;
637 }
638
639 if (certificate_id != NULL)
640 {
641 pkcs11h_certificate_freeCertificateId(certificate_id);
642 certificate_id = NULL;
643 }
644
645 dmsg(D_PKCS11_DEBUG, "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld", ok ? 1 : 0, rv);
646
647 return ok ? 1 : 0;
648}
649
650static PKCS11H_BOOL
651_pkcs11_openvpn_show_pkcs11_ids_pin_prompt(void *const global_data, void *const user_data,
652 const pkcs11h_token_id_t token, const unsigned retry,
653 char *const pin, const size_t pin_max)
654{
655 struct gc_arena gc = gc_new();
656 struct buffer pass_prompt = alloc_buf_gc(128, &gc);
657
660 (void)retry;
661
662 ASSERT(token != NULL);
663
664 buf_printf(&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display);
666 {
667 msg(M_FATAL, "Could not retrieve the PIN");
668 }
669
670 gc_free(&gc);
671
672 if (!strcmp(pin, "cancel"))
673 {
674 return FALSE;
675 }
676 else
677 {
678 return TRUE;
679 }
680}
681
682void
683show_pkcs11_ids(const char *const provider, bool cert_private)
684{
685 struct gc_arena gc = gc_new();
686 pkcs11h_certificate_id_list_t user_certificates = NULL;
687 pkcs11h_certificate_id_list_t current = NULL;
688 CK_RV rv = CKR_FUNCTION_FAILED;
689
690 if ((rv = pkcs11h_initialize()) != CKR_OK)
691 {
692 msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
693 goto cleanup;
694 }
695
696 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
697 {
698 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
699 goto cleanup;
700 }
701
702 pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));
703
704 if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
705 {
706 msg(M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv,
707 pkcs11h_getMessage(rv));
708 goto cleanup;
709 }
710
711 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
712 {
713 msg(M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
714 goto cleanup;
715 }
716
717 if (!pkcs11_addProvider(provider, TRUE, 0, cert_private ? TRUE : FALSE))
718 {
719 msg(M_FATAL, "Failed to add PKCS#11 provider '%s", provider);
720 goto cleanup;
721 }
722
723 if ((rv = pkcs11h_certificate_enumCertificateIds(PKCS11H_ENUM_METHOD_CACHE_EXIST, NULL,
724 PKCS11H_PROMPT_MASK_ALLOW_ALL, NULL,
725 &user_certificates))
726 != CKR_OK)
727 {
728 msg(M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
729 goto cleanup;
730 }
731
733 ("\n"
734 "The following objects are available for use.\n"
735 "Each object shown below may be used as parameter to\n"
736 "--pkcs11-id option please remember to use single quote mark.\n"));
737 for (current = user_certificates; current != NULL; current = current->next)
738 {
739 pkcs11h_certificate_t certificate = NULL;
740 char *dn = NULL;
741 char serial[1024] = { 0 };
742 char *ser = NULL;
743 size_t ser_len = 0;
744
745 if ((rv = pkcs11h_certificate_serializeCertificateId(NULL, &ser_len,
746 current->certificate_id))
747 != CKR_OK)
748 {
749 msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
750 pkcs11h_getMessage(rv));
751 goto cleanup1;
752 }
753
754 if (rv == CKR_OK && (ser = (char *)malloc(ser_len)) == NULL)
755 {
756 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
757 goto cleanup1;
758 }
759
760 if ((rv =
761 pkcs11h_certificate_serializeCertificateId(ser, &ser_len, current->certificate_id))
762 != CKR_OK)
763 {
764 msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv,
765 pkcs11h_getMessage(rv));
766 goto cleanup1;
767 }
768
769 if ((rv = pkcs11h_certificate_create(current->certificate_id, NULL,
770 PKCS11H_PROMPT_MASK_ALLOW_ALL,
771 PKCS11H_PIN_CACHE_INFINITE, &certificate)))
772 {
773 msg(M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
774 goto cleanup1;
775 }
776
777 if ((dn = pkcs11_certificate_dn(certificate, &gc)) == NULL)
778 {
779 goto cleanup1;
780 }
781
782 if ((pkcs11_certificate_serial(certificate, serial, sizeof(serial))))
783 {
784 goto cleanup1;
785 }
786
788 ("\n"
789 "Certificate\n"
790 " DN: %s\n"
791 " Serial: %s\n"
792 " Serialized id: %s\n"),
793 dn, serial, ser);
794
795cleanup1:
796
797 if (certificate != NULL)
798 {
799 pkcs11h_certificate_freeCertificate(certificate);
800 certificate = NULL;
801 }
802
803 free(ser);
804 ser = NULL;
805 }
806
807cleanup:
808 pkcs11h_certificate_freeCertificateIdList(user_certificates);
809 user_certificates = NULL;
810
811 pkcs11h_terminate();
812 gc_free(&gc);
813}
814#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:465
#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
int get_debug_level(void)
Definition error.c:136
#define M_NOPREFIX
Definition error.h:96
#define M_FATAL
Definition error.h:88
#define M_NOLF
Definition error.h:100
#define dmsg(flags,...)
Definition error.h:170
#define msg(flags,...)
Definition error.h:150
#define ASSERT(x)
Definition error.h:217
#define M_WARN
Definition error.h:90
static time_t openvpn_time(time_t *t)
Definition otime.h:89
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:154