summaryrefslogtreecommitdiffstats
path: root/pkcs11.c
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2006-04-05 07:17:02 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2006-04-05 07:17:02 +0000
commit18597b93f7b43f63173f373fbd8548f2d08e25bb (patch)
tree31287d7784477dff653e5b92daee22872f58cab2 /pkcs11.c
parentbe9150b693345134142d1d58fac9b251d7e7ba5d (diff)
downloadopenvpn-18597b93f7b43f63173f373fbd8548f2d08e25bb.tar.gz
openvpn-18597b93f7b43f63173f373fbd8548f2d08e25bb.tar.xz
openvpn-18597b93f7b43f63173f373fbd8548f2d08e25bb.zip
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
Diffstat (limited to 'pkcs11.c')
-rw-r--r--pkcs11.c315
1 files changed, 248 insertions, 67 deletions
diff --git a/pkcs11.c b/pkcs11.c
index a8875cf..3b136c5 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -44,6 +44,74 @@
#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
void
_pkcs11_openvpn_print (
IN const void *pData,
@@ -62,20 +130,46 @@ _pkcs11_openvpn_print (
}
static
+void
+_pkcs11_openvpn_log (
+ IN const void *pData,
+ 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_card_prompt (
+_pkcs11_openvpn_token_prompt (
IN const void *pData,
- IN const char * const szLabel
+ IN const pkcs11h_token_id_t token
) {
static struct user_pass token_resp;
- ASSERT (szLabel!=NULL);
+ ASSERT (token!=NULL);
CLEAR (token_resp);
token_resp.defined = false;
token_resp.nocache = true;
- openvpn_snprintf (token_resp.username, sizeof (token_resp.username), "Please insert %s token", szLabel);
- get_user_pass (&token_resp, NULL, "token-insertion-request", GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK);
+ openvpn_snprintf (
+ 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;
}
@@ -84,16 +178,16 @@ static
bool
_pkcs11_openvpn_pin_prompt (
IN const void *pData,
- IN const char * const szLabel,
+ IN const pkcs11h_token_id_t token,
OUT char * const szPIN,
IN const size_t nMaxPIN
) {
static struct user_pass token_pass;
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.nocache = true;
@@ -111,12 +205,13 @@ _pkcs11_openvpn_pin_prompt (
bool
pkcs11_initialize (
- const int nPINCachePeriod
+ IN const bool fProtectedAuthentication,
+ IN const int nPINCachePeriod
) {
CK_RV rv = CKR_OK;
- PKCS11LOG (
- PKCS11_LOG_DEBUG2,
+ dmsg (
+ D_PKCS11_DEBUG,
"PKCS#11: pkcs11_initialize - entered"
);
@@ -124,32 +219,50 @@ pkcs11_initialize (
rv == 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 (
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 (
rv == 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 (
rv == 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 (
- PKCS11_LOG_DEBUG2,
+ dmsg (
+ D_PKCS11_DEBUG,
"PKCS#11: pkcs11_initialize - return %ld-'%s'",
rv,
pkcs11h_getMessage (rv)
@@ -160,15 +273,15 @@ pkcs11_initialize (
void
pkcs11_terminate () {
- PKCS11LOG (
- PKCS11_LOG_DEBUG2,
+ dmsg (
+ D_PKCS11_DEBUG,
"PKCS#11: pkcs11_terminate - entered"
);
pkcs11h_terminate ();
- PKCS11LOG (
- PKCS11_LOG_DEBUG2,
+ dmsg (
+ D_PKCS11_DEBUG,
"PKCS#11: pkcs11_terminate - return"
);
}
@@ -181,32 +294,69 @@ pkcs11_forkFixup () {
bool
pkcs11_addProvider (
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;
- PKCS11LOG (
- PKCS11_LOG_DEBUG2,
+ ASSERT (provider!=NULL);
+ /*ASSERT (sign_mode!=NULL); NULL is default */
+
+ dmsg (
+ D_PKCS11_DEBUG,
"PKCS#11: pkcs11_addProvider - entered - provider='%s', sign_mode='%s'",
provider,
sign_mode == NULL ? "default" : sign_mode
);
- PKCS11LOG (
- PKCS11_LOG_INFO,
+ msg (
+ M_INFO,
"PKCS#11: Adding PKCS#11 provider '%s'",
provider
);
+ if (rv == CKR_OK) {
+ if (sign_mode == NULL || !strcmp (sign_mode, "auto")) {
+ maskSignMode = 0;
+ }
+ 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;
+ }
+ }
+
if (
rv == CKR_OK &&
- (rv = pkcs11h_addProvider (provider, sign_mode)) != CKR_OK
+ (rv = pkcs11h_addProvider (
+ provider,
+ provider,
+ fProtectedAuthentication,
+ maskSignMode,
+ PKCS11H_SLOTEVENT_METHOD_AUTO,
+ 0,
+ fCertIsPrivate
+ )) != CKR_OK
) {
- PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
+ msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
}
- PKCS11LOG (
- PKCS11_LOG_DEBUG2,
+ dmsg (
+ D_PKCS11_DEBUG,
"PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'",
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,
IN const char * const pkcs11_id_type,
- IN const char * const pkcs11_id,
- IN const bool pkcs11_protected_authentication,
- IN const bool pkcs11_cert_private
+ IN const char * const pkcs11_id
) {
X509 *x509 = 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;
bool fOK = true;
- PKCS11LOG (
- PKCS11_LOG_DEBUG2,
- "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 (ssl_ctx!=NULL);
+ ASSERT (pkcs11_slot_type!=NULL);
+ 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,
pkcs11_slot_type,
pkcs11_slot,
pkcs11_id_type,
- pkcs11_id,
- pkcs11_protected_authentication ? 1 : 0
+ pkcs11_id
);
- PKCS11ASSERT (ssl_ctx!=NULL);
- PKCS11ASSERT (pkcs11_slot_type!=NULL);
- PKCS11ASSERT (pkcs11_slot!=NULL);
- PKCS11ASSERT (pkcs11_id_type!=NULL);
- PKCS11ASSERT (pkcs11_id!=NULL);
+ ASSERT (ssl_ctx!=NULL);
+ ASSERT (pkcs11_slot_type!=NULL);
+ ASSERT (pkcs11_slot!=NULL);
+ ASSERT (pkcs11_id_type!=NULL);
+ ASSERT (pkcs11_id!=NULL);
if (
fOK &&
- (pkcs11h_openssl_session = pkcs11h_openssl_createSession ()) == NULL
+ (rv = pkcs11h_locate_certificate (
+ pkcs11_slot_type,
+ pkcs11_slot,
+ pkcs11_id_type,
+ pkcs11_id,
+ &certificate_id
+ )) != CKR_OK
) {
fOK = false;
- PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize openssh session");
+ msg (M_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv));
}
if (
fOK &&
- (rv = pkcs11h_createCertificateSession (
- pkcs11_slot_type,
- pkcs11_slot,
- pkcs11_id_type,
- pkcs11_id,
- pkcs11_protected_authentication,
- pkcs11_cert_private,
+ (rv = pkcs11h_certificate_create (
+ certificate_id,
PKCS11H_PIN_CACHE_INFINITE,
- &pkcs11h_openssl_session->certificate
+ &certificate
)) != CKR_OK
) {
fOK = false;
- PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv));
+ msg (M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
}
if (
fOK &&
- (rsa = pkcs11h_openssl_getRSA (pkcs11h_openssl_session)) == NULL
+ (openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL
) {
fOK = false;
- PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get rsa object");
+ msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
+ }
+
+ if (fOK) {
+ /*
+ * Will be released by openssl_session
+ */
+ certificate = NULL;
}
if (
fOK &&
- (x509 = pkcs11h_openssl_getX509 (pkcs11h_openssl_session)) == NULL
+ (rsa = pkcs11h_openssl_getRSA (openssl_session)) == NULL
) {
fOK = false;
- PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get certificate object");
+ 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 (
@@ -295,7 +466,7 @@ SSL_CTX_use_pkcs11 (
!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)
) {
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 (
@@ -303,7 +474,7 @@ SSL_CTX_use_pkcs11 (
!SSL_CTX_use_certificate (ssl_ctx, x509)
) {
fOK = false;
- PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set certificate for openssl");
+ msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
}
/*
@@ -320,14 +491,24 @@ SSL_CTX_use_pkcs11 (
RSA_free (rsa);
rsa = NULL;
}
+
+ if (certificate != NULL) {
+ pkcs11h_freeCertificate (certificate);
+ certificate = NULL;
+ }
+
+ if (certificate_id != NULL) {
+ pkcs11h_freeCertificateId (certificate_id);
+ certificate_id = NULL;
+ }
- if (pkcs11h_openssl_session != NULL) {
- pkcs11h_openssl_freeSession (pkcs11h_openssl_session);
- pkcs11h_openssl_session = NULL;
+ if (openssl_session != NULL) {
+ pkcs11h_openssl_freeSession (openssl_session);
+ openssl_session = NULL;
}
- PKCS11LOG (
- PKCS11_LOG_DEBUG2,
+ dmsg (
+ D_PKCS11_DEBUG,
"PKCS#11: SSL_CTX_use_pkcs11 - return fOK=%d, rv=%ld",
fOK ? 1 : 0,
rv