summaryrefslogtreecommitdiff
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 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
2917static int 2917static int
2918do_download_sk(const char *skprovider) 2918do_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)