I've recently worked on a better version of pkcs11-helper. I've also merged

it into QCA (Qt Cryptographic Architecture), so that KDE 4 will finally be
able to use smartcards.

The changes allows the following features:

1. Thread safe, is activated if USE_PTHREAD.

2. Slot event - Will allow us in the future to disconnect VPN when smartcard
is removed. In order to support this OpenVPN must support threading... At
least SIGUSR1 from a different thread. Threading should be supported in both
Windows and Linux. -- currently disabled.

When I talk about threading support it is just support in configuration script
and that the method that SIGUSR1 self can be called from a different thread.
I already handle the monitor threads.

3. Certificate enumeration - Will allow us to finally have one configuration
file for all users! When you add the plugin GUI stuff you talked about, we will
be able to display a list of available certificates for the user to select.
-- currently disabled.

4. Data object manipulation - Will allow us to store tls-auth on the smartcard
as well. -- currently disabled.

5. Many other minor improvements.

Alon Bar-Lev


git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@990 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
james 2006-04-05 07:17:02 +00:00
parent be9150b693
commit 18597b93f7
10 changed files with 10189 additions and 3120 deletions

5
init.c
View File

@ -140,9 +140,10 @@ context_init_1 (struct context *c)
#if defined(ENABLE_PKCS11) #if defined(ENABLE_PKCS11)
if (c->first_time) { if (c->first_time) {
int i; int i;
pkcs11_initialize (c->options.pkcs11_pin_cache_period); pkcs11_initialize (true, c->options.pkcs11_pin_cache_period);
for (i=0;i<MAX_PARMS && c->options.pkcs11_providers[i] != NULL;i++) for (i=0;i<MAX_PARMS && c->options.pkcs11_providers[i] != NULL;i++)
pkcs11_addProvider (c->options.pkcs11_providers[i], c->options.pkcs11_sign_mode[i]); pkcs11_addProvider (c->options.pkcs11_providers[i], c->options.pkcs11_protected_authentication[i],
c->options.pkcs11_sign_mode[i], c->options.pkcs11_cert_private[i]);
} }
#endif #endif

115
openvpn.8
View File

