fixes, fully translated tomato, with english dictionary and Polish translation
[tomato.git] / release / src / router / openvpn / pkcs11.c
blobe06a2ed7dbc321ba2b89d040af43d074496e5578
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.
8 * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
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.
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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "syshead.h"
27 #if defined(ENABLE_PKCS11)
29 #include <pkcs11-helper-1.0/pkcs11h-certificate.h>
30 #include <pkcs11-helper-1.0/pkcs11h-openssl.h>
31 #include "basic.h"
32 #include "error.h"
33 #include "manage.h"
34 #include "base64.h"
35 #include "pkcs11.h"
37 static
38 time_t
39 __mytime (void) {
40 return openvpn_time (NULL);
43 #if !defined(_WIN32)
44 static
45 int
46 __mygettimeofday (struct timeval *tv) {
47 return gettimeofday (tv, NULL);
49 #endif
51 static
52 void
53 __mysleep (const unsigned long usec) {
54 #if defined(_WIN32)
55 Sleep (usec/1000);
56 #else
57 usleep (usec);
58 #endif
62 static pkcs11h_engine_system_t s_pkcs11h_sys_engine = {
63 malloc,
64 free,
65 __mytime,
66 __mysleep,
67 #if defined(_WIN32)
68 NULL
69 #else
70 __mygettimeofday
71 #endif
74 static
75 unsigned
76 _pkcs11_msg_pkcs112openvpn (
77 const unsigned flags
78 ) {
79 unsigned openvpn_flags;
81 switch (flags) {
82 case PKCS11H_LOG_DEBUG2:
83 openvpn_flags = D_PKCS11_DEBUG;
84 break;
85 case PKCS11H_LOG_DEBUG1:
86 openvpn_flags = D_SHOW_PKCS11;
87 break;
88 case PKCS11H_LOG_INFO:
89 openvpn_flags = M_INFO;
90 break;
91 case PKCS11H_LOG_WARN:
92 openvpn_flags = M_WARN;
93 break;
94 case PKCS11H_LOG_ERROR:
95 openvpn_flags = M_FATAL;
96 break;
97 default:
98 openvpn_flags = M_FATAL;
99 break;
102 #if defined(ENABLE_PKCS11_FORCE_DEBUG)
103 openvpn_flags=M_INFO;
104 #endif
106 return openvpn_flags;
109 static
110 unsigned
111 _pkcs11_msg_openvpn2pkcs11 (
112 const unsigned flags
114 unsigned pkcs11_flags;
116 if ((flags & D_PKCS11_DEBUG) != 0) {
117 pkcs11_flags = PKCS11H_LOG_DEBUG2;
119 else if ((flags & D_SHOW_PKCS11) != 0) {
120 pkcs11_flags = PKCS11H_LOG_DEBUG1;
122 else if ((flags & M_INFO) != 0) {
123 pkcs11_flags = PKCS11H_LOG_INFO;
125 else if ((flags & M_WARN) != 0) {
126 pkcs11_flags = PKCS11H_LOG_WARN;
128 else if ((flags & M_FATAL) != 0) {
129 pkcs11_flags = PKCS11H_LOG_ERROR;
131 else {
132 pkcs11_flags = PKCS11H_LOG_ERROR;
135 #if defined(ENABLE_PKCS11_FORCE_DEBUG)
136 pkcs11_flags = PKCS11H_LOG_DEBUG2;
137 #endif
139 return pkcs11_flags;
142 static
143 void
144 _pkcs11_openvpn_log (
145 void * const global_data,
146 unsigned flags,
147 const char * const szFormat,
148 va_list args
150 char Buffer[10*1024];
152 (void)global_data;
154 vsnprintf (Buffer, sizeof (Buffer), szFormat, args);
155 Buffer[sizeof (Buffer)-1] = 0;
157 msg (_pkcs11_msg_pkcs112openvpn (flags), "%s", Buffer);
160 static
161 PKCS11H_BOOL
162 _pkcs11_openvpn_token_prompt (
163 void * const global_data,
164 void * const user_data,
165 const pkcs11h_token_id_t token,
166 const unsigned retry
168 struct user_pass token_resp;
170 (void)global_data;
171 (void)user_data;
172 (void)retry;
174 ASSERT (token!=NULL);
176 CLEAR (token_resp);
177 token_resp.defined = false;
178 token_resp.nocache = true;
179 openvpn_snprintf (
180 token_resp.username,
181 sizeof (token_resp.username),
182 "Please insert %s token",
183 token->label
186 if (
187 !get_user_pass (
188 &token_resp,
189 NULL,
190 "token-insertion-request",
191 GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK|GET_USER_PASS_NOFATAL
194 return false;
196 else {
197 return strcmp (token_resp.password, "ok") == 0;
201 static
202 PKCS11H_BOOL
203 _pkcs11_openvpn_pin_prompt (
204 void * const global_data,
205 void * const user_data,
206 const pkcs11h_token_id_t token,
207 const unsigned retry,
208 char * const pin,
209 const size_t pin_max
211 struct user_pass token_pass;
212 char prompt[1024];
214 (void)global_data;
215 (void)user_data;
216 (void)retry;
218 ASSERT (token!=NULL);
220 openvpn_snprintf (prompt, sizeof (prompt), "%s token", token->label);
222 token_pass.defined = false;
223 token_pass.nocache = true;
225 if (
226 !get_user_pass (
227 &token_pass,
228 NULL,
229 prompt,
230 GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL
233 return false;
235 else {
236 strncpynt (pin, token_pass.password, pin_max);
237 purge_user_pass (&token_pass, true);
239 if (strlen (pin) == 0) {
240 return false;
242 else {
243 return true;
248 bool
249 pkcs11_initialize (
250 const bool protected_auth,
251 const int nPINCachePeriod
253 CK_RV rv = CKR_FUNCTION_FAILED;
255 dmsg (
256 D_PKCS11_DEBUG,
257 "PKCS#11: pkcs11_initialize - entered"
260 if ((rv = pkcs11h_engine_setSystem (&s_pkcs11h_sys_engine)) != CKR_OK) {
261 msg (M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv, pkcs11h_getMessage (rv));
262 goto cleanup;
265 if ((rv = pkcs11h_initialize ()) != CKR_OK) {
266 msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
267 goto cleanup;
270 if ((rv = pkcs11h_setLogHook (_pkcs11_openvpn_log, NULL)) != CKR_OK) {
271 msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
272 goto cleanup;
275 pkcs11h_setLogLevel (_pkcs11_msg_openvpn2pkcs11 (get_debug_level ()));
277 if ((rv = pkcs11h_setForkMode (TRUE)) != CKR_OK) {
278 msg (M_FATAL, "PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage (rv));
279 goto cleanup;
282 if ((rv = pkcs11h_setTokenPromptHook (_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK) {
283 msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
284 goto cleanup;
287 if ((rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK) {
288 msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
289 goto cleanup;
292 if ((rv = pkcs11h_setProtectedAuthentication (protected_auth)) != CKR_OK) {
293 msg (M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage (rv));
294 goto cleanup;
297 if ((rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK) {
298 msg (M_FATAL, "PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
299 goto cleanup;
302 rv = CKR_OK;
304 cleanup:
305 dmsg (
306 D_PKCS11_DEBUG,
307 "PKCS#11: pkcs11_initialize - return %ld-'%s'",
309 pkcs11h_getMessage (rv)
312 return rv == CKR_OK;
315 void
316 pkcs11_terminate () {
317 dmsg (
318 D_PKCS11_DEBUG,
319 "PKCS#11: pkcs11_terminate - entered"
322 pkcs11h_terminate ();
324 dmsg (
325 D_PKCS11_DEBUG,
326 "PKCS#11: pkcs11_terminate - return"
330 void
331 pkcs11_forkFixup () {
332 pkcs11h_forkFixup ();
335 bool
336 pkcs11_addProvider (
337 const char * const provider,
338 const bool protected_auth,
339 const unsigned private_mode,
340 const bool cert_private
342 CK_RV rv = CKR_OK;
344 ASSERT (provider!=NULL);
346 dmsg (
347 D_PKCS11_DEBUG,
348 "PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x",
349 provider,
350 private_mode
353 msg (
354 M_INFO,
355 "PKCS#11: Adding PKCS#11 provider '%s'",
356 provider
359 if (
360 (rv = pkcs11h_addProvider (
361 provider,
362 provider,
363 protected_auth,
364 private_mode,
365 PKCS11H_SLOTEVENT_METHOD_AUTO,
367 cert_private
368 )) != CKR_OK
370 msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
373 dmsg (
374 D_PKCS11_DEBUG,
375 "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'",
377 pkcs11h_getMessage (rv)
380 return rv == CKR_OK;
384 pkcs11_logout() {
385 return pkcs11h_logout () == CKR_OK;
389 pkcs11_management_id_count () {
390 pkcs11h_certificate_id_list_t id_list = NULL;
391 pkcs11h_certificate_id_list_t t = NULL;
392 CK_RV rv = CKR_OK;
393 int count = 0;
395 dmsg (
396 D_PKCS11_DEBUG,
397 "PKCS#11: pkcs11_management_id_count - entered"
400 if (
401 (rv = pkcs11h_certificate_enumCertificateIds (
402 PKCS11H_ENUM_METHOD_CACHE_EXIST,
403 NULL,
404 PKCS11H_PROMPT_MASK_ALLOW_ALL,
405 NULL,
406 &id_list
407 )) != CKR_OK
409 msg (M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage (rv));
410 goto cleanup;
413 for (count = 0, t = id_list; t != NULL; t = t->next) {
414 count++;
417 cleanup:
419 if (id_list != NULL) {
420 pkcs11h_certificate_freeCertificateIdList (id_list);
421 id_list = NULL;
424 dmsg (
425 D_PKCS11_DEBUG,
426 "PKCS#11: pkcs11_management_id_count - return count=%d",
427 count
430 return count;
433 bool
434 pkcs11_management_id_get (
435 const int index,
436 char ** id,
437 char **base64
439 pkcs11h_certificate_id_list_t id_list = NULL;
440 pkcs11h_certificate_id_list_t entry = NULL;
441 #if 0 /* certificate_id seems to be unused -- JY */
442 pkcs11h_certificate_id_t certificate_id = NULL;
443 #endif
444 pkcs11h_certificate_t certificate = NULL;
445 CK_RV rv = CKR_OK;
446 unsigned char *certificate_blob = NULL;
447 size_t certificate_blob_size = 0;
448 size_t max;
449 char *internal_id = NULL;
450 char *internal_base64 = NULL;
451 int count = 0;
452 bool success = false;
454 ASSERT (id!=NULL);
455 ASSERT (base64!=NULL);
457 dmsg (
458 D_PKCS11_DEBUG,
459 "PKCS#11: pkcs11_management_id_get - entered index=%d",
460 index
463 *id = NULL;
464 *base64 = NULL;
466 if (
467 (rv = pkcs11h_certificate_enumCertificateIds (
468 PKCS11H_ENUM_METHOD_CACHE_EXIST,
469 NULL,
470 PKCS11H_PROMPT_MASK_ALLOW_ALL,
471 NULL,
472 &id_list
473 )) != CKR_OK
475 msg (M_WARN, "PKCS#11: Cannot get certificate list %ld-'%s'", rv, pkcs11h_getMessage (rv));
476 goto cleanup;
479 entry = id_list;
480 count = 0;
481 while (entry != NULL && count != index) {
482 count++;
483 entry = entry->next;
486 if (entry == NULL) {
487 dmsg (
488 D_PKCS11_DEBUG,
489 "PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
490 index
492 goto cleanup;
495 if (
496 (rv = pkcs11h_certificate_serializeCertificateId (
497 NULL,
498 &max,
499 entry->certificate_id
500 )) != CKR_OK
502 msg (M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage (rv));
503 goto cleanup;
506 if ((internal_id = (char *)malloc (max)) == NULL) {
507 msg (M_FATAL, "PKCS#11: Cannot allocate memory");
508 goto cleanup;
511 if (
512 (rv = pkcs11h_certificate_serializeCertificateId (
513 internal_id,
514 &max,
515 entry->certificate_id
516 )) != CKR_OK
518 msg (M_WARN, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv, pkcs11h_getMessage (rv));
519 goto cleanup;
522 if (
523 (rv = pkcs11h_certificate_create (
524 entry->certificate_id,
525 NULL,
526 PKCS11H_PROMPT_MASK_ALLOW_ALL,
527 PKCS11H_PIN_CACHE_INFINITE,
528 &certificate
529 )) != CKR_OK
531 msg (M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
532 goto cleanup;
535 if (
536 (rv = pkcs11h_certificate_getCertificateBlob (
537 certificate,
538 NULL,
539 &certificate_blob_size
540 )) != CKR_OK
542 msg (M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv));
543 goto cleanup;
546 if ((certificate_blob = (unsigned char *)malloc (certificate_blob_size)) == NULL) {
547 msg (M_FATAL, "PKCS#11: Cannot allocate memory");
548 goto cleanup;
551 if (
552 (rv = pkcs11h_certificate_getCertificateBlob (
553 certificate,
554 certificate_blob,
555 &certificate_blob_size
556 )) != CKR_OK
558 msg (M_WARN, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv, pkcs11h_getMessage (rv));
559 goto cleanup;
562 if (base64_encode (certificate_blob, certificate_blob_size, &internal_base64) == -1) {
563 msg (M_WARN, "PKCS#11: Cannot encode certificate");
564 goto cleanup;
567 *id = internal_id;
568 internal_id = NULL;
569 *base64 = internal_base64;
570 internal_base64 = NULL;
571 success = true;
573 cleanup:
575 if (id_list != NULL) {
576 pkcs11h_certificate_freeCertificateIdList (id_list);
577 id_list = NULL;
580 if (internal_id != NULL) {
581 free (internal_id);
582 internal_id = NULL;
585 if (internal_base64 != NULL) {
586 free (internal_base64);
587 internal_base64 = NULL;
590 if (certificate_blob != NULL) {
591 free (certificate_blob);
592 certificate_blob = NULL;
595 dmsg (
596 D_PKCS11_DEBUG,
597 "PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
598 success ? 1 : 0,
602 return success;
606 SSL_CTX_use_pkcs11 (
607 SSL_CTX * const ssl_ctx,
608 bool pkcs11_id_management,
609 const char * const pkcs11_id
611 X509 *x509 = NULL;
612 RSA *rsa = NULL;
613 pkcs11h_certificate_id_t certificate_id = NULL;
614 pkcs11h_certificate_t certificate = NULL;
615 pkcs11h_openssl_session_t openssl_session = NULL;
616 CK_RV rv = CKR_OK;
618 bool ok = false;
620 ASSERT (ssl_ctx!=NULL);
621 ASSERT (pkcs11_id_management || pkcs11_id!=NULL);
623 dmsg (
624 D_PKCS11_DEBUG,
625 "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
626 (void *)ssl_ctx,
627 pkcs11_id_management ? 1 : 0,
628 pkcs11_id
631 if (pkcs11_id_management) {
632 struct user_pass id_resp;
634 CLEAR (id_resp);
636 id_resp.defined = false;
637 id_resp.nocache = true;
638 openvpn_snprintf (
639 id_resp.username,
640 sizeof (id_resp.username),
641 "Please specify PKCS#11 id to use"
644 if (
645 !get_user_pass (
646 &id_resp,
647 NULL,
648 "pkcs11-id-request",
649 GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_STR|GET_USER_PASS_NOFATAL
652 goto cleanup;
655 if (
656 (rv = pkcs11h_certificate_deserializeCertificateId (
657 &certificate_id,
658 id_resp.password
659 )) != CKR_OK
661 msg (M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv));
662 goto cleanup;
665 else {
666 if (
667 (rv = pkcs11h_certificate_deserializeCertificateId (
668 &certificate_id,
669 pkcs11_id
670 )) != CKR_OK
672 msg (M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv));
673 goto cleanup;
677 if (
678 (rv = pkcs11h_certificate_create (
679 certificate_id,
680 NULL,
681 PKCS11H_PROMPT_MASK_ALLOW_ALL,
682 PKCS11H_PIN_CACHE_INFINITE,
683 &certificate
684 )) != CKR_OK
686 msg (M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
687 goto cleanup;
690 if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL ) {
691 msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
692 goto cleanup;
696 * Will be released by openssl_session
698 certificate = NULL;
700 if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL) {
701 msg (M_WARN, "PKCS#11: Unable get rsa object");
702 goto cleanup;
705 if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) {
706 msg (M_WARN, "PKCS#11: Unable get certificate object");
707 goto cleanup;
710 if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)) {
711 msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
712 goto cleanup;
715 if (!SSL_CTX_use_certificate (ssl_ctx, x509)) {
716 msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
717 goto cleanup;
720 ok = true;
722 cleanup:
724 * openssl objects have reference
725 * count, so release them
728 if (x509 != NULL) {
729 X509_free (x509);
730 x509 = NULL;
733 if (rsa != NULL) {
734 RSA_free (rsa);
735 rsa = NULL;
738 if (certificate != NULL) {
739 pkcs11h_certificate_freeCertificate (certificate);
740 certificate = NULL;
743 if (certificate_id != NULL) {
744 pkcs11h_certificate_freeCertificateId (certificate_id);
745 certificate_id = NULL;
748 if (openssl_session != NULL) {
749 pkcs11h_openssl_freeSession (openssl_session);
750 openssl_session = NULL;
753 dmsg (
754 D_PKCS11_DEBUG,
755 "PKCS#11: SSL_CTX_use_pkcs11 - return ok=%d, rv=%ld",
756 ok ? 1 : 0,
760 return ok ? 1 : 0;
763 static
764 bool
765 _pkcs11_openvpn_show_pkcs11_ids_pin_prompt (
766 void * const global_data,
767 void * const user_data,
768 const pkcs11h_token_id_t token,
769 const unsigned retry,
770 char * const pin,
771 const size_t pin_max
773 struct gc_arena gc = gc_new ();
774 struct buffer pass_prompt = alloc_buf_gc (128, &gc);
776 (void)global_data;
777 (void)user_data;
778 (void)retry;
780 ASSERT (token!=NULL);
782 buf_printf (&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display);
784 if (!get_console_input (BSTR (&pass_prompt), false, pin, pin_max)) {
785 msg (M_FATAL, "Cannot read password from stdin");
788 gc_free (&gc);
790 if (!strcmp (pin, "cancel")) {
791 return FALSE;
793 else {
794 return TRUE;
798 void
799 show_pkcs11_ids (
800 const char * const provider,
801 bool cert_private
803 pkcs11h_certificate_id_list_t user_certificates = NULL;
804 pkcs11h_certificate_id_list_t current = NULL;
805 CK_RV rv = CKR_FUNCTION_FAILED;
807 if ((rv = pkcs11h_initialize ()) != CKR_OK) {
808 msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
809 goto cleanup;
812 if ((rv = pkcs11h_setLogHook (_pkcs11_openvpn_log, NULL)) != CKR_OK) {
813 msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
814 goto cleanup;
817 pkcs11h_setLogLevel (_pkcs11_msg_openvpn2pkcs11 (get_debug_level ()));
819 if ((rv = pkcs11h_setProtectedAuthentication (TRUE)) != CKR_OK) {
820 msg (M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv, pkcs11h_getMessage (rv));
821 goto cleanup;
824 if ((rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK) {
825 msg (M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage (rv));
826 goto cleanup;
829 if (
830 (rv = pkcs11h_addProvider (
831 provider,
832 provider,
833 TRUE,
835 FALSE,
837 cert_private ? TRUE : FALSE
838 )) != CKR_OK
840 msg (M_FATAL, "PKCS#11: Cannot add provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
841 goto cleanup;
844 if (
845 (rv = pkcs11h_certificate_enumCertificateIds (
846 PKCS11H_ENUM_METHOD_CACHE_EXIST,
847 NULL,
848 PKCS11H_PROMPT_MASK_ALLOW_ALL,
849 NULL,
850 &user_certificates
851 )) != CKR_OK
853 msg (M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage (rv));
854 goto cleanup;
857 msg (
858 M_INFO|M_NOPREFIX|M_NOLF,
860 "\n"
861 "The following objects are available for use.\n"
862 "Each object shown below may be used as parameter to\n"
863 "--pkcs11-id option please remember to use single quote mark.\n"
866 for (current = user_certificates;current != NULL; current = current->next) {
867 pkcs11h_certificate_t certificate = NULL;
868 X509 *x509 = NULL;
869 BIO *bio = NULL;
870 char dn[1024] = {0};
871 char serial[1024] = {0};
872 char *ser = NULL;
873 size_t ser_len = 0;
874 int n;
876 if (
877 (rv = pkcs11h_certificate_serializeCertificateId (
878 NULL,
879 &ser_len,
880 current->certificate_id
881 )) != CKR_OK
883 msg (M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
884 goto cleanup1;
887 if (
888 rv == CKR_OK &&
889 (ser = (char *)malloc (ser_len)) == NULL
891 msg (M_FATAL, "PKCS#11: Cannot allocate memory");
892 goto cleanup1;
895 if (
896 (rv = pkcs11h_certificate_serializeCertificateId (
897 ser,
898 &ser_len,
899 current->certificate_id
900 )) != CKR_OK
902 msg (M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
903 goto cleanup1;
906 if (
907 (rv = pkcs11h_certificate_create (
908 current->certificate_id,
909 NULL,
910 PKCS11H_PROMPT_MASK_ALLOW_ALL,
911 PKCS11H_PIN_CACHE_INFINITE,
912 &certificate
915 msg (M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
916 goto cleanup1;
919 if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL) {
920 msg (M_FATAL, "PKCS#11: Cannot get X509");
921 goto cleanup1;
924 X509_NAME_oneline (
925 X509_get_subject_name (x509),
927 sizeof (dn)
930 if ((bio = BIO_new (BIO_s_mem ())) == NULL) {
931 msg (M_FATAL, "PKCS#11: Cannot create BIO");
932 goto cleanup1;
935 i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509));
936 n = BIO_read (bio, serial, sizeof (serial)-1);
937 if (n<0) {
938 serial[0] = '\x0';
940 else {
941 serial[n] = 0;
944 msg (
945 M_INFO|M_NOPREFIX|M_NOLF,
947 "\n"
948 "Certificate\n"
949 " DN: %s\n"
950 " Serial: %s\n"
951 " Serialized id: %s\n"
954 serial,
958 cleanup1:
959 if (x509 != NULL) {
960 X509_free (x509);
961 x509 = NULL;
964 if (certificate != NULL) {
965 pkcs11h_certificate_freeCertificate (certificate);
966 certificate = NULL;
969 if (ser != NULL) {
970 free (ser);
971 ser = NULL;
975 cleanup:
976 if (user_certificates != NULL) {
977 pkcs11h_certificate_freeCertificateIdList (user_certificates);
978 user_certificates = NULL;
981 pkcs11h_terminate ();
984 #else
985 static void dummy (void) {}
986 #endif /* ENABLE_PKCS11 */