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
This commit is contained in:
djm@openbsd.org 2020-08-27 01:08:45 +00:00 committed by Damien Miller
parent b649b3daa6
commit 0caff05350
2 changed files with 23 additions and 19 deletions

View File

@ -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 <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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,

View File

@ -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 <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, 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;
}