From f361212a68303e42955f1fd84c8dafb122523bf3 Mon Sep 17 00:00:00 2001 From: djm Date: Fri, 14 Jan 2022 03:43:48 +0000 Subject: [PATCH] allow pin-required FIDO keys to be added to ssh-agent(1). ssh-askpass will be used to request the PIN at authentication time. From Pedro Martelletto, ok djm --- usr.bin/ssh/ssh-add.c | 7 +------ usr.bin/ssh/ssh-agent.c | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/usr.bin/ssh/ssh-add.c b/usr.bin/ssh/ssh-add.c index 50790d2a014..ceefa749618 100644 --- a/usr.bin/ssh/ssh-add.c +++ b/usr.bin/ssh/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.163 2021/12/22 06:56:41 jmc Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.164 2022/01/14 03:43:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -349,11 +349,6 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag, "without provider\n", filename); goto out; } - if ((private->sk_flags & SSH_SK_USER_VERIFICATION_REQD) != 0) { - fprintf(stderr, "FIDO verify-required key %s is not " - "currently supported by ssh-agent\n", filename); - goto out; - } } else { /* Don't send provider constraint for other keys */ skprovider = NULL; diff --git a/usr.bin/ssh/ssh-agent.c b/usr.bin/ssh/ssh-agent.c index c459dbec79e..83a162d4978 100644 --- a/usr.bin/ssh/ssh-agent.c +++ b/usr.bin/ssh/ssh-agent.c @@ -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 @@ process_sign_request2(SocketEntry *e) 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 @@ process_sign_request2(SocketEntry *e) /* 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 @@ process_sign_request2(SocketEntry *e) 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 @@ process_sign_request2(SocketEntry *e) free(signature); free(sig_dest); free(user); + free(prompt); + if (pin != NULL) + freezero(pin, strlen(pin)); } /* shared */ -- 2.20.1