diff options
author | djm@openbsd.org <djm@openbsd.org> | 2020-01-06 02:00:46 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2020-01-06 13:12:46 +1100 |
commit | c312ca077cd2a6c15545cd6b4d34ee2f69289174 (patch) | |
tree | b8dd974c55dd0de351dfcbfc4f33fddb935a1c12 /ssh-keygen.c | |
parent | 2ab335712d084d9ccaf3f53afc3fa9535329da87 (diff) |
upstream: Extends the SK API to accept a set of key/value options
for all operations. These are intended to future-proof the API a little by
making it easier to specify additional fields for without having to change
the API version for each.
At present, only two options are defined: one to explicitly specify
the device for an operation (rather than accepting the middleware's
autoselection) and another to specify the FIDO2 username that may
be used when generating a resident key. These new options may be
invoked at key generation time via ssh-keygen -O
This also implements a suggestion from Markus to avoid "int" in favour
of uint32_t for the algorithm argument in the API, to make implementation
of ssh-sk-client/helper a little easier.
feedback, fixes and ok markus@
OpenBSD-Commit-ID: 973ce11704609022ab36abbdeb6bc23c8001eabc
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r-- | ssh-keygen.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c index 7731339f..d0ffa5cd 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.381 2020/01/02 22:40:09 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.382 2020/01/06 02:00:46 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -2915,7 +2915,7 @@ skip_ssh_url_preamble(const char *s) } static int -do_download_sk(const char *skprovider) +do_download_sk(const char *skprovider, const char *device) { struct sshkey **keys; size_t nkeys, i; @@ -2927,7 +2927,8 @@ do_download_sk(const char *skprovider) fatal("Cannot download keys without provider"); pin = read_passphrase("Enter PIN for security key: ", RP_ALLOW_STDIN); - if ((r = sshsk_load_resident(skprovider, pin, &keys, &nkeys)) != 0) { + if ((r = sshsk_load_resident(skprovider, device, pin, + &keys, &nkeys)) != 0) { freezero(pin, strlen(pin)); error("Unable to load resident keys: %s", ssh_err(r)); return -1; @@ -3067,6 +3068,7 @@ main(int argc, char **argv) int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0; unsigned long long cert_serial = 0; char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL; + char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL; size_t i, nopts = 0; u_int32_t bits = 0; uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD; @@ -3396,8 +3398,17 @@ main(int argc, char **argv) } if (pkcs11provider != NULL) do_download(pw); - if (download_sk) - return do_download_sk(sk_provider); + if (download_sk) { + for (i = 0; i < nopts; i++) { + if (strncasecmp(opts[i], "device=", 7) == 0) { + sk_device = xstrdup(opts[i] + 7); + } else { + fatal("Option \"%s\" is unsupported for " + "FIDO authenticator download", opts[i]); + } + } + return do_download_sk(sk_provider, sk_device); + } if (print_fingerprint || print_bubblebabble) do_fingerprint(pw); if (change_passphrase) @@ -3484,6 +3495,13 @@ main(int argc, char **argv) sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; } else if (strcasecmp(opts[i], "resident") == 0) { sk_flags |= SSH_SK_RESIDENT_KEY; + } else if (strncasecmp(opts[i], "device=", 7) == 0) { + sk_device = xstrdup(opts[i] + 7); + } else if (strncasecmp(opts[i], "user=", 5) == 0) { + sk_user = xstrdup(opts[i] + 5); + } else if (strncasecmp(opts[i], + "application=", 12) == 0) { + sk_application = xstrdup(opts[i] + 12); } else { fatal("Option \"%s\" is unsupported for " "FIDO authenticator enrollment", opts[i]); @@ -3495,14 +3513,11 @@ main(int argc, char **argv) } passphrase = NULL; for (i = 0 ; i < 3; i++) { - if (!quiet) { - printf("You may need to touch your security " - "key to authorize key generation.\n"); - } fflush(stdout); - r = sshsk_enroll(type, sk_provider, - cert_key_id == NULL ? "ssh:" : cert_key_id, - sk_flags, passphrase, NULL, &private, NULL); + r = sshsk_enroll(type, sk_provider, sk_device, + sk_application == NULL ? "ssh:" : sk_application, + sk_user, sk_flags, passphrase, NULL, + &private, NULL); if (r == 0) break; if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) |