diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-09-05 10:05:51 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-09-05 20:07:12 +1000 |
commit | 7d6034bd020248e9fc0f8c39c71c858debd0d0c1 (patch) | |
tree | 8c1138c653536ce885bd7c80830fa7d18c9f7beb /ssh-pkcs11.c | |
parent | 76f09bd95917862101b740afb19f4db5ccc752bf (diff) | |
download | openssh-git-7d6034bd020248e9fc0f8c39c71c858debd0d0c1.tar.gz |
upstream: if a PKCS#11 token returns no keys then try to login and
refetch them. Based on patch from Jakub Jelen; bz#2430 ok markus@
OpenBSD-Commit-ID: ab53bd6ddd54dd09e54a8bfbed1a984496f08b43
Diffstat (limited to 'ssh-pkcs11.c')
-rw-r--r-- | ssh-pkcs11.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index d1a10121..d4053ea8 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.44 2019/09/02 00:19:25 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.45 2019/09/05 10:05:51 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -240,21 +240,17 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, } static int -pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) +pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + 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) { + if (provider == NULL || si == NULL || !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) ? @@ -271,7 +267,7 @@ pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) return (-1); /* bail out */ } } - rv = f->C_Login(si->session, type, (u_char *)pin, + rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, (pin != NULL) ? strlen(pin) : 0); if (pin != NULL) freezero(pin, strlen(pin)); @@ -284,6 +280,19 @@ pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) } static int +pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) +{ + if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + + return pkcs11_login_slot(k11->provider, + &k11->provider->slotinfo[k11->slotidx], type); +} + + +static int pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_TYPE type, int *val) { @@ -1565,9 +1574,22 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, * open session, login with pin and retrieve public * keys (if keyp is provided) */ - if ((ret = pkcs11_open_session(p, i, pin, user)) == 0) { - if (keyp == NULL) + if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || + keyp == NULL) + continue; + pkcs11_fetch_keys(p, i, keyp, &nkeys); + pkcs11_fetch_certs(p, i, keyp, &nkeys); + if (nkeys == 0 && !p->slotinfo[i].logged_in && + pkcs11_interactive) { + /* + * Some tokens require login before they will + * expose keys. + */ + if (pkcs11_login_slot(p, &p->slotinfo[i], + CKU_USER) < 0) { + error("login failed"); continue; + } pkcs11_fetch_keys(p, i, keyp, &nkeys); pkcs11_fetch_certs(p, i, keyp, &nkeys); } |