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 7731339f7..d0ffa5cd7 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.381 2020/01/02 22:40:09 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.382 2020/01/06 02:00:46 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -2915,7 +2915,7 @@ skip_ssh_url_preamble(const char *s) | |||
2915 | } | 2915 | } |
2916 | 2916 | ||
2917 | static int | 2917 | static int |
2918 | do_download_sk(const char *skprovider) | 2918 | do_download_sk(const char *skprovider, const char *device) |
2919 | { | 2919 | { |
2920 | struct sshkey **keys; | 2920 | struct sshkey **keys; |
2921 | size_t nkeys, i; | 2921 | size_t nkeys, i; |
@@ -2927,7 +2927,8 @@ do_download_sk(const char *skprovider) | |||
2927 | fatal("Cannot download keys without provider"); | 2927 | fatal("Cannot download keys without provider"); |
2928 | 2928 | ||
2929 | pin = read_passphrase("Enter PIN for security key: ", RP_ALLOW_STDIN); | 2929 | pin = read_passphrase("Enter PIN for security key: ", RP_ALLOW_STDIN); |
2930 | if ((r = sshsk_load_resident(skprovider, pin, &keys, &nkeys)) != 0) { | 2930 | if ((r = sshsk_load_resident(skprovider, device, pin, |
2931 | &keys, &nkeys)) != 0) { | ||
2931 | freezero(pin, strlen(pin)); | 2932 | freezero(pin, strlen(pin)); |
2932 | error("Unable to load resident keys: %s", ssh_err(r)); | 2933 | error("Unable to load resident keys: %s", ssh_err(r)); |
2933 | return -1; | 2934 | return -1; |
@@ -3067,6 +3068,7 @@ main(int argc, char **argv) | |||
3067 | int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0; | 3068 | int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0; |
3068 | unsigned long long cert_serial = 0; | 3069 | unsigned long long cert_serial = 0; |
3069 | char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL; | 3070 | char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL; |
3071 | char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL; | ||
3070 | size_t i, nopts = 0; | 3072 | size_t i, nopts = 0; |
3071 | u_int32_t bits = 0; | 3073 | u_int32_t bits = 0; |
3072 | uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD; | 3074 | uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD; |
@@ -3396,8 +3398,17 @@ main(int argc, char **argv) | |||
3396 | } | 3398 | } |
3397 | if (pkcs11provider != NULL) | 3399 | if (pkcs11provider != NULL) |
3398 | do_download(pw); | 3400 | do_download(pw); |
3399 | if (download_sk) | 3401 | if (download_sk) { |
3400 | return do_download_sk(sk_provider); | 3402 | for (i = 0; i < nopts; i++) { |
3403 | if (strncasecmp(opts[i], "device=", 7) == 0) { | ||
3404 | sk_device = xstrdup(opts[i] + 7); | ||
3405 | } else { | ||
3406 | fatal("Option \"%s\" is unsupported for " | ||
3407 | "FIDO authenticator download", opts[i]); | ||
3408 | } | ||
3409 | } | ||
3410 | return do_download_sk(sk_provider, sk_device); | ||
3411 | } | ||
3401 | if (print_fingerprint || print_bubblebabble) | 3412 | if (print_fingerprint || print_bubblebabble) |
3402 | do_fingerprint(pw); | 3413 | do_fingerprint(pw); |
3403 | if (change_passphrase) | 3414 | if (change_passphrase) |
@@ -3484,6 +3495,13 @@ main(int argc, char **argv) | |||
3484 | sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; | 3495 | sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; |
3485 | } else if (strcasecmp(opts[i], "resident") == 0) { | 3496 | } else if (strcasecmp(opts[i], "resident") == 0) { |
3486 | sk_flags |= SSH_SK_RESIDENT_KEY; | 3497 | sk_flags |= SSH_SK_RESIDENT_KEY; |
3498 | } else if (strncasecmp(opts[i], "device=", 7) == 0) { | ||
3499 | sk_device = xstrdup(opts[i] + 7); | ||
3500 | } else if (strncasecmp(opts[i], "user=", 5) == 0) { | ||
3501 | sk_user = xstrdup(opts[i] + 5); | ||
3502 | } else if (strncasecmp(opts[i], | ||
3503 | "application=", 12) == 0) { | ||
3504 | sk_application = xstrdup(opts[i] + 12); | ||
3487 | } else { | 3505 | } else { |
3488 | fatal("Option \"%s\" is unsupported for " | 3506 | fatal("Option \"%s\" is unsupported for " |
3489 | "FIDO authenticator enrollment", opts[i]); | 3507 | "FIDO authenticator enrollment", opts[i]); |
@@ -3495,14 +3513,11 @@ main(int argc, char **argv) | |||
3495 | } | 3513 | } |
3496 | passphrase = NULL; | 3514 | passphrase = NULL; |
3497 | for (i = 0 ; i < 3; i++) { | 3515 | for (i = 0 ; i < 3; i++) { |
3498 | if (!quiet) { | ||
3499 | printf("You may need to touch your security " | ||
3500 | "key to authorize key generation.\n"); | ||
3501 | } | ||
3502 | fflush(stdout); | 3516 | fflush(stdout); |
3503 | r = sshsk_enroll(type, sk_provider, | 3517 | r = sshsk_enroll(type, sk_provider, sk_device, |
3504 | cert_key_id == NULL ? "ssh:" : cert_key_id, | 3518 | sk_application == NULL ? "ssh:" : sk_application, |
3505 | sk_flags, passphrase, NULL, &private, NULL); | 3519 | sk_user, sk_flags, passphrase, NULL, |
3520 | &private, NULL); | ||
3506 | if (r == 0) | 3521 | if (r == 0) |
3507 | break; | 3522 | break; |
3508 | if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) | 3523 | if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) |