summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2017-06-16 22:04:49 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-06-17 14:04:35 +0200
commit41a9cb35b0bcd056fc506f985eb3716bd0c41365 (patch)
tree43819d5a333281ef702aaaf0ec703d3a1c27dc03
parentb60b8a42c4c972c82d80c9e875b2afdb61f0f109 (diff)
downloadgnutls-41a9cb35b0bcd056fc506f985eb3716bd0c41365.tar.gz
pkcs11: improved handling of HSMs without CKU_CONTEXT_SPECIFIC support
That is, when the HSM returns CKR_USER_NOT_LOGGED_IN, switch to CKU_USER, instead of relying to a fallback within pkcs11_login(). That simplifies login logic. Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
-rw-r--r--lib/pkcs11.c34
-rw-r--r--lib/pkcs11_privkey.c28
2 files changed, 28 insertions, 34 deletions
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index b88b5af846..b22d8e8e5b 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -2583,7 +2583,6 @@ pkcs11_login(struct pkcs11_session_info *sinfo,
return 0;
}
- retry_login:
/* For a token with a "protected" (out-of-band) authentication
* path, calling login with a NULL username is all that is
* required. */
@@ -2597,7 +2596,8 @@ pkcs11_login(struct pkcs11_session_info *sinfo,
gnutls_assert();
_gnutls_debug_log
("p11: Protected login failed.\n");
- goto login_finished;
+ ret = GNUTLS_E_PKCS11_ERROR;
+ goto cleanup;
}
}
@@ -2607,16 +2607,18 @@ pkcs11_login(struct pkcs11_session_info *sinfo,
memcpy(&tinfo, &sinfo->tinfo, sizeof(tinfo));
- /* Check whether the session is already logged in, and if so, just skip */
- rv = (sinfo->module)->C_GetSessionInfo(sinfo->pks,
- &session_info);
- if (rv == CKR_OK && !(flags & SESSION_CONTEXT_SPECIFIC) &&
- (session_info.state == CKS_RO_USER_FUNCTIONS
- || session_info.state == CKS_RW_USER_FUNCTIONS)) {
- ret = 0;
- _gnutls_debug_log
- ("p11: Already logged in\n");
- goto cleanup;
+ if (!(flags & SESSION_CONTEXT_SPECIFIC)) {
+ /* Check whether the session is already logged in, and if so, just skip */
+ rv = (sinfo->module)->C_GetSessionInfo(sinfo->pks,
+ &session_info);
+ if (rv == CKR_OK &&
+ (session_info.state == CKS_RO_USER_FUNCTIONS
+ || session_info.state == CKS_RW_USER_FUNCTIONS)) {
+ ret = 0;
+ _gnutls_debug_log
+ ("p11: Already logged in\n");
+ goto cleanup;
+ }
}
/* If login has been attempted once already, check the token
@@ -2651,16 +2653,8 @@ pkcs11_login(struct pkcs11_session_info *sinfo,
}
while (rv == CKR_PIN_INCORRECT);
- login_finished:
_gnutls_debug_log("p11: Login result = %s (%lu)\n", (rv==0)?"ok":p11_kit_strerror(rv), rv);
- if (unlikely(rv == CKR_USER_TYPE_INVALID && user_type == CKU_CONTEXT_SPECIFIC)) {
- _gnutls_debug_log("p11: Retrying login with CKU_USER\n");
- /* PKCS#11 v2.10 don't know about CKU_CONTEXT_SPECIFIC */
- user_type = CKU_USER;
- goto retry_login;
- }
-
ret = (rv == CKR_OK || rv ==
CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err(rv);
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
index 07dc9e0a79..40def6cff5 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -290,8 +290,8 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key,
gnutls_datum_t tmp = { NULL, 0 };
unsigned long siglen;
struct pkcs11_session_info *sinfo;
- unsigned retried_login = 0;
- unsigned flags = SESSION_LOGIN|SESSION_CONTEXT_SPECIFIC;
+ unsigned req_login = 0;
+ unsigned login_flags = SESSION_LOGIN|SESSION_CONTEXT_SPECIFIC;
PKCS11_CHECK_INIT_PRIVKEY(key);
@@ -315,12 +315,12 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key,
}
retry_login:
- if (key->reauth || retried_login) {
- if (retried_login)
- flags |= SESSION_FORCE_LOGIN;
+ if (key->reauth || req_login) {
+ if (req_login)
+ login_flags = SESSION_FORCE_LOGIN|SESSION_LOGIN;
ret =
pkcs11_login(&key->sinfo, &key->pin,
- key->uinfo, flags);
+ key->uinfo, login_flags);
if (ret < 0) {
gnutls_assert();
_gnutls_debug_log("PKCS #11 login failed, trying operation anyway\n");
@@ -331,8 +331,8 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key,
/* Work out how long the signature must be: */
rv = pkcs11_sign(sinfo->module, sinfo->pks, hash->data, hash->size,
NULL, &siglen);
- if (unlikely(rv == CKR_USER_NOT_LOGGED_IN && retried_login == 0)) {
- retried_login = 1;
+ if (unlikely(rv == CKR_USER_NOT_LOGGED_IN && req_login == 0)) {
+ req_login = 1;
goto retry_login;
}
@@ -562,7 +562,7 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key,
int ret;
struct ck_mechanism mech;
unsigned long siglen;
- unsigned retried_login = 0;
+ unsigned req_login = 0;
unsigned login_flags = SESSION_LOGIN|SESSION_CONTEXT_SPECIFIC;
PKCS11_CHECK_INIT_PRIVKEY(key);
@@ -588,9 +588,9 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key,
}
retry_login:
- if (key->reauth || retried_login) {
- if (retried_login)
- login_flags |= SESSION_FORCE_LOGIN;
+ if (key->reauth || req_login) {
+ if (req_login)
+ login_flags = SESSION_FORCE_LOGIN|SESSION_LOGIN;
ret =
pkcs11_login(&key->sinfo, &key->pin,
key->uinfo, login_flags);
@@ -604,8 +604,8 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key,
/* Work out how long the plaintext must be: */
rv = pkcs11_decrypt(key->sinfo.module, key->sinfo.pks, ciphertext->data,
ciphertext->size, NULL, &siglen);
- if (unlikely(rv == CKR_USER_NOT_LOGGED_IN && retried_login == 0)) {
- retried_login = 1;
+ if (unlikely(rv == CKR_USER_NOT_LOGGED_IN && req_login == 0)) {
+ req_login = 1;
goto retry_login;
}