diff options
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r-- | ssh-keygen.c | 41 |
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 */ |
151 | static char *pkcs11provider = NULL; | 153 | static char *pkcs11provider = NULL; |
152 | 154 | ||
155 | /* FIDO/U2F provider to use */ | ||
156 | static char *sk_provider = NULL; | ||
157 | |||
153 | /* Format for writing private keys */ | 158 | /* Format for writing private keys */ |
154 | static int private_key_format = SSHKEY_PRIVATE_OPENSSH; | 159 | static 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)); |