summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/pkcs11.c17
-rw-r--r--lib/pkcs11_int.h2
-rw-r--r--lib/pkcs11_privkey.c33
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;