diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-01-22 12:03:58 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-01-22 23:04:54 +1100 |
commit | 41923ce06ac149453debe472238e0cca7d5a2e5f (patch) | |
tree | 2ae3cf82dc629a17b636ff26df2bdc91adff5caf | |
parent | 2162171ad517501ba511fa9f8191945d01857bb4 (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
-rw-r--r-- | ssh-pkcs11.c | 34 |
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 | |||
620 | pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, | 620 | pkcs11_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 | ||