summaryrefslogtreecommitdiff
path: root/ssh-pkcs11.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-01-22 12:03:58 +0000
committerDamien Miller <djm@mindrot.org>2019-01-22 23:04:54 +1100
commit41923ce06ac149453debe472238e0cca7d5a2e5f (patch)
tree2ae3cf82dc629a17b636ff26df2bdc91adff5caf /ssh-pkcs11.c
parent2162171ad517501ba511fa9f8191945d01857bb4 (diff)
upstream: Correct some bugs in PKCS#11 token PIN handling at
initial login, the attempt at reading the PIN could be skipped in some cases especially on devices with integrated PIN readers. based on patch from Daniel Kucera in bz#2652; ok markus@ OpenBSD-Commit-ID: fad70a61c60610afe8bb0db538c90e343e75e58e
Diffstat (limited to 'ssh-pkcs11.c')
-rw-r--r--ssh-pkcs11.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index 384ac1edb..f116e4051 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-pkcs11.c,v 1.40 2019/01/22 12:00:50 djm Exp $ */ 1/* $OpenBSD: ssh-pkcs11.c,v 1.41 2019/01/22 12:03:58 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.
@@ -620,26 +620,36 @@ static int
620pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, 620pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin,
621 CK_ULONG user) 621 CK_ULONG user)
622{ 622{
623 CK_RV rv; 623 struct pkcs11_slotinfo *si;
624 CK_FUNCTION_LIST *f; 624 CK_FUNCTION_LIST *f;
625 CK_RV rv;
625 CK_SESSION_HANDLE session; 626 CK_SESSION_HANDLE session;
626 int login_required, ret; 627 int login_required, have_pinpad, ret;
627 628
628 f = p->function_list; 629 f = p->function_list;
629 login_required = p->slotinfo[slotidx].token.flags & CKF_LOGIN_REQUIRED; 630 si = &p->slotinfo[slotidx];
630 if (pin && login_required && !strlen(pin)) { 631
632 have_pinpad = si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH;
633 login_required = si->token.flags & CKF_LOGIN_REQUIRED;
634
635 /* fail early before opening session */
636 if (login_required && !have_pinpad && pin != NULL && strlen(pin) == 0) {
631 error("pin required"); 637 error("pin required");
632 return (-SSH_PKCS11_ERR_PIN_REQUIRED); 638 return (-SSH_PKCS11_ERR_PIN_REQUIRED);
633 } 639 }
634 if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| 640 if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION|
635 CKF_SERIAL_SESSION, NULL, NULL, &session)) 641 CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) {
636 != CKR_OK) {
637 error("C_OpenSession failed: %lu", rv); 642 error("C_OpenSession failed: %lu", rv);
638 return (-1); 643 return (-1);
639 } 644 }
640 if (login_required && pin) { 645 if (login_required) {
641 rv = f->C_Login(session, user, 646 if (have_pinpad && (pin == NULL || strlen(pin) == 0)) {
642 (u_char *)pin, strlen(pin)); 647 /* defer PIN entry to the reader keypad */
648 rv = f->C_Login(session, CKU_USER, NULL_PTR, 0);
649 } else {
650 rv = f->C_Login(session, CKU_USER,
651 (u_char *)pin, strlen(pin));
652 }
643 if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { 653 if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
644 error("C_Login failed: %lu", rv); 654 error("C_Login failed: %lu", rv);
645 ret = (rv == CKR_PIN_LOCKED) ? 655 ret = (rv == CKR_PIN_LOCKED) ?
@@ -649,9 +659,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin,
649 error("C_CloseSession failed: %lu", rv); 659 error("C_CloseSession failed: %lu", rv);
650 return (ret); 660 return (ret);
651 } 661 }
652 p->slotinfo[slotidx].logged_in = 1; 662 si->logged_in = 1;
653 } 663 }
654 p->slotinfo[slotidx].session = session; 664 si->session = session;
655 return (0); 665 return (0);
656} 666}
657 667