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-2024 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, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "syshead.h"
29
30#if defined(ENABLE_PKCS11)
31
32#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
33#include "basic.h"
34#include "error.h"
35#include "manage.h"
36#include "base64.h"
37#include "pkcs11.h"
38#include "misc.h"
39#include "otime.h"
40#include "console.h"
41#include "pkcs11_backend.h"
42
43static
44time_t
45__mytime(void)
46{
47 return openvpn_time(NULL);
48}
49
50#if !defined(_WIN32)
51static
52int
53__mygettimeofday(struct timeval *tv)
54{
55 return gettimeofday(tv, NULL);
56}
57#endif
58
59static
60void
61__mysleep(const unsigned long usec)
62{
63#if defined(_WIN32)
64 Sleep(usec/1000);
65#else
66 usleep(usec);
67#endif
68}
69
70
71static pkcs11h_engine_system_t s_pkcs11h_sys_engine = {
72 malloc,
73 free,
74 __mytime,
75 __mysleep,
76#if defined(_WIN32)
77 NULL
78#else
79 __mygettimeofday
80#endif
81};
82
83static
84unsigned
85_pkcs11_msg_pkcs112openvpn(
86 const unsigned flags
87 )
88{
89 unsigned openvpn_flags;
90
91 switch (flags)
92 {
93 case PKCS11H_LOG_DEBUG2:
94 openvpn_flags = D_PKCS11_DEBUG;
95 break;
96
97 case PKCS11H_LOG_DEBUG1:
98 openvpn_flags = D_SHOW_PKCS11;
99 break;
100
101 case PKCS11H_LOG_INFO:
102 openvpn_flags = M_INFO;
103 break;
104
105 case PKCS11H_LOG_WARN:
106 openvpn_flags = M_WARN;
107 break;
108
109 case PKCS11H_LOG_ERROR:
110 openvpn_flags = M_FATAL;
111 break;
112
113 default:
114 openvpn_flags = M_FATAL;
115 break;
116 }
117
118#if defined(ENABLE_PKCS11_FORCE_DEBUG)
119 openvpn_flags = M_INFO;
120#endif
121
122 return openvpn_flags;
123}
124
125static
126unsigned
127_pkcs11_msg_openvpn2pkcs11(
128 const unsigned flags
129 )
130{
131 unsigned pkcs11_flags;
132
133 if ((flags & D_PKCS11_DEBUG) != 0)
134 {
135 pkcs11_flags = PKCS11H_LOG_DEBUG2;
136 }
137 else if ((flags & D_SHOW_PKCS11) != 0)
138 {
139 pkcs11_flags = PKCS11H_LOG_DEBUG1;
140 }
141 else if ((flags & M_INFO) != 0)
142 {
143 pkcs11_flags = PKCS11H_LOG_INFO;
144 }
145 else if ((flags & M_WARN) != 0)
146 {
147 pkcs11_flags = PKCS11H_LOG_WARN;
148 }
149 else if ((flags & M_FATAL) != 0)
150 {
151 pkcs11_flags = PKCS11H_LOG_ERROR;
152 }
153 else
154 {
155 pkcs11_flags = PKCS11H_LOG_ERROR;
156 }
157
158#if defined(ENABLE_PKCS11_FORCE_DEBUG)
159 pkcs11_flags = PKCS11H_LOG_DEBUG2;
160#endif
161
162 return pkcs11_flags;
163}
164
165static
166void
167_pkcs11_openvpn_log(
168 void *const global_data,
169 unsigned flags,
170 const char *const szFormat,
171 va_list args
172 )
173{
174 char Buffer[10*1024];
175
176 (void)global_data;
177
178 vsnprintf(Buffer, sizeof(Buffer), szFormat, args);
179 Buffer[sizeof(Buffer)-1] = 0;
180
181 msg(_pkcs11_msg_pkcs112openvpn(flags), "%s", Buffer);
182}
183
184static
185PKCS11H_BOOL
186_pkcs11_openvpn_token_prompt(
187 void *const global_data,
188 void *const user_data,
189 const pkcs11h_token_id_t token,
190 const unsigned retry
191 )
192{
193 struct user_pass token_resp;
194
195 (void)global_data;
196 (void)user_data;
197 (void)retry;
198
199 ASSERT(token!=NULL);
200
201 CLEAR(token_resp);
202 token_resp.defined = false;
203 token_resp.nocache = true;
204 snprintf(
205 token_resp.username,
206 sizeof(token_resp.username),
207 "Please insert %s token",
208 token->label
209 );
210
211 if (
213 &token_resp,
214 NULL,
215 "token-insertion-request",
217 )
218 )
219 {
220 return false;
221 }
222 else
223 {
224 return strcmp(token_resp.password, "ok") == 0;
225 }
226}
227
228static
229PKCS11H_BOOL
230_pkcs11_openvpn_pin_prompt(
231 void *const global_data,
232 void *const user_data,
233 const pkcs11h_token_id_t token,
234 const unsigned retry,
235 char *const pin,
236 const size_t pin_max
237 )
238{
239 struct user_pass token_pass;
240 char prompt[1024];
241 CLEAR(token_pass);
242
243 (void)global_data;
244 (void)user_data;
245 (void)retry;
246
247 ASSERT(token!=NULL);
248
249 snprintf(prompt, sizeof(prompt), "%s token", token->label);
250
251 token_pass.defined = false;
252 token_pass.nocache = true;
253
254 if (
256 &token_pass,
257 NULL,
258 prompt,
260 )
261 )
262 {
263 return false;
264 }
265 else
266 {
267 strncpynt(pin, token_pass.password, pin_max);
268 purge_user_pass(&token_pass, true);
269
270 if (strlen(pin) == 0)
271 {
272 return false;
273 }
274 else
275 {
276 return true;
277 }
278 }
279}
280
281bool
282pkcs11_initialize(
283 const bool protected_auth,
284 const int nPINCachePeriod
285 )
286{
287 CK_RV rv = CKR_FUNCTION_FAILED;
288
289 dmsg(
291 "PKCS#11: pkcs11_initialize - entered"
292 );
293
294 if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK)
295 {
296 msg(M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv, pkcs11h_getMessage(rv));
297 goto cleanup;
298 }
299
300 if ((rv = pkcs11h_initialize()) != CKR_OK)
301 {
302 msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
303 goto cleanup;
304 }
305
306 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
307 {
308 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
309 goto cleanup;
310 }
311
312 pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));
313
314 if ((rv = pkcs11h_setForkMode(FALSE)) != CKR_OK)
315 {
316 msg(M_FATAL, "PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage(rv));
317 goto cleanup;
318 }
319
320 if ((rv = pkcs11h_setTokenPromptHook(_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK)
321 {
322 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
323 goto cleanup;
324 }
325
326 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK)
327 {
328 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
329 goto cleanup;
330 }
331
332 if ((rv = pkcs11h_setProtectedAuthentication(protected_auth)) != CKR_OK)
333 {
334 msg(M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage(rv));
335 goto cleanup;
336 }
337
338 if ((rv = pkcs11h_setPINCachePeriod(nPINCachePeriod)) != CKR_OK)
339 {
340 msg(M_FATAL, "PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage(rv));
341 goto cleanup;
342 }
343
344 rv = CKR_OK;
345
346cleanup:
347 dmsg(
349 "PKCS#11: pkcs11_initialize - return %ld-'%s'",
350 rv,
351 pkcs11h_getMessage(rv)
352 );
353
354 return rv == CKR_OK;
355}
356
357void
358pkcs11_terminate(void)
359{
360 dmsg(
362 "PKCS#11: pkcs11_terminate - entered"
363 );
364
365 pkcs11h_terminate();
366
367 dmsg(
369 "PKCS#11: pkcs11_terminate - return"
370 );
371}
372
373bool
374pkcs11_addProvider(
375 const char *const provider,
376 const bool protected_auth,
377 const unsigned private_mode,
378 const bool cert_private
379 )
380{
381 CK_RV rv = CKR_OK;
382
383 ASSERT(provider!=NULL);
384
385 dmsg(
387 "PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x",
388 provider,
389 private_mode
390 );
391
392 msg(
393 M_INFO,
394 "PKCS#11: Adding PKCS#11 provider '%s'",
395 provider
396 );
397
398#if PKCS11H_VERSION >= ((1<<16) | (28<<8) | (0<<0))
399 if ((rv = pkcs11h_registerProvider(provider)) != CKR_OK)
400 {
401 msg(M_WARN, "PKCS#11: Cannot register provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage(rv));
402 }
403 else
404 {
405 PKCS11H_BOOL allow_protected_auth = protected_auth;
406 PKCS11H_BOOL cert_is_private = cert_private;
407
408 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOCATION, provider, strlen(provider) + 1);
409
410 if (rv == CKR_OK)
411 {
412 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_ALLOW_PROTECTED_AUTH, &allow_protected_auth, sizeof(allow_protected_auth));
413 }
414 if (rv == CKR_OK)
415 {
416 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_MASK_PRIVATE_MODE, &private_mode, sizeof(private_mode));
417 }
418 if (rv == CKR_OK)
419 {
420 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_CERT_IS_PRIVATE, &cert_is_private, sizeof(cert_is_private));
421 }
422#if defined(WIN32) && defined(PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS)
423 if (rv == CKR_OK && platform_absolute_pathname(provider))
424 {
425 unsigned loader_flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
426 rv = pkcs11h_setProviderProperty(provider, PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS, &loader_flags, sizeof(loader_flags));
427 }
428#endif
429
430 if (rv != CKR_OK || (rv = pkcs11h_initializeProvider(provider)) != CKR_OK)
431 {
432 msg(M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage(rv));
433 pkcs11h_removeProvider(provider);
434 }
435 }
436#else /* if PKCS11H_VERSION >= ((1<<16) | (28<<8) | (0<<0)) */
437 if (
438 (rv = pkcs11h_addProvider(
439 provider,
440 provider,
441 protected_auth,
442 private_mode,
443 PKCS11H_SLOTEVENT_METHOD_AUTO,
444 0,
445 cert_private
446 )) != CKR_OK
447 )
448 {
449 msg(M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage(rv));
450 }
451#endif /* if PKCS11H_VERSION >= ((1<<16) | (28<<8) | (0<<0)) */
452
453 dmsg(
455 "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'",
456 rv,
457 pkcs11h_getMessage(rv)
458 );
459
460 return rv == CKR_OK;
461}
462
463int
464pkcs11_logout(void)
465{
466 return pkcs11h_logout() == CKR_OK;
467}
468
469int
470pkcs11_management_id_count(void)
471{
472 pkcs11h_certificate_id_list_t id_list = NULL;
473 pkcs11h_certificate_id_list_t t = NULL;
474 CK_RV rv = CKR_OK;
475 int count = 0;
476
477 dmsg(
479 "PKCS#11: pkcs11_management_id_count - entered"
480 );
481
482 if (
483 (rv = pkcs11h_certificate_enumCertificateIds(
484 PKCS11H_ENUM_METHOD_CACHE_EXIST,
485 NULL,
486 PKCS11H_PROMPT_MASK_ALLOW_ALL,
487 NULL,
488 &id_list
489 )) != CKR_OK
490 )
491 {
492 msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
493 goto cleanup;
494 }
495
496 for (count = 0, t = id_list; t != NULL; t = t->next)
497 {
498 count++;
499 }
500
501cleanup:
502
503 pkcs11h_certificate_freeCertificateIdList(id_list);
504 id_list = NULL;
505
506 dmsg(
508 "PKCS#11: pkcs11_management_id_count - return count=%d",
509 count
510 );
511
512 return count;
513}
514
515bool
516pkcs11_management_id_get(
517 const int index,
518 char **id,
519 char **base64
520 )
521{
522 pkcs11h_certificate_id_list_t id_list = NULL;
523 pkcs11h_certificate_id_list_t entry = NULL;
524#if 0 /* certificate_id seems to be unused -- JY */
525 pkcs11h_certificate_id_t certificate_id = NULL;
526#endif
527 pkcs11h_certificate_t certificate = NULL;
528 CK_RV rv = CKR_OK;
529 unsigned char *certificate_blob = NULL;
530 size_t certificate_blob_size = 0;
531 size_t max;
532 char *internal_id = NULL;
533 char *internal_base64 = NULL;
534 int count = 0;
535 bool success = false;
536
537 ASSERT(id!=NULL);
538 ASSERT(base64!=NULL);
539
540 dmsg(
542 "PKCS#11: pkcs11_management_id_get - entered index=%d",
543 index
544 );
545
546 *id = NULL;
547 *base64 = NULL;
548
549 if (
550 (rv = pkcs11h_certificate_enumCertificateIds(
551 PKCS11H_ENUM_METHOD_CACHE_EXIST,
552 NULL,
553 PKCS11H_PROMPT_MASK_ALLOW_ALL,
554 NULL,
555 &id_list
556 )) != CKR_OK
557 )
558 {
559 msg(M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage(rv));
560 goto cleanup;
561 }
562
563 entry = id_list;
564 count = 0;
565 while (entry != NULL && count != index)
566 {
567 count++;
568 entry = entry->next;
569 }
570
571 if (entry == NULL)
572 {
573 dmsg(
575 "PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
576 index
577 );
578 goto cleanup;
579 }
580
581 if (
582 (rv = pkcs11h_certificate_serializeCertificateId(
583 NULL,
584 &max,
585 entry->certificate_id
586 )) != CKR_OK
587 )
588 {
589 msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage(rv));
590 goto cleanup;
591 }
592
593 if ((internal_id = (char *)malloc(max)) == NULL)
594 {
595 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
596 goto cleanup;
597 }
598
599 if (
600 (rv = pkcs11h_certificate_serializeCertificateId(
601 internal_id,
602 &max,
603 entry->certificate_id
604 )) != CKR_OK
605 )
606 {
607 msg(M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage(rv));
608 goto cleanup;
609 }
610
611 if (
612 (rv = pkcs11h_certificate_create(
613 entry->certificate_id,
614 NULL,
615 PKCS11H_PROMPT_MASK_ALLOW_ALL,
616 PKCS11H_PIN_CACHE_INFINITE,
617 &certificate
618 )) != CKR_OK
619 )
620 {
621 msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
622 goto cleanup;
623 }
624
625 if (
626 (rv = pkcs11h_certificate_getCertificateBlob(
627 certificate,
628 NULL,
629 &certificate_blob_size
630 )) != CKR_OK
631 )
632 {
633 msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
634 goto cleanup;
635 }
636
637 if ((certificate_blob = (unsigned char *)malloc(certificate_blob_size)) == NULL)
638 {
639 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
640 goto cleanup;
641 }
642
643 if (
644 (rv = pkcs11h_certificate_getCertificateBlob(
645 certificate,
646 certificate_blob,
647 &certificate_blob_size
648 )) != CKR_OK
649 )
650 {
651 msg(M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage(rv));
652 goto cleanup;
653 }
654
655 if (openvpn_base64_encode(certificate_blob, certificate_blob_size, &internal_base64) == -1)
656 {
657 msg(M_WARN, "PKCS#11: Cannot encode certificate");
658 goto cleanup;
659 }
660
661 *id = internal_id;
662 internal_id = NULL;
663 *base64 = internal_base64;
664 internal_base64 = NULL;
665 success = true;
666
667cleanup:
668
669 pkcs11h_certificate_freeCertificateIdList(id_list);
670 id_list = NULL;
671
672 free(internal_id);
673 internal_id = NULL;
674
675 free(internal_base64);
676 internal_base64 = NULL;
677
678 free(certificate_blob);
679 certificate_blob = NULL;
680
681 dmsg(
683 "PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
684 success ? 1 : 0,
685 *id
686 );
687
688 return success;
689}
690
691int
692tls_ctx_use_pkcs11(
693 struct tls_root_ctx *const ssl_ctx,
695 const char *const pkcs11_id
696 )
697{
698 pkcs11h_certificate_id_t certificate_id = NULL;
699 pkcs11h_certificate_t certificate = NULL;
700 CK_RV rv = CKR_OK;
701
702 bool ok = false;
703
704 ASSERT(ssl_ctx!=NULL);
705 ASSERT(pkcs11_id_management || pkcs11_id!=NULL);
706
707 dmsg(
709 "PKCS#11: tls_ctx_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
710 (void *)ssl_ctx,
711 pkcs11_id_management ? 1 : 0,
712 pkcs11_id
713 );
714
716 {
717 struct user_pass id_resp;
718
719 CLEAR(id_resp);
720
721 id_resp.defined = false;
722 id_resp.nocache = true;
723 snprintf(
724 id_resp.username,
725 sizeof(id_resp.username),
726 "Please specify PKCS#11 id to use"
727 );
728
729 if (
731 &id_resp,
732 NULL,
733 "pkcs11-id-request",
735 )
736 )
737 {
738 goto cleanup;
739 }
740
741 if (
742 (rv = pkcs11h_certificate_deserializeCertificateId(
743 &certificate_id,
744 id_resp.password
745 )) != CKR_OK
746 )
747 {
748 msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
749 goto cleanup;
750 }
751 }
752 else
753 {
754 if (
755 (rv = pkcs11h_certificate_deserializeCertificateId(
756 &certificate_id,
757 pkcs11_id
758 )) != CKR_OK
759 )
760 {
761 msg(M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage(rv));
762 goto cleanup;
763 }
764 }
765
766 if (
767 (rv = pkcs11h_certificate_create(
768 certificate_id,
769 NULL,
770 PKCS11H_PROMPT_MASK_ALLOW_ALL,
771 PKCS11H_PIN_CACHE_INFINITE,
772 &certificate
773 )) != CKR_OK
774 )
775 {
776 msg(M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
777 goto cleanup;
778 }
779
780 if (
781 (pkcs11_init_tls_session(
782 certificate,
783 ssl_ctx
784 ))
785 )
786 {
787 /* Handled by SSL context free */
788 certificate = NULL;
789 goto cleanup;
790 }
791
792 /* Handled by SSL context free */
793 certificate = NULL;
794 ok = true;
795
796cleanup:
797 if (certificate != NULL)
798 {
799 pkcs11h_certificate_freeCertificate(certificate);
800 certificate = NULL;
801 }
802
803 if (certificate_id != NULL)
804 {
805 pkcs11h_certificate_freeCertificateId(certificate_id);
806 certificate_id = NULL;
807 }
808
809 dmsg(
811 "PKCS#11: tls_ctx_use_pkcs11 - return ok=%d, rv=%ld",
812 ok ? 1 : 0,
813 rv
814 );
815
816 return ok ? 1 : 0;
817}
818
819static
820PKCS11H_BOOL
821_pkcs11_openvpn_show_pkcs11_ids_pin_prompt(
822 void *const global_data,
823 void *const user_data,
824 const pkcs11h_token_id_t token,
825 const unsigned retry,
826 char *const pin,
827 const size_t pin_max
828 )
829{
830 struct gc_arena gc = gc_new();
831 struct buffer pass_prompt = alloc_buf_gc(128, &gc);
832
835 (void)retry;
836
837 ASSERT(token!=NULL);
838
839 buf_printf(&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display);
841 pin, pin_max, false))
842 {
843 msg(M_FATAL, "Could not retrieve the PIN");
844 }
845
846 gc_free(&gc);
847
848 if (!strcmp(pin, "cancel"))
849 {
850 return FALSE;
851 }
852 else
853 {
854 return TRUE;
855 }
856}
857
858void
860 const char *const provider,
861 bool cert_private
862 )
863{
864 struct gc_arena gc = gc_new();
865 pkcs11h_certificate_id_list_t user_certificates = NULL;
866 pkcs11h_certificate_id_list_t current = NULL;
867 CK_RV rv = CKR_FUNCTION_FAILED;
868
869 if ((rv = pkcs11h_initialize()) != CKR_OK)
870 {
871 msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
872 goto cleanup;
873 }
874
875 if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
876 {
877 msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
878 goto cleanup;
879 }
880
881 pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));
882
883 if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
884 {
885 msg(M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv, pkcs11h_getMessage(rv));
886 goto cleanup;
887 }
888
889 if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
890 {
891 msg(M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
892 goto cleanup;
893 }
894
895 if (!pkcs11_addProvider(provider, TRUE, 0, cert_private ? TRUE : FALSE))
896 {
897 msg(M_FATAL, "Failed to add PKCS#11 provider '%s", provider);
898 goto cleanup;
899 }
900
901 if (
902 (rv = pkcs11h_certificate_enumCertificateIds(
903 PKCS11H_ENUM_METHOD_CACHE_EXIST,
904 NULL,
905 PKCS11H_PROMPT_MASK_ALLOW_ALL,
906 NULL,
907 &user_certificates
908 )) != CKR_OK
909 )
910 {
911 msg(M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
912 goto cleanup;
913 }
914
915 msg(
917 (
918 "\n"
919 "The following objects are available for use.\n"
920 "Each object shown below may be used as parameter to\n"
921 "--pkcs11-id option please remember to use single quote mark.\n"
922 )
923 );
924 for (current = user_certificates; current != NULL; current = current->next)
925 {
926 pkcs11h_certificate_t certificate = NULL;
927 char *dn = NULL;
928 char serial[1024] = {0};
929 char *ser = NULL;
930 size_t ser_len = 0;
931
932 if (
933 (rv = pkcs11h_certificate_serializeCertificateId(
934 NULL,
935 &ser_len,
936 current->certificate_id
937 )) != CKR_OK
938 )
939 {
940 msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
941 goto cleanup1;
942 }
943
944 if (
945 rv == CKR_OK
946 && (ser = (char *)malloc(ser_len)) == NULL
947 )
948 {
949 msg(M_FATAL, "PKCS#11: Cannot allocate memory");
950 goto cleanup1;
951 }
952
953 if (
954 (rv = pkcs11h_certificate_serializeCertificateId(
955 ser,
956 &ser_len,
957 current->certificate_id
958 )) != CKR_OK
959 )
960 {
961 msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
962 goto cleanup1;
963 }
964
965 if (
966 (rv = pkcs11h_certificate_create(
967 current->certificate_id,
968 NULL,
969 PKCS11H_PROMPT_MASK_ALLOW_ALL,
970 PKCS11H_PIN_CACHE_INFINITE,
971 &certificate
972 ))
973 )
974 {
975 msg(M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
976 goto cleanup1;
977 }
978
979 if (
980 (dn = pkcs11_certificate_dn(
981 certificate,
982 &gc
983 )) == NULL
984 )
985 {
986 goto cleanup1;
987 }
988
989 if (
990 (pkcs11_certificate_serial(
991 certificate,
992 serial,
993 sizeof(serial)
994 ))
995 )
996 {
997 goto cleanup1;
998 }
999
1000 msg(
1002 (
1003 "\n"
1004 "Certificate\n"
1005 " DN: %s\n"
1006 " Serial: %s\n"
1007 " Serialized id: %s\n"
1008 ),
1009 dn,
1010 serial,
1011 ser
1012 );
1013
1014cleanup1:
1015
1016 if (certificate != NULL)
1017 {
1018 pkcs11h_certificate_freeCertificate(certificate);
1019 certificate = NULL;
1020 }
1021
1022 free(ser);
1023 ser = NULL;
1024 }
1025
1026cleanup:
1027 pkcs11h_certificate_freeCertificateIdList(user_certificates);
1028 user_certificates = NULL;
1029
1030 pkcs11h_terminate();
1031 gc_free(&gc);
1032}
1033#endif /* ENABLE_PKCS11 */
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
#define BSTR(buf)
Definition buffer.h:129
#define BLEN(buf)
Definition buffer.h:127
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:1033
static struct gc_arena gc_new(void)
Definition buffer.h:1025
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:122
#define D_PKCS11_DEBUG
Definition errlevel.h:174
#define D_SHOW_PKCS11
Definition errlevel.h:141
#define M_INFO
Definition errlevel.h:55
void purge_user_pass(struct user_pass *up, const bool force)
Definition misc.c:485
#define GET_USER_PASS_MANAGEMENT
Definition misc.h:109
#define GET_USER_PASS_PASSWORD_ONLY
Definition misc.h:111
#define GET_USER_PASS_NEED_OK
Definition misc.h:112
#define GET_USER_PASS_NOFATAL
Definition misc.h:113
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:114
#define CLEAR(x)
Definition basic.h:33
int get_debug_level(void)
Definition error.c:137
#define M_NOPREFIX
Definition error.h:97
#define M_FATAL
Definition error.h:89
#define M_NOLF
Definition error.h:101
#define dmsg(flags,...)
Definition error.h:148
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
static time_t openvpn_time(time_t *t)
Definition otime.h:90
PKCS #11 SSL library-specific backend.
bool platform_absolute_pathname(const char *pathname)
Return true if pathname is absolute.
Definition platform.c:641
int openvpn_base64_encode(const void *data, int size, char **str)
Definition base64.c:52
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
Structure that wraps the TLS context.
static int cleanup(void **state)
static bool pkcs11_id_management
struct gc_arena gc
Definition test_ssl.c:155