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
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
27 #if defined(ENABLE_PKCS11)
29 #include <pkcs11-helper-1.0/pkcs11h-certificate.h>
30 #include <pkcs11-helper-1.0/pkcs11h-openssl.h>
40 return openvpn_time (NULL
);
46 __mygettimeofday (struct timeval
*tv
) {
47 return gettimeofday (tv
, NULL
);
53 __mysleep (const unsigned long usec
) {
62 static pkcs11h_engine_system_t s_pkcs11h_sys_engine
= {
76 _pkcs11_msg_pkcs112openvpn (
79 unsigned openvpn_flags
;
82 case PKCS11H_LOG_DEBUG2
:
83 openvpn_flags
= D_PKCS11_DEBUG
;
85 case PKCS11H_LOG_DEBUG1
:
86 openvpn_flags
= D_SHOW_PKCS11
;
88 case PKCS11H_LOG_INFO
:
89 openvpn_flags
= M_INFO
;
91 case PKCS11H_LOG_WARN
:
92 openvpn_flags
= M_WARN
;
94 case PKCS11H_LOG_ERROR
:
95 openvpn_flags
= M_FATAL
;
98 openvpn_flags
= M_FATAL
;
102 #if defined(ENABLE_PKCS11_FORCE_DEBUG)
103 openvpn_flags
=M_INFO
;
106 return openvpn_flags
;
111 _pkcs11_msg_openvpn2pkcs11 (
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
;
132 pkcs11_flags
= PKCS11H_LOG_ERROR
;
135 #if defined(ENABLE_PKCS11_FORCE_DEBUG)
136 pkcs11_flags
= PKCS11H_LOG_DEBUG2
;
144 _pkcs11_openvpn_log (
145 void * const global_data
,
147 const char * const szFormat
,
150 char Buffer
[10*1024];
154 vsnprintf (Buffer
, sizeof (Buffer
), szFormat
, args
);
155 Buffer
[sizeof (Buffer
)-1] = 0;
157 msg (_pkcs11_msg_pkcs112openvpn (flags
), "%s", Buffer
);
162 _pkcs11_openvpn_token_prompt (
163 void * const global_data
,
164 void * const user_data
,
165 const pkcs11h_token_id_t token
,
168 struct user_pass token_resp
;
174 ASSERT (token
!=NULL
);
177 token_resp
.defined
= false;
178 token_resp
.nocache
= true;
181 sizeof (token_resp
.username
),
182 "Please insert %s token",
190 "token-insertion-request",
191 GET_USER_PASS_MANAGEMENT
|GET_USER_PASS_NEED_OK
|GET_USER_PASS_NOFATAL
197 return strcmp (token_resp
.password
, "ok") == 0;
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
,
211 struct user_pass token_pass
;
218 ASSERT (token
!=NULL
);
220 openvpn_snprintf (prompt
, sizeof (prompt
), "%s token", token
->label
);
222 token_pass
.defined
= false;
223 token_pass
.nocache
= true;
230 GET_USER_PASS_MANAGEMENT
|GET_USER_PASS_PASSWORD_ONLY
|GET_USER_PASS_NOFATAL
236 strncpynt (pin
, token_pass
.password
, pin_max
);
237 purge_user_pass (&token_pass
, true);
239 if (strlen (pin
) == 0) {
250 const bool protected_auth
,
251 const int nPINCachePeriod
253 CK_RV rv
= CKR_FUNCTION_FAILED
;
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
));
265 if ((rv
= pkcs11h_initialize ()) != CKR_OK
) {
266 msg (M_FATAL
, "PKCS#11: Cannot initialize %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
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
));
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
));
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
));
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
));
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
));
297 if ((rv
= pkcs11h_setPINCachePeriod (nPINCachePeriod
)) != CKR_OK
) {
298 msg (M_FATAL
, "PKCS#11: Cannot set Pcache period %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
307 "PKCS#11: pkcs11_initialize - return %ld-'%s'",
309 pkcs11h_getMessage (rv
)
316 pkcs11_terminate () {
319 "PKCS#11: pkcs11_terminate - entered"
322 pkcs11h_terminate ();
326 "PKCS#11: pkcs11_terminate - return"
331 pkcs11_forkFixup () {
332 pkcs11h_forkFixup ();
337 const char * const provider
,
338 const bool protected_auth
,
339 const unsigned private_mode
,
340 const bool cert_private
344 ASSERT (provider
!=NULL
);
348 "PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x",
355 "PKCS#11: Adding PKCS#11 provider '%s'",
360 (rv
= pkcs11h_addProvider (
365 PKCS11H_SLOTEVENT_METHOD_AUTO
,
370 msg (M_WARN
, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider
, rv
, pkcs11h_getMessage (rv
));
375 "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'",
377 pkcs11h_getMessage (rv
)
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
;
397 "PKCS#11: pkcs11_management_id_count - entered"
401 (rv
= pkcs11h_certificate_enumCertificateIds (
402 PKCS11H_ENUM_METHOD_CACHE_EXIST
,
404 PKCS11H_PROMPT_MASK_ALLOW_ALL
,
409 msg (M_WARN
, "PKCS#11: Cannot get certificate list %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
413 for (count
= 0, t
= id_list
; t
!= NULL
; t
= t
->next
) {
419 if (id_list
!= NULL
) {
420 pkcs11h_certificate_freeCertificateIdList (id_list
);
426 "PKCS#11: pkcs11_management_id_count - return count=%d",
434 pkcs11_management_id_get (
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
;
444 pkcs11h_certificate_t certificate
= NULL
;
446 unsigned char *certificate_blob
= NULL
;
447 size_t certificate_blob_size
= 0;
449 char *internal_id
= NULL
;
450 char *internal_base64
= NULL
;
452 bool success
= false;
455 ASSERT (base64
!=NULL
);
459 "PKCS#11: pkcs11_management_id_get - entered index=%d",
467 (rv
= pkcs11h_certificate_enumCertificateIds (
468 PKCS11H_ENUM_METHOD_CACHE_EXIST
,
470 PKCS11H_PROMPT_MASK_ALLOW_ALL
,
475 msg (M_WARN
, "PKCS#11: Cannot get certificate list %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
481 while (entry
!= NULL
&& count
!= index
) {
489 "PKCS#11: pkcs11_management_id_get - no certificate at index=%d",
496 (rv
= pkcs11h_certificate_serializeCertificateId (
499 entry
->certificate_id
502 msg (M_WARN
, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
506 if ((internal_id
= (char *)malloc (max
)) == NULL
) {
507 msg (M_FATAL
, "PKCS#11: Cannot allocate memory");
512 (rv
= pkcs11h_certificate_serializeCertificateId (
515 entry
->certificate_id
518 msg (M_WARN
, "PKCS#11: Cannot serialize certificate id %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
523 (rv
= pkcs11h_certificate_create (
524 entry
->certificate_id
,
526 PKCS11H_PROMPT_MASK_ALLOW_ALL
,
527 PKCS11H_PIN_CACHE_INFINITE
,
531 msg (M_WARN
, "PKCS#11: Cannot get certificate %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
536 (rv
= pkcs11h_certificate_getCertificateBlob (
539 &certificate_blob_size
542 msg (M_WARN
, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
546 if ((certificate_blob
= (unsigned char *)malloc (certificate_blob_size
)) == NULL
) {
547 msg (M_FATAL
, "PKCS#11: Cannot allocate memory");
552 (rv
= pkcs11h_certificate_getCertificateBlob (
555 &certificate_blob_size
558 msg (M_WARN
, "PKCS#11: Cannot get certificate blob %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
562 if (base64_encode (certificate_blob
, certificate_blob_size
, &internal_base64
) == -1) {
563 msg (M_WARN
, "PKCS#11: Cannot encode certificate");
569 *base64
= internal_base64
;
570 internal_base64
= NULL
;
575 if (id_list
!= NULL
) {
576 pkcs11h_certificate_freeCertificateIdList (id_list
);
580 if (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
;
597 "PKCS#11: pkcs11_management_id_get - return success=%d, id='%s'",
607 SSL_CTX
* const ssl_ctx
,
608 bool pkcs11_id_management
,
609 const char * const pkcs11_id
613 pkcs11h_certificate_id_t certificate_id
= NULL
;
614 pkcs11h_certificate_t certificate
= NULL
;
615 pkcs11h_openssl_session_t openssl_session
= NULL
;
620 ASSERT (ssl_ctx
!=NULL
);
621 ASSERT (pkcs11_id_management
|| pkcs11_id
!=NULL
);
625 "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id_management=%d, pkcs11_id='%s'",
627 pkcs11_id_management
? 1 : 0,
631 if (pkcs11_id_management
) {
632 struct user_pass id_resp
;
636 id_resp
.defined
= false;
637 id_resp
.nocache
= true;
640 sizeof (id_resp
.username
),
641 "Please specify PKCS#11 id to use"
649 GET_USER_PASS_MANAGEMENT
|GET_USER_PASS_NEED_STR
|GET_USER_PASS_NOFATAL
656 (rv
= pkcs11h_certificate_deserializeCertificateId (
661 msg (M_WARN
, "PKCS#11: Cannot deserialize id %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
667 (rv
= pkcs11h_certificate_deserializeCertificateId (
672 msg (M_WARN
, "PKCS#11: Cannot deserialize id %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
678 (rv
= pkcs11h_certificate_create (
681 PKCS11H_PROMPT_MASK_ALLOW_ALL
,
682 PKCS11H_PIN_CACHE_INFINITE
,
686 msg (M_WARN
, "PKCS#11: Cannot get certificate %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
690 if ((openssl_session
= pkcs11h_openssl_createSession (certificate
)) == NULL
) {
691 msg (M_WARN
, "PKCS#11: Cannot initialize openssl session");
696 * Will be released by openssl_session
700 if ((rsa
= pkcs11h_openssl_session_getRSA (openssl_session
)) == NULL
) {
701 msg (M_WARN
, "PKCS#11: Unable get rsa object");
705 if ((x509
= pkcs11h_openssl_session_getX509 (openssl_session
)) == NULL
) {
706 msg (M_WARN
, "PKCS#11: Unable get certificate object");
710 if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx
, rsa
)) {
711 msg (M_WARN
, "PKCS#11: Cannot set private key for openssl");
715 if (!SSL_CTX_use_certificate (ssl_ctx
, x509
)) {
716 msg (M_WARN
, "PKCS#11: Cannot set certificate for openssl");
724 * openssl objects have reference
725 * count, so release them
738 if (certificate
!= NULL
) {
739 pkcs11h_certificate_freeCertificate (certificate
);
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
;
755 "PKCS#11: SSL_CTX_use_pkcs11 - return ok=%d, rv=%ld",
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
,
773 struct gc_arena gc
= gc_new ();
774 struct buffer pass_prompt
= alloc_buf_gc (128, &gc
);
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");
790 if (!strcmp (pin
, "cancel")) {
800 const char * const provider
,
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
));
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
));
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
));
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
));
830 (rv
= pkcs11h_addProvider (
837 cert_private
? TRUE
: FALSE
840 msg (M_FATAL
, "PKCS#11: Cannot add provider '%s' %ld-'%s'", provider
, rv
, pkcs11h_getMessage (rv
));
845 (rv
= pkcs11h_certificate_enumCertificateIds (
846 PKCS11H_ENUM_METHOD_CACHE_EXIST
,
848 PKCS11H_PROMPT_MASK_ALLOW_ALL
,
853 msg (M_FATAL
, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
858 M_INFO
|M_NOPREFIX
|M_NOLF
,
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
;
871 char serial
[1024] = {0};
877 (rv
= pkcs11h_certificate_serializeCertificateId (
880 current
->certificate_id
883 msg (M_FATAL
, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
889 (ser
= (char *)malloc (ser_len
)) == NULL
891 msg (M_FATAL
, "PKCS#11: Cannot allocate memory");
896 (rv
= pkcs11h_certificate_serializeCertificateId (
899 current
->certificate_id
902 msg (M_FATAL
, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
907 (rv
= pkcs11h_certificate_create (
908 current
->certificate_id
,
910 PKCS11H_PROMPT_MASK_ALLOW_ALL
,
911 PKCS11H_PIN_CACHE_INFINITE
,
915 msg (M_FATAL
, "PKCS#11: Cannot create certificate %ld-'%s'", rv
, pkcs11h_getMessage (rv
));
919 if ((x509
= pkcs11h_openssl_getX509 (certificate
)) == NULL
) {
920 msg (M_FATAL
, "PKCS#11: Cannot get X509");
925 X509_get_subject_name (x509
),
930 if ((bio
= BIO_new (BIO_s_mem ())) == NULL
) {
931 msg (M_FATAL
, "PKCS#11: Cannot create BIO");
935 i2a_ASN1_INTEGER(bio
, X509_get_serialNumber (x509
));
936 n
= BIO_read (bio
, serial
, sizeof (serial
)-1);
945 M_INFO
|M_NOPREFIX
|M_NOLF
,
951 " Serialized id: %s\n"
964 if (certificate
!= NULL
) {
965 pkcs11h_certificate_freeCertificate (certificate
);
976 if (user_certificates
!= NULL
) {
977 pkcs11h_certificate_freeCertificateIdList (user_certificates
);
978 user_certificates
= NULL
;
981 pkcs11h_terminate ();
985 static void dummy (void) {}
986 #endif /* ENABLE_PKCS11 */