summaryrefslogtreecommitdiffstats
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-01-06 02:00:46 +0000
committerDamien Miller <djm@mindrot.org>2020-01-06 13:12:46 +1100
commitc312ca077cd2a6c15545cd6b4d34ee2f69289174 (patch)
treeb8dd974c55dd0de351dfcbfc4f33fddb935a1c12 /ssh-keygen.c
parent2ab335712d084d9ccaf3f53afc3fa9535329da87 (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.c39
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)