@ -205,15 +205,15 @@ openvpn \- secure IP tunnel daemon.
[\ \fB\-\-ping\-restart\fR\ \fIn\fR\ ] [\ \fB\-\-ping\-restart\fR\ \fIn\fR\ ]
[\ \fB\-\-ping\-timer\-rem\fR\ ] [\ \fB\-\-ping\-timer\-rem\fR\ ]
[\ \fB\-\-ping\fR\ \fIn\fR\ ] [\ \fB\-\-ping\fR\ \fIn\fR\ ]
[\ \fB\-\-pkcs11\-cert\-private\fR\ \fI[0|1]...\fR\ ]
[\ \fB\-\-pkcs11\-id\fR\ \fIname\fR\ ]
[\ \fB\-\-pkcs11\-id\-type\fR\ \fItype\fR\ ]
[\ \fB\-\-pkcs11\-pin\-cache\fR\ \fIseconds\fR\ ]
[\ \fB\-\-pkcs11\-protected\-authentication\fR\ \fI[0|1]...\fR\ ]
[\ \fB\-\-pkcs11\-providers\fR\ \fIprovider...\fR\ ] [\ \fB\-\-pkcs11\-providers\fR\ \fIprovider...\fR\ ]
[\ \fB\-\-pkcs11\-sign\-mode\fR\ \fImode...\fR\ ] [\ \fB\-\-pkcs11\-sign\-mode\fR\ \fImode...\fR\ ]
[\ \fB\-\-pkcs11\-slot\-type\fR\ \fItype\fR\ ]
[\ \fB\-\-pkcs11\-slot\fR\ \fIname\fR\ ] [\ \fB\-\-pkcs11\-slot\fR\ \fIname\fR\ ]
[\ \fB\-\-pkcs11\-id\-type\fR\ \fItype\fR\ ] [\ \fB\-\-pkcs11\-slot\-type\fR\ \fItype\fR\ ]
[\ \fB\-\-pkcs11\-id\fR\ \fIname\fR\ ]
[\ \fB\-\-pkcs11\-pin\-cache\fR\ \fIseconds\fR\ ]
[\ \fB\-\-pkcs11\-protected\-authentication\fR\ ]
[\ \fB\-\-pkcs11\-cert\-private\fR\ ]
[\ \fB\-\-pkcs12\fR\ \fIfile\fR\ ] [\ \fB\-\-pkcs12\fR\ \fIfile\fR\ ]
[\ \fB\-\-plugin\fR\ \fImodule\-pathname\ init\-string\fR\ ] [\ \fB\-\-plugin\fR\ \fImodule\-pathname\ init\-string\fR\ ]
[\ \fB\-\-port\fR\ \fIport\fR\ ] [\ \fB\-\-port\fR\ \fIport\fR\ ]
@ -257,8 +257,8 @@ openvpn \- secure IP tunnel daemon.
[\ \fB\-\-show\-ciphers\fR\ ] [\ \fB\-\-show\-ciphers\fR\ ]
[\ \fB\-\-show\-digests\fR\ ] [\ \fB\-\-show\-digests\fR\ ]
[\ \fB\-\-show\-engines\fR\ ] [\ \fB\-\-show\-engines\fR\ ]
[\ \fB\-\-show\-pkcs11\-slots\fR\ \fIprovider\fR\ ]
[\ \fB\-\-show\-pkcs11\-objects\fR\ \fIprovider\ slot\fR\ ] [\ \fB\-\-show\-pkcs11\-objects\fR\ \fIprovider\ slot\fR\ ]
[\ \fB\-\-show\-pkcs11\-slots\fR\ \fIprovider\fR\ ]
[\ \fB\-\-show\-net\-up\fR\ ] [\ \fB\-\-show\-net\-up\fR\ ]
[\ \fB\-\-show\-net\fR\ ] [\ \fB\-\-show\-net\fR\ ]
[\ \fB\-\-show\-tls\fR\ ] [\ \fB\-\-show\-tls\fR\ ]
@ -3620,48 +3620,13 @@ and
.B --key. .B --key.
.\"********************************************************* .\"*********************************************************
.TP .TP
.B --pkcs11-providers provider... .B --pkcs11-cert-private [0|1]...
Specify a RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki) providers Set if access to certificate object should be performed after login.
to load. Every provider has its own setting.
This option can be used instead of
.B --cert, --key,
and
.B --pkcs12.
.\"********************************************************* .\"*********************************************************
.TP .TP
.B --pkcs11-sign-mode mode... .B --pkcs11-id name
Specify which method to use in order to sign data. A different mode can be specified Specify a name of the object to search for.
for each provider. Mode can be one of the following:
.B 'auto'
(default) -- Try to determind automatically.
.br
.B 'recover'
-- Use SignRecover.
.br
.B 'sign'
-- Use Sign.
.br
.\"*********************************************************
.TP
.B --pkcs11-slot-type type
Specify how to locate the correct slot. Type can be one of the following:
.B 'id'
-- Locate the slot by a numeric id. The format is [provider:]id, for example, slot 2 of provider 1
is encoded as 1:2. If you have only one provider you can omit the provider number.
The provider number is set by the order specified in the --pkcs11-providers option.
.br
.B 'name'
-- Locate the slot by its name.
.br
.B 'label'
-- Locate the slot by the label of the token that reside within.
.br
.\"*********************************************************
.TP
.B --pkcs11-slot name
Specify a name of the slot to search for.
.\"********************************************************* .\"*********************************************************
.TP .TP
.B --pkcs11-id-type type .B --pkcs11-id-type type
@ -3678,21 +3643,63 @@ Specify how to locate the correct objects. Type can be one of the following:
.br .br
.\"********************************************************* .\"*********************************************************
.TP .TP
.B --pkcs11-id name
Specify a name of the object to search for.
.\"*********************************************************
.TP
.B --pkcs11-pin-cache seconds .B --pkcs11-pin-cache seconds
Specify how many seconds the PIN can be cached, the default is until the token is removed. Specify how many seconds the PIN can be cached, the default is until the token is removed.
.\"********************************************************* .\"*********************************************************
.TP .TP
.B --pkcs11-protected-authentication .B --pkcs11-protected-authentication [0|1]...
Use PKCS#11 protected authentication path, useful for biometric and external Use PKCS#11 protected authentication path, useful for biometric and external
keypad devices. keypad devices.
Every provider has its own setting.
.\"********************************************************* .\"*********************************************************
.TP .TP
.B --pkcs11-cert-private .B --pkcs11-providers provider...
Set if access to certificate object should be performed after login. Specify a RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki) providers
to load.
This option can be used instead of
.B --cert, --key,
and
.B --pkcs12.
.\"*********************************************************
.TP
.B --pkcs11-sign-mode mode...
Specify which method to use in order to sign data. A different mode can be specified
for each provider. Mode can be one of the following:
.B 'auto'
(default) -- Try to determind automatically.
.br
.B 'sign'
-- Use Sign.
.br
.B 'recover'
-- Use SignRecover.
.br
.B 'any'
-- Use Sign and if not supported use SignRecover.
.br
.\"*********************************************************
.TP
.B --pkcs11-slot name
Specify a name of the slot to search for.
.\"*********************************************************
.TP
.B --pkcs11-slot-type type
Specify how to locate the correct slot. Type can be one of the following:
.B 'id'
-- Locate the slot by a numeric id. The format is [provider:]id, for example, slot 2 of provider a.so
should be encoded as a.so:2. If you have only one provider you can omit the provider name.
The provider name is set by the name specified in the
.B --pkcs11-providers
option.
.br
.B 'name'
-- Locate the slot by its name.
.br
.B 'label'
-- Locate the slot by the label of the token that reside within.
.br
.\"********************************************************* .\"*********************************************************
.TP .TP
.B --cryptoapicert select-string .B --cryptoapicert select-string

View File

