diff options
-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 | ||