diff options
Diffstat (limited to 'crypto/openssh/ssh-keygen.c')
-rw-r--r-- | crypto/openssh/ssh-keygen.c | 93 |
1 files changed, 62 insertions, 31 deletions
diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c index 03c444d..eae83a4 100644 --- a/crypto/openssh/ssh-keygen.c +++ b/crypto/openssh/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.230 2013/07/20 01:44:37 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.238 2013/12/06 13:39:49 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -150,6 +150,18 @@ char *key_type_name = NULL; /* Load key from this PKCS#11 provider */ char *pkcs11provider = NULL; +/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */ +int use_new_format = 0; + +/* Cipher for new-format private keys */ +char *new_format_cipher = NULL; + +/* + * Number of KDF rounds to derive new format keys / + * number of primality trials when screening moduli. + */ +int rounds = 0; + /* argv0 */ extern char *__progname; @@ -185,7 +197,7 @@ type_bits_valid(int type, u_int32_t *bitsp) } if (type == KEY_DSA && *bitsp != 1024) fatal("DSA keys must be 1024 bits"); - else if (type != KEY_ECDSA && *bitsp < 768) + else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) fatal("Key must at least be 768 bits"); else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1) fatal("Invalid ECDSA key length - valid lengths are " @@ -221,6 +233,10 @@ ask_filename(struct passwd *pw, const char *prompt) case KEY_RSA: name = _PATH_SSH_CLIENT_ID_RSA; break; + case KEY_ED25519: + case KEY_ED25519_CERT: + name = _PATH_SSH_CLIENT_ID_ED25519; + break; default: fprintf(stderr, "bad key type\n"); exit(1); @@ -884,6 +900,7 @@ do_gen_all_hostkeys(struct passwd *pw) #ifdef OPENSSL_HAS_ECC { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE }, #endif + { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE }, { NULL, NULL, NULL } }; @@ -910,7 +927,6 @@ do_gen_all_hostkeys(struct passwd *pw) } printf("%s ", key_types[i].key_type_display); fflush(stdout); - arc4random_stir(); type = key_type_from_name(key_types[i].key_type); strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); bits = 0; @@ -924,7 +940,8 @@ do_gen_all_hostkeys(struct passwd *pw) public = key_from_private(private); snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); - if (!key_save_private(private, identity_file, "", comment)) { + if (!key_save_private(private, identity_file, "", comment, + use_new_format, new_format_cipher, rounds)) { printf("Saving the key failed: %s.\n", identity_file); key_free(private); key_free(public); @@ -932,7 +949,6 @@ do_gen_all_hostkeys(struct passwd *pw) continue; } key_free(private); - arc4random_stir(); strlcat(identity_file, ".pub", sizeof(identity_file)); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { @@ -1001,6 +1017,7 @@ do_known_hosts(struct passwd *pw, const char *name) char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; int ca; + int found_key = 0; if (!have_identity) { cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); @@ -1103,11 +1120,13 @@ do_known_hosts(struct passwd *pw, const char *name) } c = (strcmp(cp2, cp) == 0); if (find_host && c) { - printf("# Host %s found: " - "line %d type %s%s\n", name, - num, key_type(pub), - ca ? " (CA key)" : ""); + if (!quiet) + printf("# Host %s found: " + "line %d type %s%s\n", name, + num, key_type(pub), + ca ? " (CA key)" : ""); printhost(out, cp, pub, ca, 0); + found_key = 1; } if (delete_host) { if (!c && !ca) @@ -1124,12 +1143,14 @@ do_known_hosts(struct passwd *pw, const char *name) c = (match_hostname(name, cp, strlen(cp)) == 1); if (find_host && c) { - printf("# Host %s found: " - "line %d type %s%s\n", name, - num, key_type(pub), - ca ? " (CA key)" : ""); + if (!quiet) + printf("# Host %s found: " + "line %d type %s%s\n", name, + num, key_type(pub), + ca ? " (CA key)" : ""); printhost(out, name, pub, ca, hash_hosts && !ca); + found_key = 1; } if (delete_host) { if (!c && !ca) @@ -1205,7 +1226,7 @@ do_known_hosts(struct passwd *pw, const char *name) } } - exit(0); + exit (find_host && !found_key); } /* @@ -1272,7 +1293,8 @@ do_change_passphrase(struct passwd *pw) } /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase1, comment)) { + if (!key_save_private(private, identity_file, passphrase1, comment, + use_new_format, new_format_cipher, rounds)) { printf("Saving the key failed: %s.\n", identity_file); memset(passphrase1, 0, strlen(passphrase1)); free(passphrase1); @@ -1382,7 +1404,8 @@ do_change_comment(struct passwd *pw) } /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase, new_comment)) { + if (!key_save_private(private, identity_file, passphrase, new_comment, + use_new_format, new_format_cipher, rounds)) { printf("Saving the key failed: %s.\n", identity_file); memset(passphrase, 0, strlen(passphrase)); free(passphrase); @@ -1593,7 +1616,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) if ((public = key_load_public(tmp, &comment)) == NULL) fatal("%s: unable to open \"%s\"", __func__, tmp); if (public->type != KEY_RSA && public->type != KEY_DSA && - public->type != KEY_ECDSA) + public->type != KEY_ECDSA && public->type != KEY_ED25519) fatal("%s: key \"%s\" type %s cannot be certified", __func__, tmp, key_type(public)); @@ -1738,7 +1761,7 @@ parse_cert_times(char *timespec) cert_valid_from = parse_absolute_time(from); if (*to == '-' || *to == '+') - cert_valid_to = parse_relative_time(to, cert_valid_from); + cert_valid_to = parse_relative_time(to, now); else cert_valid_to = parse_absolute_time(to); @@ -1963,7 +1986,7 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, continue; if (strncasecmp(cp, "serial:", 7) == 0) { if (ca == NULL) { - fatal("revoking certificated by serial number " + fatal("revoking certificates by serial number " "requires specification of a CA key"); } cp += 7; @@ -2000,7 +2023,7 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, } } else if (strncasecmp(cp, "id:", 3) == 0) { if (ca == NULL) { - fatal("revoking certificated by key ID " + fatal("revoking certificates by key ID " "requires specification of a CA key"); } cp += 3; @@ -2129,7 +2152,7 @@ usage(void) fprintf(stderr, "usage: %s [options]\n", __progname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -A Generate non-existent host keys for all key types.\n"); - fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n"); + fprintf(stderr, " -a number Number of KDF rounds for new key format or moduli primality tests.\n"); fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); fprintf(stderr, " -b bits Number of bits in the key to create.\n"); fprintf(stderr, " -C comment Provide new comment.\n"); @@ -2157,6 +2180,7 @@ usage(void) fprintf(stderr, " -N phrase Provide new passphrase.\n"); fprintf(stderr, " -n name,... User/host principal names to include in certificate\n"); fprintf(stderr, " -O option Specify a certificate option.\n"); + fprintf(stderr, " -o Enforce new private key format.\n"); fprintf(stderr, " -P phrase Provide old passphrase.\n"); fprintf(stderr, " -p Change passphrase of private key file.\n"); fprintf(stderr, " -Q Test whether key(s) are revoked in KRL.\n"); @@ -2173,6 +2197,7 @@ usage(void) fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); fprintf(stderr, " -y Read private key file and print public key.\n"); fprintf(stderr, " -z serial Specify a serial number.\n"); + fprintf(stderr, " -Z cipher Specify a cipher for new private key format.\n"); exit(1); } @@ -2190,7 +2215,7 @@ main(int argc, char **argv) struct passwd *pw; struct stat st; int opt, type, fd; - u_int32_t memory = 0, generator_wanted = 0, trials = 100; + u_int32_t memory = 0, generator_wanted = 0; int do_gen_candidates = 0, do_screen_candidates = 0; int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; unsigned long start_lineno = 0, lines_to_process = 0; @@ -2222,8 +2247,9 @@ main(int argc, char **argv) exit(1); } - while ((opt = getopt(argc, argv, "ABHLQXceghiklpquvxy" - "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { + /* Remaining characters: EUYdw */ + while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" + "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { switch (opt) { case 'A': gen_all_hostkeys = 1; @@ -2281,6 +2307,9 @@ main(int argc, char **argv) case 'n': cert_principals = optarg; break; + case 'o': + use_new_format = 1; + break; case 'p': change_passphrase = 1; break; @@ -2308,6 +2337,9 @@ main(int argc, char **argv) case 'O': add_cert_option(optarg); break; + case 'Z': + new_format_cipher = optarg; + break; case 'C': identity_comment = optarg; break; @@ -2366,9 +2398,9 @@ main(int argc, char **argv) optarg, errstr); break; case 'a': - trials = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); + rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr); if (errstr) - fatal("Invalid number of trials: %s (%s)", + fatal("Invalid number: %s (%s)", optarg, errstr); break; case 'M': @@ -2527,7 +2559,8 @@ main(int argc, char **argv) fatal("Couldn't open moduli file \"%s\": %s", out_file, strerror(errno)); } - if (prime_test(in, out, trials, generator_wanted, checkpoint, + if (prime_test(in, out, rounds == 0 ? 100 : rounds, + generator_wanted, checkpoint, start_lineno, lines_to_process) != 0) fatal("modulus screening failed"); return (0); @@ -2538,8 +2571,6 @@ main(int argc, char **argv) return (0); } - arc4random_stir(); - if (key_type_name == NULL) key_type_name = "rsa"; @@ -2621,7 +2652,8 @@ passphrase_again: } /* Save the key with the given passphrase and comment. */ - if (!key_save_private(private, identity_file, passphrase1, comment)) { + if (!key_save_private(private, identity_file, passphrase1, comment, + use_new_format, new_format_cipher, rounds)) { printf("Saving the key failed: %s.\n", identity_file); memset(passphrase1, 0, strlen(passphrase1)); free(passphrase1); @@ -2633,7 +2665,6 @@ passphrase_again: /* Clear the private key and the random number generator. */ key_free(private); - arc4random_stir(); if (!quiet) printf("Your identification has been saved in %s.\n", identity_file); |