@ -492,12 +492,19 @@ static const char usage_message[] =
"\n" "\n"
"PKCS#11 Options:\n" "PKCS#11 Options:\n"
"--pkcs11-providers provider ... : PKCS#11 provider to load.\n" "--pkcs11-providers provider ... : PKCS#11 provider to load.\n"
"--pkcs11-protected-authentication [0|1] ... : Use PKCS#11 protected authentication\n"
" path. Set for each provider.\n"
"--pkcs11-sign-mode mode ... : PKCS#11 signature method.\n" "--pkcs11-sign-mode mode ... : PKCS#11 signature method.\n"
" auto : Try to determind automatically (default).\n" " auto : Try to determind automatically (default).\n"
" recover : Use SignRecover.\n"
" sign : Use Sign.\n" " sign : Use Sign.\n"
" recover : Use SignRecover.\n"
" any : Use Sign and then SignRecover.\n"
"--pkcs11-cert-private [0|1] ... : Set if login should be performed before\n"
" certificate can be accessed. Set for each provider.\n"
"--pkcs11-pin-cache seconds : Number of seconds to cache PIN. The default is -1\n"
" cache until token is removed.\n"
"--pkcs11-slot-type method : Slot locate method:\n" "--pkcs11-slot-type method : Slot locate method:\n"
" id : By slot id (numeric [prov#:]slot#).\n" " id : By slot id (numeric [prov:]slot#).\n"
" name : By slot name.\n" " name : By slot name.\n"
" label : By the card label that resides in slot.\n" " label : By the card label that resides in slot.\n"
"--pkcs11-slot name : The slot name.\n" "--pkcs11-slot name : The slot name.\n"
@ -506,11 +513,6 @@ static const char usage_message[] =
" label : By the object label (string).\n" " label : By the object label (string).\n"
" subject : By certificate subject (String).\n" " subject : By certificate subject (String).\n"
"--pkcs11-id name : The object name.\n" "--pkcs11-id name : The object name.\n"
"--pkcs11-pin-cache seconds : Number of seconds to cache PIN. The default is -1\n"
" cache until token removed.\n"
"--pkcs11-protected-authentication : Use PKCS#11 protected authentication path.\n"
"--pkcs11-cert-private : Set if login should be performed before\n"
" certificate can be accessed.\n"
#endif /* ENABLE_PKCS11 */ #endif /* ENABLE_PKCS11 */
"\n" "\n"
"SSL Library information:\n" "SSL Library information:\n"
@ -688,8 +690,6 @@ init_options (struct options *o)
#endif #endif
#ifdef ENABLE_PKCS11 #ifdef ENABLE_PKCS11
o->pkcs11_pin_cache_period = -1; o->pkcs11_pin_cache_period = -1;
o->pkcs11_protected_authentication = false;
o->pkcs11_cert_private = false;
#endif /* ENABLE_PKCS11 */ #endif /* ENABLE_PKCS11 */
} }
@ -1263,18 +1263,26 @@ show_settings (const struct options *o)
for (i=0;i<MAX_PARMS && o->pkcs11_providers[i] != NULL;i++) for (i=0;i<MAX_PARMS && o->pkcs11_providers[i] != NULL;i++)
SHOW_PARM (pkcs11_providers, o->pkcs11_providers[i], "%s"); SHOW_PARM (pkcs11_providers, o->pkcs11_providers[i], "%s");
} }
{
int i;
for (i=0;i<MAX_PARMS;i++)
SHOW_PARM (pkcs11_protected_authentication, o->pkcs11_protected_authentication[i] ? "ENABLED" : "DISABLED", "%s");
}
{ {
int i; int i;
for (i=0;i<MAX_PARMS && o->pkcs11_sign_mode[i] != NULL;i++) for (i=0;i<MAX_PARMS && o->pkcs11_sign_mode[i] != NULL;i++)
SHOW_PARM (pkcs11_sign_mode, o->pkcs11_sign_mode[i], "%s"); SHOW_PARM (pkcs11_sign_mode, o->pkcs11_sign_mode[i], "%s");
} }
{
int i;
for (i=0;i<MAX_PARMS;i++)
SHOW_PARM (pkcs11_cert_private, o->pkcs11_cert_private[i] ? "ENABLED" : "DISABLED", "%s");
}
SHOW_INT (pkcs11_pin_cache_period);
SHOW_STR (pkcs11_slot_type); SHOW_STR (pkcs11_slot_type);
SHOW_STR (pkcs11_slot); SHOW_STR (pkcs11_slot);
SHOW_STR (pkcs11_id_type); SHOW_STR (pkcs11_id_type);
SHOW_STR (pkcs11_id); SHOW_STR (pkcs11_id);
SHOW_INT (pkcs11_pin_cache_period);
SHOW_BOOL (pkcs11_protected_authentication);
SHOW_BOOL (pkcs11_cert_private);
#endif /* ENABLE_PKCS11 */ #endif /* ENABLE_PKCS11 */
#if P2MP #if P2MP
@ -5080,6 +5088,15 @@ add_option (struct options *options,
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j) for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
options->pkcs11_providers[j-1] = p[j]; options->pkcs11_providers[j-1] = p[j];
} }
else if (streq (p[0], "pkcs11-protected-authentication"))
{
int j;
VERIFY_PERMISSION (OPT_P_GENERAL);
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
options->pkcs11_protected_authentication[j-1] = atoi (p[j]) != 0 ? 1 : 0;
}
else if (streq (p[0], "pkcs11-sign-mode") && p[1]) else if (streq (p[0], "pkcs11-sign-mode") && p[1])
{ {
int j; int j;
@ -5089,6 +5106,20 @@ add_option (struct options *options,
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j) for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
options->pkcs11_sign_mode[j-1] = p[j]; options->pkcs11_sign_mode[j-1] = p[j];
} }
else if (streq (p[0], "pkcs11-cert-private"))
{
int j;
VERIFY_PERMISSION (OPT_P_GENERAL);
for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
options->pkcs11_cert_private[j-1] = atoi (p[j]) != 0 ? 1 : 0;
}
else if (streq (p[0], "pkcs11-pin-cache") && p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs11_pin_cache_period = atoi (p[1]);
}
else if (streq (p[0], "pkcs11-slot-type") && p[1]) else if (streq (p[0], "pkcs11-slot-type") && p[1])
{ {
VERIFY_PERMISSION (OPT_P_GENERAL); VERIFY_PERMISSION (OPT_P_GENERAL);
@ -5109,21 +5140,6 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_GENERAL); VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs11_id = p[1]; options->pkcs11_id = p[1];
} }
else if (streq (p[0], "pkcs11-pin-cache") && p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs11_pin_cache_period = atoi (p[1]);
}
else if (streq (p[0], "pkcs11-protected-authentication"))
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs11_protected_authentication = true;
}
else if (streq (p[0], "pkcs11-cert-private"))
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->pkcs11_cert_private = true;
}
#endif #endif
#ifdef TUNSETPERSIST #ifdef TUNSETPERSIST
else if (streq (p[0], "rmtun")) else if (streq (p[0], "rmtun"))

