upstream: Support keys that set the CKA_ALWAYS_AUTHENTICATE by
requring a fresh login after the C_SignInit operation. based on patch from Jakub Jelen in bz#2638; ok markus OpenBSD-Commit-ID: a76e66996ba7c0923b46b74d46d499b811786661
This commit is contained in:
parent
7a2cb18a21
commit
2162171ad5
121
ssh-pkcs11.c
121
ssh-pkcs11.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: ssh-pkcs11.c,v 1.39 2019/01/21 02:05:38 djm Exp $ */
|
/* $OpenBSD: ssh-pkcs11.c,v 1.40 2019/01/22 12:00:50 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 Markus Friedl. All rights reserved.
|
* Copyright (c) 2010 Markus Friedl. All rights reserved.
|
||||||
* Copyright (c) 2014 Pedro Martelletto. All rights reserved.
|
* Copyright (c) 2014 Pedro Martelletto. All rights reserved.
|
||||||
|
@ -239,6 +239,85 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr,
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type)
|
||||||
|
{
|
||||||
|
struct pkcs11_slotinfo *si;
|
||||||
|
CK_FUNCTION_LIST *f;
|
||||||
|
char *pin = NULL, prompt[1024];
|
||||||
|
CK_RV rv;
|
||||||
|
|
||||||
|
if (!k11->provider || !k11->provider->valid) {
|
||||||
|
error("no pkcs11 (valid) provider found");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = k11->provider->function_list;
|
||||||
|
si = &k11->provider->slotinfo[k11->slotidx];
|
||||||
|
|
||||||
|
if (!pkcs11_interactive) {
|
||||||
|
error("need pin entry%s",
|
||||||
|
(si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ?
|
||||||
|
" on reader keypad" : "");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
|
||||||
|
verbose("Deferring PIN entry to reader keypad.");
|
||||||
|
else {
|
||||||
|
snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ",
|
||||||
|
si->token.label);
|
||||||
|
if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) {
|
||||||
|
debug("%s: no pin specified", __func__);
|
||||||
|
return (-1); /* bail out */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rv = f->C_Login(si->session, type, (u_char *)pin,
|
||||||
|
(pin != NULL) ? strlen(pin) : 0);
|
||||||
|
if (pin != NULL)
|
||||||
|
freezero(pin, strlen(pin));
|
||||||
|
if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
|
||||||
|
error("C_Login failed: %lu", rv);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
si->logged_in = 1;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj,
|
||||||
|
CK_ATTRIBUTE_TYPE type, int *val)
|
||||||
|
{
|
||||||
|
struct pkcs11_slotinfo *si;
|
||||||
|
CK_FUNCTION_LIST *f;
|
||||||
|
CK_BBOOL flag = 0;
|
||||||
|
CK_ATTRIBUTE attr;
|
||||||
|
CK_RV rv;
|
||||||
|
|
||||||
|
*val = 0;
|
||||||
|
|
||||||
|
if (!k11->provider || !k11->provider->valid) {
|
||||||
|
error("no pkcs11 (valid) provider found");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = k11->provider->function_list;
|
||||||
|
si = &k11->provider->slotinfo[k11->slotidx];
|
||||||
|
|
||||||
|
attr.type = type;
|
||||||
|
attr.pValue = &flag;
|
||||||
|
attr.ulValueLen = sizeof(flag);
|
||||||
|
|
||||||
|
rv = f->C_GetAttributeValue(si->session, obj, &attr, 1);
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
error("C_GetAttributeValue failed: %lu", rv);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*val = flag != 0;
|
||||||
|
debug("%s: provider %p slot %lu object %lu: attrib %lu = %d",
|
||||||
|
__func__, k11->provider, k11->slotidx, obj, type, *val);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
|
pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
|
||||||
{
|
{
|
||||||
|
@ -250,7 +329,8 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
|
||||||
CK_BBOOL true_val;
|
CK_BBOOL true_val;
|
||||||
CK_MECHANISM mech;
|
CK_MECHANISM mech;
|
||||||
CK_ATTRIBUTE key_filter[3];
|
CK_ATTRIBUTE key_filter[3];
|
||||||
char *pin = NULL, prompt[1024];
|
int always_auth = 0;
|
||||||
|
int did_login = 0;
|
||||||
|
|
||||||
if (!k11->provider || !k11->provider->valid) {
|
if (!k11->provider || !k11->provider->valid) {
|
||||||
error("no pkcs11 (valid) provider found");
|
error("no pkcs11 (valid) provider found");
|
||||||
|
@ -261,32 +341,11 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
|
||||||
si = &k11->provider->slotinfo[k11->slotidx];
|
si = &k11->provider->slotinfo[k11->slotidx];
|
||||||
|
|
||||||
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
|
if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
|
||||||
if (!pkcs11_interactive) {
|
if (pkcs11_login(k11, CKU_USER) < 0) {
|
||||||
error("need pin entry%s", (si->token.flags &
|
error("login failed");
|
||||||
CKF_PROTECTED_AUTHENTICATION_PATH) ?
|
|
||||||
" on reader keypad" : "");
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
|
did_login = 1;
|
||||||
verbose("Deferring PIN entry to reader keypad.");
|
|
||||||
else {
|
|
||||||
snprintf(prompt, sizeof(prompt),
|
|
||||||
"Enter PIN for '%s': ", si->token.label);
|
|
||||||
pin = read_passphrase(prompt, RP_ALLOW_EOF);
|
|
||||||
if (pin == NULL)
|
|
||||||
return (-1); /* bail out */
|
|
||||||
}
|
|
||||||
rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
|
|
||||||
(pin != NULL) ? strlen(pin) : 0);
|
|
||||||
if (pin != NULL) {
|
|
||||||
explicit_bzero(pin, strlen(pin));
|
|
||||||
free(pin);
|
|
||||||
}
|
|
||||||
if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
|
|
||||||
error("C_Login failed: %lu", rv);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
si->logged_in = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&key_filter, 0, sizeof(key_filter));
|
memset(&key_filter, 0, sizeof(key_filter));
|
||||||
|
@ -321,6 +380,16 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkcs11_check_obj_bool_attrib(k11, obj, CKA_ALWAYS_AUTHENTICATE,
|
||||||
|
&always_auth); /* ignore errors here */
|
||||||
|
if (always_auth && !did_login) {
|
||||||
|
debug("%s: always-auth key", __func__);
|
||||||
|
if (pkcs11_login(k11, CKU_CONTEXT_SPECIFIC) < 0) {
|
||||||
|
error("login failed for always-auth key");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue