version 1.39, 2019/01/21 02:05:38 |
version 1.40, 2019/01/22 12:00:50 |
|
|
} |
} |
|
|
static int |
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 |
pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) |
pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) |
{ |
{ |
struct pkcs11_slotinfo *si; |
struct pkcs11_slotinfo *si; |
|
|
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"); |
|
|
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)); |
|
|
if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) { |
if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) { |
error("C_SignInit failed: %lu", rv); |
error("C_SignInit failed: %lu", rv); |
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); |