summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2019-09-05 10:05:52 +0000
committerDamien Miller <djm@cvs.openbsd.org>2019-09-05 10:05:52 +0000
commit389dbdc358f9e0292f57bbc172a52504ac6f11bc (patch)
tree14f7a8d20165b0a4abe5e26a0a2f0b51b65c888f
parent00014cc9ec8b8e332ea61773669ec3ab14c6b11d (diff)
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@
-rw-r--r--usr.bin/ssh/ssh-pkcs11.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/usr.bin/ssh/ssh-pkcs11.c b/usr.bin/ssh/ssh-pkcs11.c
index e6c37b0ca4e..12aa6dacb07 100644
--- a/usr.bin/ssh/ssh-pkcs11.c
+++ b/usr.bin/ssh/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.
@@ -231,21 +231,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) ?
@@ -262,7 +258,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));
@@ -275,6 +271,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)
{
@@ -1540,9 +1549,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);
}