diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-05-29 11:11:24 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-06-19 11:16:20 +0200 |
commit | 67e8843091b5704c79451898d59b85485b290dda (patch) | |
tree | 47a507b94d5476cdcbcc947cbee8a3798e28eb31 | |
parent | e5254397345dd340d87625cbeb92cbe4b9f3b103 (diff) | |
download | gnutls-67e8843091b5704c79451898d59b85485b290dda.tar.gz |
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 <nmav@redhat.com>
-rw-r--r-- | lib/pkcs11.c | 49 | ||||
-rw-r--r-- | lib/pkcs11_int.h | 2 | ||||
-rw-r--r-- | lib/pkcs11_privkey.c | 12 |
3 files changed, 38 insertions, 25 deletions
diff --git a/lib/pkcs11.c b/lib/pkcs11.c index 9ca9863b43..429c8601a8 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -1255,15 +1255,13 @@ pkcs11_open_session(struct pkcs11_session_info *sinfo, sinfo->init = 1; memcpy(&sinfo->tinfo, &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; @@ -1337,15 +1335,12 @@ _pkcs11_traverse_tokens(find_func_t find_func, void *input, sinfo.sid = tinfo.sid; memcpy(&sinfo.tinfo, &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(); - return ret; - } + ret = + pkcs11_login(&sinfo, pin_info, + info, flags, 0); + if (ret < 0) { + gnutls_assert(); + return ret; } ret = @@ -1957,9 +1952,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; @@ -2418,7 +2415,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; @@ -2426,7 +2423,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 @@ -2434,7 +2436,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 fa994fe88d..3d639d2e55 100644 --- a/lib/pkcs11_int.h +++ b/lib/pkcs11_int.h @@ -119,6 +119,8 @@ int pkcs11_info_to_url(struct p11_kit_uri *info, #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 e4a540f93c..5ce6e0ac4e 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -232,6 +232,7 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key, unsigned long siglen; struct pkcs11_session_info *sinfo; unsigned req_login = 0; + unsigned login_flags = SESSION_LOGIN; PKCS11_CHECK_INIT_PRIVKEY(key); @@ -252,9 +253,12 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key, retry_login: if (key->reauth || req_login) { + if (req_login) + login_flags |= SESSION_FORCE_LOGIN; + ret = pkcs11_login(&key->sinfo, &key->pin, - key->uinfo, 0, 1-req_login); + key->uinfo, login_flags, 1-req_login); if (ret < 0) { gnutls_assert(); _gnutls_debug_log("PKCS #11 login failed, trying operation anyway\n"); @@ -482,6 +486,7 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, struct ck_mechanism mech; unsigned long siglen; unsigned req_login = 0; + unsigned login_flags = SESSION_LOGIN; PKCS11_CHECK_INIT_PRIVKEY(key); @@ -503,9 +508,12 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, retry_login: if (key->reauth || req_login) { + if (req_login) + login_flags |= SESSION_FORCE_LOGIN; + ret = pkcs11_login(&key->sinfo, &key->pin, - key->uinfo, 0, 1-req_login); + key->uinfo, login_flags, 1-req_login); if (ret < 0) { gnutls_assert(); _gnutls_debug_log("PKCS #11 login failed, trying operation anyway\n"); |