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