=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-agent.c,v retrieving revision 1.286 retrieving revision 1.287 diff -u -r1.286 -r1.287 --- src/usr.bin/ssh/ssh-agent.c 2022/01/12 03:30:32 1.286 +++ src/usr.bin/ssh/ssh-agent.c 2022/01/14 03:43:48 1.287 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.286 2022/01/12 03:30:32 dtucker Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.287 2022/01/14 03:43:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -711,8 +711,9 @@ u_char *signature = NULL; size_t slen = 0; u_int compat = 0, flags; - int r, ok = -1; - char *fp = NULL, *user = NULL, *sig_dest = NULL; + int r, ok = -1, retried = 0; + char *fp = NULL, *pin = NULL, *prompt = NULL; + char *user = NULL, *sig_dest = NULL; const char *fwd_host = NULL, *dest_host = NULL; struct sshbuf *msg = NULL, *data = NULL, *sid = NULL; struct sshkey *key = NULL, *hostkey = NULL; @@ -799,7 +800,16 @@ /* error already logged */ goto send; } - if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { + if ((id->key->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) { + /* XXX include sig_dest */ + xasprintf(&prompt, "Enter PIN%sfor %s key %s: ", + (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) ? + " and confirm user presence " : " ", + sshkey_type(id->key), fp); + pin = read_passphrase(prompt, RP_USE_ASKPASS); + free(prompt); + prompt = NULL; + } else if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { notifier = notify_start(0, "Confirm user presence for key %s %s%s%s", sshkey_type(id->key), fp, @@ -807,10 +817,26 @@ sig_dest == NULL ? "" : sig_dest); } } - /* XXX support PIN required FIDO keys */ + retry_pin: if ((r = sshkey_sign(id->key, &signature, &slen, sshbuf_ptr(data), sshbuf_len(data), agent_decode_alg(key, flags), - id->sk_provider, NULL, compat)) != 0) { + id->sk_provider, pin, compat)) != 0) { + debug_fr(r, "sshkey_sign"); + if (pin == NULL && !retried && sshkey_is_sk(id->key) && + r == SSH_ERR_KEY_WRONG_PASSPHRASE) { + if (notifier) { + notify_complete(notifier, NULL); + notifier = NULL; + } + /* XXX include sig_dest */ + xasprintf(&prompt, "Enter PIN%sfor %s key %s: ", + (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) ? + " and confirm user presence " : " ", + sshkey_type(id->key), fp); + pin = read_passphrase(prompt, RP_USE_ASKPASS); + retried = 1; + goto retry_pin; + } error_fr(r, "sshkey_sign"); goto send; } @@ -838,6 +864,9 @@ free(signature); free(sig_dest); free(user); + free(prompt); + if (pin != NULL) + freezero(pin, strlen(pin)); } /* shared */