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