View File

@ -409,13 +409,13 @@ struct options
#ifdef ENABLE_PKCS11 #ifdef ENABLE_PKCS11
const char *pkcs11_providers[MAX_PARMS]; const char *pkcs11_providers[MAX_PARMS];
const char *pkcs11_sign_mode[MAX_PARMS]; const char *pkcs11_sign_mode[MAX_PARMS];
bool pkcs11_protected_authentication[MAX_PARMS];
bool pkcs11_cert_private[MAX_PARMS];
int pkcs11_pin_cache_period;
const char *pkcs11_slot_type; const char *pkcs11_slot_type;
const char *pkcs11_slot; const char *pkcs11_slot;
const char *pkcs11_id_type; const char *pkcs11_id_type;
const char *pkcs11_id; const char *pkcs11_id;
int pkcs11_pin_cache_period;
bool pkcs11_protected_authentication;
bool pkcs11_cert_private;
#endif #endif
#ifdef WIN32 #ifdef WIN32

View File

@ -22,8 +22,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef __PKCS11_HELPER_CONFIG_H #ifndef __PKCS11H_HELPER_CONFIG_H
#define __PKCS11_HELPER_CONFIG_H #define __PKCS11H_HELPER_CONFIG_H
#if !defined(PKCS11H_NO_NEED_INCLUDE_CONFIG) #if !defined(PKCS11H_NO_NEED_INCLUDE_CONFIG)
@ -38,32 +38,25 @@
#endif /* PKCS11H_NO_NEED_INCLUDE_CONFIG */ #endif /* PKCS11H_NO_NEED_INCLUDE_CONFIG */
#ifdef ENABLE_PKCS11 #ifdef ENABLE_PKCS11
#define PKCS11H_ENABLE_HELPER #define ENABLE_PKCS11H_HELPER
#endif #endif
#ifdef PKCS11H_ENABLE_HELPER #ifdef ENABLE_PKCS11H_HELPER
#include "error.h" #include "error.h"
#include "misc.h" #include "misc.h"
#include "ssl.h" #include "ssl.h"
#define PKCS11ASSERT ASSERT #undef PKCS11H_USE_CYGWIN /* cygwin is not supported in openvpn */
#define PKCS11LOG msg
#define PKCS11DLOG dmsg
#define PKCS11_LOG_DEBUG2 D_PKCS11_DEBUG
#define PKCS11_LOG_DEBUG1 D_SHOW_PKCS11
#define PKCS11_LOG_INFO M_INFO
#define PKCS11_LOG_WARN M_WARN
#define PKCS11_LOG_ERROR M_FATAL
#undef PKCS11_USE_CYGWIN #if !defined(FALSE)
#define FALSE false
#endif
#if !defined(TRUE)
#define TRUE true
#endif
#if !defined(false) typedef bool PKCS11H_BOOL;
#define false 0
#endif
#if !defined(true)
#define true (!false)
#endif
#if !defined(IN) #if !defined(IN)
#define IN #define IN
@ -72,18 +65,34 @@
#define OUT #define OUT
#endif #endif
#define PKCS11_PRM_SLOT_TYPE "--pkcs11-slot-type" #ifdef ENABLE_DEBUG
#define PKCS11_PRM_SLOT_ID "--pkcs11-slot" #define ENABLE_PKCS11H_DEBUG
#define PKCS11_PRM_OBJ_TYPE "--pkcs11-id-type" #endif
#define PKCS11_PRM_OBJ_ID "--pkcs11-id" #ifdef USE_PTHREAD
#define ENABLE_PKCS11H_THREADING
#endif
#undef ENABLE_PKCS11H_TOKEN
#undef ENABLE_PKCS11H_DATA
#define ENABLE_PKCS11H_CERTIFICATE
#define ENABLE_PKCS11H_LOCATE
#undef ENABLE_PKCS11H_ENUM
#undef ENABLE_PKCS11H_SLOTEVENT
#define ENABLE_PKCS11H_OPENSSL
#define ENABLE_PKCS11H_STANDALONE
#define PKCS11_TIME openvpn_time #define PKCS11H_PRM_SLOT_TYPE "--pkcs11-slot-type"
#define PKCS11H_PRM_SLOT_ID "--pkcs11-slot"
#define PKCS11H_PRM_OBJ_TYPE "--pkcs11-id-type"
#define PKCS11H_PRM_OBJ_ID "--pkcs11-id"
#if defined(WIN32) || defined(PKCS11_USE_CYGWIN) #define PKCS11H_ASSERT ASSERT
#define PKCS11H_TIME openvpn_time
#if defined(WIN32) || defined(PKCS11H_USE_CYGWIN)
#include "cryptoki-win32.h" #include "cryptoki-win32.h"
#else #else
#include "cryptoki.h" #include "cryptoki.h"
#endif #endif
#endif /* PKCS11H_ENABLE_HELPER */ #endif /* PKCS11_ENABLE_HELPER */
#endif /* __PKCS11_HELPER_CONFIG_H */ #endif /* __PKCS11H_HELPER_CONFIG_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

