From 49a33f79c941a18d90a6dada9c32f526b1a5aa9c Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 29 May 2017 11:11:24 +0200 Subject: pkcs11: the GNUTLS_PKCS11_OBJ_FLAG_LOGIN will force a login That is, even in tokens which do not have a CKF_LOGIN_REQUIRED flag a login will be forced. This allows operation on the safenet HSMs which do not set that flag. Signed-off-by: Nikos Mavrogiannopoulos --- lib/pkcs11.c | 49 ++++++++++++++++++++++++++----------------------- lib/pkcs11_int.h | 2 ++ lib/pkcs11_privkey.c | 10 ++++++++-- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/lib/pkcs11.c b/lib/pkcs11.c index 85954e72ad..5785c4c782 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -1343,15 +1343,13 @@ pkcs11_open_session(struct pkcs11_session_info *sinfo, sinfo->init = 1; memcpy(&sinfo->tinfo, &tinfo, sizeof(sinfo->tinfo)); - if (flags & SESSION_LOGIN) { - ret = - pkcs11_login(sinfo, pin_info, info, - (flags & SESSION_SO) ? 1 : 0, 0); - if (ret < 0) { - gnutls_assert(); - pkcs11_close_session(sinfo); - return ret; - } + ret = + pkcs11_login(sinfo, pin_info, info, + flags, 0); + if (ret < 0) { + gnutls_assert(); + pkcs11_close_session(sinfo); + return ret; } return 0; @@ -1426,15 +1424,12 @@ _pkcs11_traverse_tokens(find_func_t find_func, void *input, memcpy(&sinfo.tinfo, &l_tinfo, sizeof(sinfo.tinfo)); memcpy(&sinfo.slot_info, &l_sinfo, sizeof(sinfo.slot_info)); - if (flags & SESSION_LOGIN) { - ret = - pkcs11_login(&sinfo, pin_info, - info, (flags & SESSION_SO) ? 1 : 0, - 0); - if (ret < 0) { - gnutls_assert(); - return ret; - } + ret = + pkcs11_login(&sinfo, pin_info, + info, flags, 0); + if (ret < 0) { + gnutls_assert(); + return ret; } ret = @@ -2065,9 +2060,11 @@ unsigned int pkcs11_obj_flags_to_int(unsigned int flags) unsigned int ret_flags = 0; if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN) - ret_flags |= SESSION_LOGIN; + ret_flags |= SESSION_LOGIN | SESSION_FORCE_LOGIN; + if (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO) - ret_flags |= SESSION_LOGIN | SESSION_SO; + ret_flags |= SESSION_LOGIN | SESSION_SO | SESSION_FORCE_LOGIN; + if (flags & GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE) ret_flags |= SESSION_TRUSTED; @@ -2559,7 +2556,7 @@ int pkcs11_login(struct pkcs11_session_info *sinfo, struct pin_info_st *pin_info, struct p11_kit_uri *info, - unsigned so, + unsigned flags, unsigned reauth) { struct ck_session_info session_info; @@ -2567,7 +2564,12 @@ pkcs11_login(struct pkcs11_session_info *sinfo, ck_user_type_t user_type; ck_rv_t rv; - if (so == 0) { + if (!(flags & SESSION_LOGIN)) { + _gnutls_debug_log("p11: No login requested.\n"); + return 0; + } + + if (!(flags & SESSION_SO)) { if (reauth == 0) user_type = CKU_USER; else @@ -2575,7 +2577,8 @@ pkcs11_login(struct pkcs11_session_info *sinfo, } else user_type = CKU_SO; - if (so == 0 && (sinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0) { + if (!(flags & (SESSION_FORCE_LOGIN|SESSION_SO)) && + !(sinfo->tinfo.flags & CKF_LOGIN_REQUIRED)) { gnutls_assert(); _gnutls_debug_log("p11: No login required.\n"); return 0; diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h index bcde4d8ce8..60a1494af6 100644 --- a/lib/pkcs11_int.h +++ b/lib/pkcs11_int.h @@ -131,6 +131,8 @@ _gnutls_x509_crt_import_pkcs11_url(gnutls_x509_crt_t crt, #define SESSION_LOGIN (1<<1) #define SESSION_SO (1<<2) /* security officer session */ #define SESSION_TRUSTED (1<<3) /* session on a marked as trusted (p11-kit) module */ +#define SESSION_FORCE_LOGIN (1<<4) /* force login even when CFK_LOGIN_REQUIRED is not set */ + int pkcs11_open_session(struct pkcs11_session_info *sinfo, struct pin_info_st *pin_info, struct p11_kit_uri *info, unsigned int flags); diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c index d5772a0ae2..51a20dc7be 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -291,6 +291,7 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key, unsigned long siglen; struct pkcs11_session_info *sinfo; unsigned retried_login = 0; + unsigned flags = SESSION_LOGIN; PKCS11_CHECK_INIT_PRIVKEY(key); @@ -315,9 +316,11 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key, retry_login: if (key->reauth || retried_login) { + if (retried_login) + flags |= SESSION_FORCE_LOGIN; ret = pkcs11_login(&key->sinfo, &key->pin, - key->uinfo, 0, 1); + key->uinfo, flags, 1); if (ret < 0) { gnutls_assert(); _gnutls_debug_log("PKCS #11 login failed, trying operation anyway\n"); @@ -560,6 +563,7 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, struct ck_mechanism mech; unsigned long siglen; unsigned retried_login = 0; + unsigned login_flags = SESSION_LOGIN; PKCS11_CHECK_INIT_PRIVKEY(key); @@ -585,9 +589,11 @@ _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; ret = pkcs11_login(&key->sinfo, &key->pin, - key->uinfo, 0, 1); + key->uinfo, login_flags, 1); if (ret < 0) { gnutls_assert(); _gnutls_debug_log("PKCS #11 login failed, trying operation anyway\n"); -- cgit v1.2.1