summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-05-29 11:11:24 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-06-16 22:20:22 +0200
commitf95a35c13db73bdee29572181df55044b65b0e5d (patch)
tree5c77b1ac9a579aebaed6e75776826c9ef5c1f3ef
parent724d23d43dc50563d3dadbdc895e2637cdfb895e (diff)
downloadgnutls-f95a35c13db73bdee29572181df55044b65b0e5d.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.c49
-rw-r--r--lib/pkcs11_int.h2
-rw-r--r--lib/pkcs11_privkey.c12
3 files changed, 38 insertions, 25 deletions
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 9641399531..44783129df 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -1312,15 +1312,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;
@@ -1395,15 +1393,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 =
@@ -2034,9 +2029,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;
@@ -2528,7 +2525,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;
@@ -2536,7 +2533,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
@@ -2544,7 +2546,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 186662785c..728d9c0a2a 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 req_login = 0;
+ unsigned login_flags = SESSION_LOGIN;
PKCS11_CHECK_INIT_PRIVKEY(key);
@@ -315,9 +316,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");
@@ -560,6 +564,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);
@@ -585,9 +590,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");