From 0caff05350bd5fc635674c9e051a0322faba5ae3 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Thu, 27 Aug 2020 01:08:45 +0000 Subject: [PATCH] upstream: Request PIN ahead of time for certain FIDO actions When we know that a particular action will require a PIN, such as downloading resident keys or generating a verify-required key, request the PIN before attempting it. joint work with Pedro Martelletto; ok markus@ OpenBSD-Commit-ID: 863182d38ef075bad1f7d20ca485752a05edb727 --- ssh-keygen.1 | 4 +++- ssh-keygen.c | 38 ++++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 7e0558fe1..e18fcde01 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.206 2020/08/27 01:06:18 djm Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.207 2020/08/27 01:08:45 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -382,6 +382,8 @@ The default import format is Download resident keys from a FIDO authenticator. Public and private key files will be written to the current directory for each downloaded key. +If multiple FIDO authenticators are attached, keys will be downloaded from +the first touched authenticator. .It Fl k Generate a KRL file. In this mode, diff --git a/ssh-keygen.c b/ssh-keygen.c index 1d6234c1c..664724276 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.417 2020/08/27 01:07:51 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.418 2020/08/27 01:08:45 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -2984,20 +2984,17 @@ do_download_sk(const char *skprovider, const char *device) if (skprovider == NULL) fatal("Cannot download keys without provider"); - for (i = 0; i < 2; i++) { - if (i == 1) { - pin = read_passphrase("Enter PIN for authenticator: ", - RP_ALLOW_STDIN); - } - if ((r = sshsk_load_resident(skprovider, device, pin, - &keys, &nkeys)) != 0) { - if (i == 0 && r == SSH_ERR_KEY_WRONG_PASSPHRASE) - continue; - if (pin != NULL) - freezero(pin, strlen(pin)); - error("Unable to load resident keys: %s", ssh_err(r)); - return -1; - } + pin = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN); + if (!quiet) { + printf("You may need to touch your authenticator " + "to authorize key download.\n"); + } + if ((r = sshsk_load_resident(skprovider, device, pin, + &keys, &nkeys)) != 0) { + if (pin != NULL) + freezero(pin, strlen(pin)); + error("Unable to load resident keys: %s", ssh_err(r)); + return -1; } if (nkeys == 0) logit("No keys to download"); @@ -3609,9 +3606,15 @@ main(int argc, char **argv) printf("You may need to touch your authenticator " "to authorize key generation.\n"); } - passphrase = NULL; if ((attest = sshbuf_new()) == NULL) fatal("sshbuf_new failed"); + if ((sk_flags & + (SSH_SK_USER_VERIFICATION_REQD|SSH_SK_RESIDENT_KEY))) { + passphrase = read_passphrase("Enter PIN for " + "authenticator: ", RP_ALLOW_STDIN); + } else { + passphrase = NULL; + } for (i = 0 ; ; i++) { fflush(stdout); r = sshsk_enroll(type, sk_provider, sk_device, @@ -3622,9 +3625,8 @@ main(int argc, char **argv) break; if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) fatal("Key enrollment failed: %s", ssh_err(r)); - else if (i > 0) + else if (passphrase != NULL) { error("PIN incorrect"); - if (passphrase != NULL) { freezero(passphrase, strlen(passphrase)); passphrase = NULL; }