From 23f38c2d8cda3fad24e214e1f0133c42435b54ee Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Thu, 31 Oct 2019 21:17:09 +0000 Subject: upstream: ssh-keygen support for generating U2F/FIDO keys OpenBSD-Commit-ID: 6ce04f2b497ac9dd8c327f76f1e6c724fb1d1b37 --- ssh-keygen.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 27ccc15df..ad7a2b4e0 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.356 2019/10/16 06:03:30 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.357 2019/10/31 21:17:09 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -63,6 +63,8 @@ #include "utf8.h" #include "authfd.h" #include "sshsig.h" +#include "ssh-sk.h" +#include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */ #ifdef WITH_OPENSSL # define DEFAULT_KEY_TYPE_NAME "rsa" @@ -150,6 +152,9 @@ static char *key_type_name = NULL; /* Load key from this PKCS#11 provider */ static char *pkcs11provider = NULL; +/* FIDO/U2F provider to use */ +static char *sk_provider = NULL; + /* Format for writing private keys */ static int private_key_format = SSHKEY_PRIVATE_OPENSSH; @@ -269,6 +274,10 @@ ask_filename(struct passwd *pw, const char *prompt) case KEY_ECDSA: name = _PATH_SSH_CLIENT_ID_ECDSA; break; + case KEY_ECDSA_SK_CERT: + case KEY_ECDSA_SK: + name = _PATH_SSH_CLIENT_ID_ECDSA_SK; + break; #endif case KEY_RSA_CERT: case KEY_RSA: @@ -2767,9 +2776,10 @@ main(int argc, char **argv) int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; int prefer_agent = 0, convert_to = 0, convert_from = 0; int print_public = 0, print_generic = 0, cert_serial_autoinc = 0; - unsigned long long cert_serial = 0; + unsigned long long ull, cert_serial = 0; char *identity_comment = NULL, *ca_key_path = NULL; u_int32_t bits = 0; + uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD; FILE *f; const char *errstr; int log_level = SYSLOG_LEVEL_INFO; @@ -2804,10 +2814,12 @@ main(int argc, char **argv) if (gethostname(hostname, sizeof(hostname)) == -1) fatal("gethostname: %s", strerror(errno)); - /* Remaining characters: dw */ + sk_provider = getenv("SSH_SK_PROVIDER"); + + /* Remaining character: d */ while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy" "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Y:Z:" - "a:b:f:g:j:m:n:r:s:t:z:")) != -1) { + "a:b:f:g:j:m:n:r:s:t:w:x:z:")) != -1) { switch (opt) { case 'A': gen_all_hostkeys = 1; @@ -2907,7 +2919,6 @@ main(int argc, char **argv) quiet = 1; break; case 'e': - case 'x': /* export key */ convert_to = 1; break; @@ -2964,6 +2975,19 @@ main(int argc, char **argv) break; case 'Y': sign_op = optarg; + case 'w': + sk_provider = optarg; + break; + case 'x': + if (*optarg == '\0') + fatal("Missing security key flags"); + ull = strtoull(optarg, &ep, 0); + if (*ep != '\0') + fatal("Security key flags \"%s\" is not a " + "number", optarg); + if (ull > 0xff) + fatal("Invalid security key flags 0x%llx", ull); + sk_flags = (uint8_t)ull; break; case 'z': errno = 0; @@ -3221,7 +3245,12 @@ main(int argc, char **argv) if (!quiet) printf("Generating public/private %s key pair.\n", key_type_name); - if ((r = sshkey_generate(type, bits, &private)) != 0) + if (type == KEY_ECDSA_SK) { + if (sshsk_enroll(sk_provider, + cert_key_id == NULL ? "ssh:" : cert_key_id, + sk_flags, NULL, &private, NULL) != 0) + exit(1); /* error message already printed */ + } else if ((r = sshkey_generate(type, bits, &private)) != 0) fatal("sshkey_generate failed"); if ((r = sshkey_from_private(private, &public)) != 0) fatal("sshkey_from_private failed: %s\n", ssh_err(r)); -- cgit v1.2.3