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 коммит произвёл Damien Miller
Родитель b649b3daa6
Коммит 0caff05350
2 изменённых файлов: 23 добавлений и 19 удалений

Просмотреть файл

@ -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,

Просмотреть файл

@ -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;
}