329
pkcs11.c
View File

@ -43,6 +43,74 @@
#include "pkcs11-helper.h" #include "pkcs11-helper.h"
#include "pkcs11.h" #include "pkcs11.h"
static
unsigned
_pkcs11_msg_pkcs112openvpn (
IN const unsigned flags
) {
unsigned openvpn_flags;
switch (flags) {
case PKCS11H_LOG_DEBUG2:
openvpn_flags = D_PKCS11_DEBUG;
break;
case PKCS11H_LOG_DEBUG1:
openvpn_flags = D_SHOW_PKCS11;
break;
case PKCS11H_LOG_INFO:
openvpn_flags = M_INFO;
break;
case PKCS11H_LOG_WARN:
openvpn_flags = M_WARN;
break;
case PKCS11H_LOG_ERROR:
openvpn_flags = M_FATAL;
break;
default:
openvpn_flags = M_FATAL;
break;
}
#if defined(ENABLE_PKCS11_FORCE_DEBUG)
openvpn_flags=M_INFO;
#endif
return openvpn_flags;
}
static
unsigned
_pkcs11_msg_openvpn2pkcs11 (
IN const unsigned flags
) {
unsigned pkcs11_flags;
if ((flags & D_PKCS11_DEBUG) != 0) {
pkcs11_flags = PKCS11H_LOG_DEBUG2;
}
else if ((flags & D_SHOW_PKCS11) != 0) {
pkcs11_flags = PKCS11H_LOG_DEBUG1;
}
else if ((flags & M_INFO) != 0) {
pkcs11_flags = PKCS11H_LOG_INFO;
}
else if ((flags & M_WARN) != 0) {
pkcs11_flags = PKCS11H_LOG_WARN;
}
else if ((flags & M_FATAL) != 0) {
pkcs11_flags = PKCS11H_LOG_ERROR;
}
else {
pkcs11_flags = PKCS11H_LOG_ERROR;
}
#if defined(ENABLE_PKCS11_FORCE_DEBUG)
pkcs11_flags = PKCS11H_LOG_DEBUG2;
#endif
return pkcs11_flags;
}
static static
void void
_pkcs11_openvpn_print ( _pkcs11_openvpn_print (
@ -62,20 +130,46 @@ _pkcs11_openvpn_print (
} }
static static
bool void
_pkcs11_openvpn_card_prompt ( _pkcs11_openvpn_log (
IN const void *pData, IN const void *pData,
IN const char * const szLabel IN unsigned flags,
IN const char * const szFormat,
IN va_list args
) {
char Buffer[10*1024];
vsnprintf (Buffer, sizeof (Buffer), szFormat, args);
Buffer[sizeof (Buffer)-1] = 0;
msg (_pkcs11_msg_pkcs112openvpn (flags), "%s", Buffer);
}
static
bool
_pkcs11_openvpn_token_prompt (
IN const void *pData,
IN const pkcs11h_token_id_t token
) { ) {
static struct user_pass token_resp; static struct user_pass token_resp;
ASSERT (szLabel!=NULL); ASSERT (token!=NULL);
CLEAR (token_resp); CLEAR (token_resp);
token_resp.defined = false; token_resp.defined = false;
token_resp.nocache = true; token_resp.nocache = true;
openvpn_snprintf (token_resp.username, sizeof (token_resp.username), "Please insert %s token", szLabel); openvpn_snprintf (
get_user_pass (&token_resp, NULL, "token-insertion-request", GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK); token_resp.username,
sizeof (token_resp.username),
"Please insert %s token",
token->label
);
get_user_pass (
&token_resp,
NULL,
"token-insertion-request",
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK
);
return strcmp (token_resp.password, "ok") == 0; return strcmp (token_resp.password, "ok") == 0;
} }
@ -84,16 +178,16 @@ static
bool bool
_pkcs11_openvpn_pin_prompt ( _pkcs11_openvpn_pin_prompt (
IN const void *pData, IN const void *pData,
IN const char * const szLabel, IN const pkcs11h_token_id_t token,
OUT char * const szPIN, OUT char * const szPIN,
IN const size_t nMaxPIN IN const size_t nMaxPIN
) { ) {
static struct user_pass token_pass; static struct user_pass token_pass;
char szPrompt[1024]; char szPrompt[1024];
ASSERT (szLabel!=NULL); ASSERT (token!=NULL);
openvpn_snprintf (szPrompt, sizeof (szPrompt), "%s token", szLabel); openvpn_snprintf (szPrompt, sizeof (szPrompt), "%s token", token->label);
token_pass.defined = false; token_pass.defined = false;
token_pass.nocache = true; token_pass.nocache = true;
@ -111,12 +205,13 @@ _pkcs11_openvpn_pin_prompt (
bool bool
pkcs11_initialize ( pkcs11_initialize (
const int nPINCachePeriod IN const bool fProtectedAuthentication,
IN const int nPINCachePeriod
) { ) {
CK_RV rv = CKR_OK; CK_RV rv = CKR_OK;
PKCS11LOG ( dmsg (
PKCS11_LOG_DEBUG2, D_PKCS11_DEBUG,
"PKCS#11: pkcs11_initialize - entered" "PKCS#11: pkcs11_initialize - entered"
); );
@ -124,32 +219,50 @@ pkcs11_initialize (
rv == CKR_OK && rv == CKR_OK &&
(rv = pkcs11h_initialize ()) != CKR_OK (rv = pkcs11h_initialize ()) != CKR_OK
) { ) {
PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv)); msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
} }
if ( if (
rv == CKR_OK && rv == CKR_OK &&
(rv = pkcs11h_setCardPromptHook (_pkcs11_openvpn_card_prompt, NULL)) != CKR_OK (rv = pkcs11h_setLogHook (_pkcs11_openvpn_log, NULL)) != CKR_OK
) { ) {
PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv)); msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
}
if (rv == CKR_OK) {
pkcs11h_setLogLevel (_pkcs11_msg_openvpn2pkcs11 (get_debug_level ()));
}
if (
rv == CKR_OK &&
(rv = pkcs11h_setTokenPromptHook (_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK
) {
msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
} }
if ( if (
rv == CKR_OK && rv == CKR_OK &&
(rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK (rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK
) { ) {
PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv)); msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
}
if (
rv == CKR_OK &&
(rv = pkcs11h_setProtectedAuthentication (fProtectedAuthentication)) != CKR_OK
) {
msg (M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage (rv));
} }
if ( if (
rv == CKR_OK && rv == CKR_OK &&
(rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK (rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK
) { ) {
PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv)); msg (M_FATAL, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
} }
PKCS11LOG ( dmsg (
PKCS11_LOG_DEBUG2, D_PKCS11_DEBUG,
"PKCS#11: pkcs11_initialize - return %ld-'%s'", "PKCS#11: pkcs11_initialize - return %ld-'%s'",
rv, rv,
pkcs11h_getMessage (rv) pkcs11h_getMessage (rv)
@ -160,15 +273,15 @@ pkcs11_initialize (
void void
pkcs11_terminate () { pkcs11_terminate () {
PKCS11LOG ( dmsg (
PKCS11_LOG_DEBUG2, D_PKCS11_DEBUG,
"PKCS#11: pkcs11_terminate - entered" "PKCS#11: pkcs11_terminate - entered"
); );
pkcs11h_terminate (); pkcs11h_terminate ();
PKCS11LOG ( dmsg (
PKCS11_LOG_DEBUG2, D_PKCS11_DEBUG,
"PKCS#11: pkcs11_terminate - return" "PKCS#11: pkcs11_terminate - return"
); );
} }
@ -181,32 +294,69 @@ pkcs11_forkFixup () {
bool bool
pkcs11_addProvider ( pkcs11_addProvider (
IN const char * const provider, IN const char * const provider,
IN const char * const sign_mode IN const bool fProtectedAuthentication,
IN const char * const sign_mode,
IN const bool fCertIsPrivate
) { ) {
unsigned maskSignMode = 0;
CK_RV rv = CKR_OK; CK_RV rv = CKR_OK;
PKCS11LOG ( ASSERT (provider!=NULL);
PKCS11_LOG_DEBUG2, /*ASSERT (sign_mode!=NULL); NULL is default */
dmsg (
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_addProvider - entered - provider='%s', sign_mode='%s'", "PKCS#11: pkcs11_addProvider - entered - provider='%s', sign_mode='%s'",
provider, provider,
sign_mode == NULL ? "default" : sign_mode sign_mode == NULL ? "default" : sign_mode
); );
PKCS11LOG ( msg (
PKCS11_LOG_INFO, M_INFO,
"PKCS#11: Adding PKCS#11 provider '%s'", "PKCS#11: Adding PKCS#11 provider '%s'",
provider provider
); );
if ( if (rv == CKR_OK) {
rv == CKR_OK && if (sign_mode == NULL || !strcmp (sign_mode, "auto")) {
(rv = pkcs11h_addProvider (provider, sign_mode)) != CKR_OK maskSignMode = 0;
) { }
PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv)); else if (!strcmp (sign_mode, "sign")) {
maskSignMode = PKCS11H_SIGNMODE_MASK_SIGN;
}
else if (!strcmp (sign_mode, "recover")) {
maskSignMode = PKCS11H_SIGNMODE_MASK_RECOVER;
}
else if (!strcmp (sign_mode, "any")) {
maskSignMode = (
PKCS11H_SIGNMODE_MASK_SIGN |
PKCS11H_SIGNMODE_MASK_RECOVER
);
}
else {
msg (M_FATAL, "PKCS#11: Invalid sign mode '%s'", sign_mode);
rv = CKR_ARGUMENTS_BAD;
}
} }
PKCS11LOG ( if (
PKCS11_LOG_DEBUG2, rv == CKR_OK &&
(rv = pkcs11h_addProvider (
provider,
provider,
fProtectedAuthentication,
maskSignMode,
PKCS11H_SLOTEVENT_METHOD_AUTO,
0,
fCertIsPrivate
)) != CKR_OK
) {
msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
}
dmsg (
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'", "PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'",
rv, rv,
pkcs11h_getMessage (rv) pkcs11h_getMessage (rv)
@ -221,73 +371,94 @@ SSL_CTX_use_pkcs11 (
IN const char * const pkcs11_slot_type, IN const char * const pkcs11_slot_type,
IN const char * const pkcs11_slot, IN const char * const pkcs11_slot,
IN const char * const pkcs11_id_type, IN const char * const pkcs11_id_type,
IN const char * const pkcs11_id, IN const char * const pkcs11_id
IN const bool pkcs11_protected_authentication,
IN const bool pkcs11_cert_private
) { ) {
X509 *x509 = NULL; X509 *x509 = NULL;
RSA *rsa = NULL; RSA *rsa = NULL;
pkcs11h_openssl_session_t pkcs11h_openssl_session = NULL; pkcs11h_certificate_id_t certificate_id = NULL;
pkcs11h_certificate_t certificate = NULL;
pkcs11h_openssl_session_t openssl_session = NULL;
CK_RV rv = CKR_OK; CK_RV rv = CKR_OK;
bool fOK = true; bool fOK = true;
PKCS11LOG ( ASSERT (ssl_ctx!=NULL);
PKCS11_LOG_DEBUG2, ASSERT (pkcs11_slot_type!=NULL);
"PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_slot_type='%s', pkcs11_slot='%s', pkcs11_id_type='%s', pkcs11_id='%s', pkcs11_protected_authentication=%d", ASSERT (pkcs11_slot!=NULL);
ASSERT (pkcs11_id_type!=NULL);
ASSERT (pkcs11_id!=NULL);
dmsg (
D_PKCS11_DEBUG,
"PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_slot_type='%s', pkcs11_slot='%s', pkcs11_id_type='%s', pkcs11_id='%s'",
(void *)ssl_ctx, (void *)ssl_ctx,
pkcs11_slot_type, pkcs11_slot_type,
pkcs11_slot, pkcs11_slot,
pkcs11_id_type, pkcs11_id_type,
pkcs11_id, pkcs11_id
pkcs11_protected_authentication ? 1 : 0
); );
PKCS11ASSERT (ssl_ctx!=NULL); ASSERT (ssl_ctx!=NULL);
PKCS11ASSERT (pkcs11_slot_type!=NULL); ASSERT (pkcs11_slot_type!=NULL);
PKCS11ASSERT (pkcs11_slot!=NULL); ASSERT (pkcs11_slot!=NULL);
PKCS11ASSERT (pkcs11_id_type!=NULL); ASSERT (pkcs11_id_type!=NULL);
PKCS11ASSERT (pkcs11_id!=NULL); ASSERT (pkcs11_id!=NULL);
if ( if (
fOK && fOK &&
(pkcs11h_openssl_session = pkcs11h_openssl_createSession ()) == NULL (rv = pkcs11h_locate_certificate (
) {
fOK = false;
PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize openssh session");
}
if (
fOK &&
(rv = pkcs11h_createCertificateSession (
pkcs11_slot_type, pkcs11_slot_type,
pkcs11_slot, pkcs11_slot,
pkcs11_id_type, pkcs11_id_type,
pkcs11_id, pkcs11_id,
pkcs11_protected_authentication, &certificate_id
pkcs11_cert_private,
PKCS11H_PIN_CACHE_INFINITE,
&pkcs11h_openssl_session->certificate
)) != CKR_OK )) != CKR_OK
) { ) {
fOK = false; fOK = false;
PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv)); msg (M_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv));
} }
if ( if (
fOK && fOK &&
(rsa = pkcs11h_openssl_getRSA (pkcs11h_openssl_session)) == NULL (rv = pkcs11h_certificate_create (
certificate_id,
PKCS11H_PIN_CACHE_INFINITE,
&certificate
)) != CKR_OK
) { ) {
fOK = false; fOK = false;
PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get rsa object"); msg (M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
} }
if ( if (
fOK && fOK &&
(x509 = pkcs11h_openssl_getX509 (pkcs11h_openssl_session)) == NULL (openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL
) { ) {
fOK = false; fOK = false;
PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get certificate object"); msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
}
if (fOK) {
/*
* Will be released by openssl_session
*/
certificate = NULL;
}
if (
fOK &&
(rsa = pkcs11h_openssl_getRSA (openssl_session)) == NULL
) {
fOK = false;
msg (M_WARN, "PKCS#11: Unable get rsa object");
}
if (
fOK &&
(x509 = pkcs11h_openssl_getX509 (openssl_session)) == NULL
) {
fOK = false;
msg (M_WARN, "PKCS#11: Unable get certificate object");
} }
if ( if (
@ -295,7 +466,7 @@ SSL_CTX_use_pkcs11 (
!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa) !SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)
) { ) {
fOK = false; fOK = false;
PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set private key for openssl"); msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
} }
if ( if (
@ -303,7 +474,7 @@ SSL_CTX_use_pkcs11 (
!SSL_CTX_use_certificate (ssl_ctx, x509) !SSL_CTX_use_certificate (ssl_ctx, x509)
) { ) {
fOK = false; fOK = false;
PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set certificate for openssl"); msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
} }
/* /*
@ -321,13 +492,23 @@ SSL_CTX_use_pkcs11 (
rsa = NULL; rsa = NULL;
} }
if (pkcs11h_openssl_session != NULL) { if (certificate != NULL) {
pkcs11h_openssl_freeSession (pkcs11h_openssl_session); pkcs11h_freeCertificate (certificate);
pkcs11h_openssl_session = NULL; certificate = NULL;
} }
PKCS11LOG ( if (certificate_id != NULL) {
PKCS11_LOG_DEBUG2, pkcs11h_freeCertificateId (certificate_id);
certificate_id = NULL;
}
if (openssl_session != NULL) {
pkcs11h_openssl_freeSession (openssl_session);
openssl_session = NULL;
}
dmsg (
D_PKCS11_DEBUG,
"PKCS#11: SSL_CTX_use_pkcs11 - return fOK=%d, rv=%ld", "PKCS#11: SSL_CTX_use_pkcs11 - return fOK=%d, rv=%ld",
fOK ? 1 : 0, fOK ? 1 : 0,
rv rv

View File

@ -31,6 +31,7 @@
bool bool
pkcs11_initialize ( pkcs11_initialize (
const bool fProtectedAuthentication,
const int nPINCachePeriod const int nPINCachePeriod
); );
@ -43,7 +44,9 @@ pkcs11_forkFixup ();
bool bool
pkcs11_addProvider ( pkcs11_addProvider (
const char * const provider, const char * const provider,
const char * const sign_mode const bool fProtectedAuthentication,
const char * const sign_mode,
const bool fCertIsPrivate
); );
int int
@ -52,9 +55,7 @@ SSL_CTX_use_pkcs11 (
const char * const pkcs11_slot_type, const char * const pkcs11_slot_type,
const char * const pkcs11_slot, const char * const pkcs11_slot,
const char * const pkcs11_id_type, const char * const pkcs11_id_type,
const char * const pkcs11_id, const char * const pkcs11_id
const bool pkcs11_protected_authentication,
const bool pkcs11_cert_private
); );
void void
@ -71,4 +72,4 @@ show_pkcs11_objects (
#endif /* ENABLE_PKCS11 */ #endif /* ENABLE_PKCS11 */
#endif /* OPENVPN_PKCS11_H */ #endif /* OPENVPN_PKCS11H_H */

2
ssl.c
View File

@ -1145,7 +1145,7 @@ init_ssl (const struct options *options)
if (options->pkcs11_providers[0]) if (options->pkcs11_providers[0])
{ {
/* Load Certificate and Private Key */ /* Load Certificate and Private Key */
if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_slot_type, options->pkcs11_slot, options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_protected_authentication, options->pkcs11_cert_private)) if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_slot_type, options->pkcs11_slot, options->pkcs11_id_type, options->pkcs11_id))
msg (M_SSLERR, "Cannot load certificate \"%s:%s\" from slot \"%s:%s\" using PKCS#11 interface", msg (M_SSLERR, "Cannot load certificate \"%s:%s\" from slot \"%s:%s\" using PKCS#11 interface",
options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_slot_type, options->pkcs11_slot); options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_slot_type, options->pkcs11_slot);
} }