diff options
-rw-r--r-- | lib/pkcs11.c | 17 | ||||
-rw-r--r-- | lib/pkcs11_int.h | 2 | ||||
-rw-r--r-- | lib/pkcs11_privkey.c | 33 |
3 files changed, 44 insertions, 8 deletions
diff --git a/lib/pkcs11.c b/lib/pkcs11.c index cec9e93813..fa517137f6 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -1052,12 +1052,13 @@ pkcs11_open_session(struct pkcs11_session_info *sinfo, /* ok found */ sinfo->pks = pks; sinfo->module = module; + sinfo->sid = slot; sinfo->init = 1; memcpy(&sinfo->tinfo, &tinfo.tinfo, sizeof(sinfo->tinfo)); if (flags & SESSION_LOGIN) { ret = - pkcs11_login(sinfo, pin_info, &tinfo, info, + pkcs11_login(sinfo, pin_info, info, (flags & SESSION_SO) ? 1 : 0); if (ret < 0) { gnutls_assert(); @@ -1134,10 +1135,12 @@ _pkcs11_traverse_tokens(find_func_t find_func, void *input, sinfo.module = module; sinfo.pks = pks; + sinfo.sid = tinfo.sid; + memcpy(&sinfo.tinfo, &tinfo.tinfo, sizeof(sinfo.tinfo)); if (flags & SESSION_LOGIN) { ret = - pkcs11_login(&sinfo, pin_info, &tinfo, + pkcs11_login(&sinfo, pin_info, info, (flags & SESSION_SO) ? 1 : 0); if (ret < 0) { gnutls_assert(); @@ -2183,7 +2186,7 @@ retrieve_pin(struct pin_info_st *pin_info, struct p11_kit_uri *info, int pkcs11_login(struct pkcs11_session_info *sinfo, struct pin_info_st *pin_info, - const struct token_info *tokinfo, struct p11_kit_uri *info, + struct p11_kit_uri *info, int so) { struct ck_session_info session_info; @@ -2192,7 +2195,7 @@ pkcs11_login(struct pkcs11_session_info *sinfo, ck_rv_t rv; user_type = (so == 0) ? CKU_USER : CKU_SO; - if (so == 0 && (tokinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0) { + if (so == 0 && (sinfo->tinfo.flags & CKF_LOGIN_REQUIRED) == 0) { gnutls_assert(); _gnutls_debug_log("p11: No login required.\n"); return 0; @@ -2201,7 +2204,7 @@ pkcs11_login(struct pkcs11_session_info *sinfo, /* For a token with a "protected" (out-of-band) authentication * path, calling login with a NULL username is all that is * required. */ - if (tokinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) { + if (sinfo->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) { rv = (sinfo->module)->C_Login(sinfo->pks, (so == 0) ? CKU_USER : CKU_SO, @@ -2221,7 +2224,7 @@ pkcs11_login(struct pkcs11_session_info *sinfo, struct p11_kit_pin *pin; struct ck_token_info tinfo; - memcpy(&tinfo, &tokinfo->tinfo, sizeof(tinfo)); + 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, @@ -2237,7 +2240,7 @@ pkcs11_login(struct pkcs11_session_info *sinfo, * status again, the flags might change. */ if (attempt) { if (pkcs11_get_token_info - (tokinfo->prov->module, tokinfo->sid, + (sinfo->module, sinfo->sid, &tinfo) != CKR_OK) { gnutls_assert(); _gnutls_debug_log diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h index 18924da750..7de1aa48c7 100644 --- a/lib/pkcs11_int.h +++ b/lib/pkcs11_int.h @@ -38,6 +38,7 @@ struct pkcs11_session_info { struct ck_function_list *module; struct ck_token_info tinfo; ck_session_handle_t pks; + ck_slot_id_t sid; unsigned int init; }; @@ -103,7 +104,6 @@ int pkcs11_get_info(struct p11_kit_uri *info, size_t * output_size); int pkcs11_login(struct pkcs11_session_info *sinfo, struct pin_info_st *pin_info, - const struct token_info *tokinfo, struct p11_kit_uri *info, int so); int pkcs11_call_token_func(struct p11_kit_uri *info, const unsigned retry); diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c index e5d3c9a527..2864dbcfc2 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -68,6 +68,7 @@ struct gnutls_pkcs11_privkey_st { struct pkcs11_session_info sinfo; ck_object_handle_t ref; /* the key in the session */ + unsigned reauth; /* whether we need to login on each operation */ struct pin_info_st pin; }; @@ -253,6 +254,17 @@ _gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key, PKCS11_CHECK_INIT_PRIVKEY(key); + if (key->reauth) { + ret = + pkcs11_login(&key->sinfo, &key->pin, + key->uinfo, 0); + if (ret < 0) { + gnutls_assert(); + _gnutls_debug_log("PKCS #11 login failed, trying operation anyway\n"); + /* let's try the operation anyway */ + } + } + sinfo = &key->sinfo; mech.mechanism = pk_to_mech(key->pk_algorithm); @@ -384,6 +396,7 @@ gnutls_pkcs11_privkey_import_url(gnutls_pkcs11_privkey_t pkey, struct ck_attribute *attr; struct ck_attribute a[4]; ck_key_type_t key_type; + ck_bool_t reauth = 0; PKCS11_CHECK_INIT; @@ -434,6 +447,15 @@ gnutls_pkcs11_privkey_import_url(gnutls_pkcs11_privkey_t pkey, } } + a[0].type = CKA_ALWAYS_AUTHENTICATE; + a[0].value = &reauth; + a[0].value_len = sizeof(reauth); + + if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, a, 1) + == CKR_OK) { + pkey->reauth = reauth; + } + ret = 0; return ret; @@ -473,6 +495,17 @@ _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, if (key->pk_algorithm != GNUTLS_PK_RSA) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + if (key->reauth) { + ret = + pkcs11_login(&key->sinfo, &key->pin, + key->uinfo, 0); + if (ret < 0) { + gnutls_assert(); + _gnutls_debug_log("PKCS #11 login failed, trying operation anyway\n"); + /* let's try the operation anyway */ + } + } + mech.mechanism = CKM_RSA_PKCS; mech.parameter = NULL; mech.parameter_len = 0; |