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 | |
parent | 76f09bd95917862101b740afb19f4db5ccc752bf (diff) |
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
-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 d1a101218..d4053ea82 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-pkcs11.c,v 1.44 2019/09/02 00:19:25 djm Exp $ */ | 1 | /* $OpenBSD: ssh-pkcs11.c,v 1.45 2019/09/05 10:05:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2010 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2010 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2014 Pedro Martelletto. All rights reserved. | 4 | * Copyright (c) 2014 Pedro Martelletto. All rights reserved. |
@@ -240,21 +240,17 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, | |||
240 | } | 240 | } |
241 | 241 | ||
242 | static int | 242 | static int |
243 | pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) | 243 | pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, |
244 | CK_USER_TYPE type) | ||
244 | { | 245 | { |
245 | struct pkcs11_slotinfo *si; | ||
246 | CK_FUNCTION_LIST *f; | ||
247 | char *pin = NULL, prompt[1024]; | 246 | char *pin = NULL, prompt[1024]; |
248 | CK_RV rv; | 247 | CK_RV rv; |
249 | 248 | ||
250 | if (!k11->provider || !k11->provider->valid) { | 249 | if (provider == NULL || si == NULL || !provider->valid) { |
251 | error("no pkcs11 (valid) provider found"); | 250 | error("no pkcs11 (valid) provider found"); |
252 | return (-1); | 251 | return (-1); |
253 | } | 252 | } |
254 | 253 | ||
255 | f = k11->provider->function_list; | ||
256 | si = &k11->provider->slotinfo[k11->slotidx]; | ||
257 | |||
258 | if (!pkcs11_interactive) { | 254 | if (!pkcs11_interactive) { |
259 | error("need pin entry%s", | 255 | error("need pin entry%s", |
260 | (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ? | 256 | (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ? |
@@ -271,7 +267,7 @@ pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) | |||
271 | return (-1); /* bail out */ | 267 | return (-1); /* bail out */ |
272 | } | 268 | } |
273 | } | 269 | } |
274 | rv = f->C_Login(si->session, type, (u_char *)pin, | 270 | rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, |
275 | (pin != NULL) ? strlen(pin) : 0); | 271 | (pin != NULL) ? strlen(pin) : 0); |
276 | if (pin != NULL) | 272 | if (pin != NULL) |
277 | freezero(pin, strlen(pin)); | 273 | freezero(pin, strlen(pin)); |
@@ -284,6 +280,19 @@ pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) | |||
284 | } | 280 | } |
285 | 281 | ||
286 | static int | 282 | static int |
283 | pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) | ||
284 | { | ||
285 | if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { | ||
286 | error("no pkcs11 (valid) provider found"); | ||
287 | return (-1); | ||
288 | } | ||
289 | |||
290 | return pkcs11_login_slot(k11->provider, | ||
291 | &k11->provider->slotinfo[k11->slotidx], type); | ||
292 | } | ||
293 | |||
294 | |||
295 | static int | ||
287 | pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, | 296 | pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, |
288 | CK_ATTRIBUTE_TYPE type, int *val) | 297 | CK_ATTRIBUTE_TYPE type, int *val) |
289 | { | 298 | { |
@@ -1565,9 +1574,22 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, | |||
1565 | * open session, login with pin and retrieve public | 1574 | * open session, login with pin and retrieve public |
1566 | * keys (if keyp is provided) | 1575 | * keys (if keyp is provided) |
1567 | */ | 1576 | */ |
1568 | if ((ret = pkcs11_open_session(p, i, pin, user)) == 0) { | 1577 | if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || |
1569 | if (keyp == NULL) | 1578 | keyp == NULL) |
1579 | continue; | ||
1580 | pkcs11_fetch_keys(p, i, keyp, &nkeys); | ||
1581 | pkcs11_fetch_certs(p, i, keyp, &nkeys); | ||
1582 | if (nkeys == 0 && !p->slotinfo[i].logged_in && | ||
1583 | pkcs11_interactive) { | ||
1584 | /* | ||
1585 | * Some tokens require login before they will | ||
1586 | * expose keys. | ||
1587 | */ | ||
1588 | if (pkcs11_login_slot(p, &p->slotinfo[i], | ||
1589 | CKU_USER) < 0) { | ||
1590 | error("login failed"); | ||
1570 | continue; | 1591 | continue; |
1592 | } | ||
1571 | pkcs11_fetch_keys(p, i, keyp, &nkeys); | 1593 | pkcs11_fetch_keys(p, i, keyp, &nkeys); |
1572 | pkcs11_fetch_certs(p, i, keyp, &nkeys); | 1594 | pkcs11_fetch_certs(p, i, keyp, &nkeys); |
1573 | } | 1595 | } |