summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-09-05 10:05:51 +0000
committerDamien Miller <djm@mindrot.org>2019-09-05 20:07:12 +1000
commit7d6034bd020248e9fc0f8c39c71c858debd0d0c1 (patch)
tree8c1138c653536ce885bd7c80830fa7d18c9f7beb
parent76f09bd95917862101b740afb19f4db5ccc752bf (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.c44
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
242static int 242static int
243pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) 243pkcs11_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
286static int 282static int
283pkcs11_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
295static int
287pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, 296pkcs11_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 }