summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-10-31 21:17:09 +0000
committerDamien Miller <djm@mindrot.org>2019-11-01 09:46:09 +1100
commit23f38c2d8cda3fad24e214e1f0133c42435b54ee (patch)
treebd3b15641dc4b3f364ae6c1721b670c8d79c7ef7 /ssh-keygen.c
parented3467c1e16b7396ff7fcf12d2769261512935ec (diff)
upstream: ssh-keygen support for generating U2F/FIDO keys
OpenBSD-Commit-ID: 6ce04f2b497ac9dd8c327f76f1e6c724fb1d1b37
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c41
1 files changed, 35 insertions, 6 deletions
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 @@
1/* $OpenBSD: ssh-keygen.c,v 1.356 2019/10/16 06:03:30 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.357 2019/10/31 21:17:09 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
@@ -63,6 +63,8 @@
63#include "utf8.h" 63#include "utf8.h"
64#include "authfd.h" 64#include "authfd.h"
65#include "sshsig.h" 65#include "sshsig.h"
66#include "ssh-sk.h"
67#include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
66 68
67#ifdef WITH_OPENSSL 69#ifdef WITH_OPENSSL
68# define DEFAULT_KEY_TYPE_NAME "rsa" 70# define DEFAULT_KEY_TYPE_NAME "rsa"
@@ -150,6 +152,9 @@ static char *key_type_name = NULL;
150/* Load key from this PKCS#11 provider */ 152/* Load key from this PKCS#11 provider */
151static char *pkcs11provider = NULL; 153static char *pkcs11provider = NULL;
152 154
155/* FIDO/U2F provider to use */
156static char *sk_provider = NULL;
157
153/* Format for writing private keys */ 158/* Format for writing private keys */
154static int private_key_format = SSHKEY_PRIVATE_OPENSSH; 159static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
155 160
@@ -269,6 +274,10 @@ ask_filename(struct passwd *pw, const char *prompt)
269 case KEY_ECDSA: 274 case KEY_ECDSA:
270 name = _PATH_SSH_CLIENT_ID_ECDSA; 275 name = _PATH_SSH_CLIENT_ID_ECDSA;
271 break; 276 break;
277 case KEY_ECDSA_SK_CERT:
278 case KEY_ECDSA_SK:
279 name = _PATH_SSH_CLIENT_ID_ECDSA_SK;
280 break;
272#endif 281#endif
273 case KEY_RSA_CERT: 282 case KEY_RSA_CERT:
274 case KEY_RSA: 283 case KEY_RSA:
@@ -2767,9 +2776,10 @@ main(int argc, char **argv)
2767 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; 2776 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
2768 int prefer_agent = 0, convert_to = 0, convert_from = 0; 2777 int prefer_agent = 0, convert_to = 0, convert_from = 0;
2769 int print_public = 0, print_generic = 0, cert_serial_autoinc = 0; 2778 int print_public = 0, print_generic = 0, cert_serial_autoinc = 0;
2770 unsigned long long cert_serial = 0; 2779 unsigned long long ull, cert_serial = 0;
2771 char *identity_comment = NULL, *ca_key_path = NULL; 2780 char *identity_comment = NULL, *ca_key_path = NULL;
2772 u_int32_t bits = 0; 2781 u_int32_t bits = 0;
2782 uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
2773 FILE *f; 2783 FILE *f;
2774 const char *errstr; 2784 const char *errstr;
2775 int log_level = SYSLOG_LEVEL_INFO; 2785 int log_level = SYSLOG_LEVEL_INFO;
@@ -2804,10 +2814,12 @@ main(int argc, char **argv)
2804 if (gethostname(hostname, sizeof(hostname)) == -1) 2814 if (gethostname(hostname, sizeof(hostname)) == -1)
2805 fatal("gethostname: %s", strerror(errno)); 2815 fatal("gethostname: %s", strerror(errno));
2806 2816
2807 /* Remaining characters: dw */ 2817 sk_provider = getenv("SSH_SK_PROVIDER");
2818
2819 /* Remaining character: d */
2808 while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy" 2820 while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy"
2809 "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Y:Z:" 2821 "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Y:Z:"
2810 "a:b:f:g:j:m:n:r:s:t:z:")) != -1) { 2822 "a:b:f:g:j:m:n:r:s:t:w:x:z:")) != -1) {
2811 switch (opt) { 2823 switch (opt) {
2812 case 'A': 2824 case 'A':
2813 gen_all_hostkeys = 1; 2825 gen_all_hostkeys = 1;
@@ -2907,7 +2919,6 @@ main(int argc, char **argv)
2907 quiet = 1; 2919 quiet = 1;
2908 break; 2920 break;
2909 case 'e': 2921 case 'e':
2910 case 'x':
2911 /* export key */ 2922 /* export key */
2912 convert_to = 1; 2923 convert_to = 1;
2913 break; 2924 break;
@@ -2964,6 +2975,19 @@ main(int argc, char **argv)
2964 break; 2975 break;
2965 case 'Y': 2976 case 'Y':
2966 sign_op = optarg; 2977 sign_op = optarg;
2978 case 'w':
2979 sk_provider = optarg;
2980 break;
2981 case 'x':
2982 if (*optarg == '\0')
2983 fatal("Missing security key flags");
2984 ull = strtoull(optarg, &ep, 0);
2985 if (*ep != '\0')
2986 fatal("Security key flags \"%s\" is not a "
2987 "number", optarg);
2988 if (ull > 0xff)
2989 fatal("Invalid security key flags 0x%llx", ull);
2990 sk_flags = (uint8_t)ull;
2967 break; 2991 break;
2968 case 'z': 2992 case 'z':
2969 errno = 0; 2993 errno = 0;
@@ -3221,7 +3245,12 @@ main(int argc, char **argv)
3221 if (!quiet) 3245 if (!quiet)
3222 printf("Generating public/private %s key pair.\n", 3246 printf("Generating public/private %s key pair.\n",
3223 key_type_name); 3247 key_type_name);
3224 if ((r = sshkey_generate(type, bits, &private)) != 0) 3248 if (type == KEY_ECDSA_SK) {
3249 if (sshsk_enroll(sk_provider,
3250 cert_key_id == NULL ? "ssh:" : cert_key_id,
3251 sk_flags, NULL, &private, NULL) != 0)
3252 exit(1); /* error message already printed */
3253 } else if ((r = sshkey_generate(type, bits, &private)) != 0)
3225 fatal("sshkey_generate failed"); 3254 fatal("sshkey_generate failed");
3226 if ((r = sshkey_from_private(private, &public)) != 0) 3255 if ((r = sshkey_from_private(private, &public)) != 0)
3227 fatal("sshkey_from_private failed: %s\n", ssh_err(r)); 3256 fatal("sshkey_from_private failed: %s\n", ssh_err(r));