=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-keygen.c,v retrieving revision 1.290 retrieving revision 1.302 diff -u -r1.290 -r1.302 --- src/usr.bin/ssh/ssh-keygen.c 2016/05/02 09:36:42 1.290 +++ src/usr.bin/ssh/ssh-keygen.c 2017/04/30 23:18:44 1.302 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.290 2016/05/02 09:36:42 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.302 2017/04/30 23:18:44 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -28,6 +28,7 @@ #include #include #include +#include #include "xmalloc.h" #include "sshkey.h" @@ -47,6 +48,7 @@ #include "atomicio.h" #include "krl.h" #include "digest.h" +#include "utf8.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" @@ -141,6 +143,15 @@ char *certflags_command = NULL; char *certflags_src_addr = NULL; +/* Arbitrary extensions specified by user */ +struct cert_userext { + char *key; + char *val; + int crit; +}; +struct cert_userext *cert_userext; +size_t ncert_userext; + /* Conversion to/from various formats */ int convert_to = 0; int convert_from = 0; @@ -200,8 +211,7 @@ *bitsp = sshkey_curve_nid_to_bits(nid); if (*bitsp == 0) *bitsp = DEFAULT_BITS_ECDSA; - } - else + } else #endif *bitsp = DEFAULT_BITS; } @@ -230,9 +240,6 @@ name = _PATH_SSH_CLIENT_ID_RSA; else { switch (sshkey_type_from_name(key_type_name)) { - case KEY_RSA1: - name = _PATH_SSH_CLIENT_IDENTITY; - break; case KEY_DSA_CERT: case KEY_DSA: name = _PATH_SSH_CLIENT_ID_DSA; @@ -302,8 +309,6 @@ char comment[61]; int r; - if (k->type == KEY_RSA1) - fatal("version 1 keys are not supported"); if ((r = sshkey_to_blob(k, &blob, &len)) != 0) fatal("key_to_blob failed: %s", ssh_err(r)); /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ @@ -325,7 +330,6 @@ do_convert_to_pkcs8(struct sshkey *k) { switch (sshkey_type_plain(k->type)) { - case KEY_RSA1: case KEY_RSA: if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) fatal("PEM_write_RSA_PUBKEY failed"); @@ -348,7 +352,6 @@ do_convert_to_pem(struct sshkey *k) { switch (sshkey_type_plain(k->type)) { - case KEY_RSA1: case KEY_RSA: if (!PEM_write_RSAPublicKey(stdout, k->rsa)) fatal("PEM_write_RSAPublicKey failed"); @@ -801,13 +804,6 @@ struct sshkey *ret; int r; - if ((ret = sshkey_new(KEY_RSA1)) == NULL) - fatal("sshkey_new failed"); - /* Try RSA1 */ - if ((r = sshkey_read(ret, cpp)) == 0) - return ret; - /* Try modern */ - sshkey_free(ret); if ((ret = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); if ((r = sshkey_read(ret, cpp)) == 0) @@ -830,7 +826,7 @@ ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint failed", __func__); - printf("%u %s %s (%s)\n", sshkey_size(public), fp, + mprintf("%u %s %s (%s)\n", sshkey_size(public), fp, comment ? comment : "no comment", sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); @@ -963,9 +959,6 @@ char *path; } key_types[] = { #ifdef WITH_OPENSSL -#ifdef WITH_SSH1 - { "rsa1", "RSA1", _PATH_HOST_KEY_FILE }, -#endif /* WITH_SSH1 */ { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE }, { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE }, { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE }, @@ -1067,6 +1060,7 @@ struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; char *hashed, *cp, *hosts, *ohosts; int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts); + int was_hashed = l->hosts && l->hosts[0] == HASH_DELIM; switch (l->status) { case HKF_STATUS_OK: @@ -1075,11 +1069,10 @@ * Don't hash hosts already already hashed, with wildcard * characters or a CA/revocation marker. */ - if ((l->match & HKF_MATCH_HOST_HASHED) != 0 || - has_wild || l->marker != MRK_NONE) { + if (was_hashed || has_wild || l->marker != MRK_NONE) { fprintf(ctx->out, "%s\n", l->line); if (has_wild && !find_host) { - logit("%s:%ld: ignoring host name " + logit("%s:%lu: ignoring host name " "with wildcard: %.64s", l->path, l->linenum, l->hosts); } @@ -1091,6 +1084,7 @@ */ ohosts = hosts = xstrdup(l->hosts); while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') { + lowercase(cp); if ((hashed = host_hash(cp, NULL, 0)) == NULL) fatal("hash_host failed"); fprintf(ctx->out, "%s %s\n", hashed, l->rawkey); @@ -1101,7 +1095,7 @@ case HKF_STATUS_INVALID: /* Retain invalid lines, but mark file as invalid. */ ctx->invalid = 1; - logit("%s:%ld: invalid line", l->path, l->linenum); + logit("%s:%lu: invalid line", l->path, l->linenum); /* FALLTHROUGH */ default: fprintf(ctx->out, "%s\n", l->line); @@ -1135,14 +1129,14 @@ */ ctx->found_key = 1; if (!quiet) - printf("# Host %s found: line %ld\n", + printf("# Host %s found: line %lu\n", ctx->host, l->linenum); } return 0; } else if (find_host) { ctx->found_key = 1; if (!quiet) { - printf("# Host %s found: line %ld %s\n", + printf("# Host %s found: line %lu %s\n", ctx->host, l->linenum, l->marker == MRK_CA ? "CA" : (l->marker == MRK_REVOKE ? "REVOKED" : "")); @@ -1151,7 +1145,7 @@ known_hosts_hash(l, ctx); else if (print_fingerprint) { fp = sshkey_fingerprint(l->key, fptype, rep); - printf("%s %s %s %s\n", ctx->host, + mprintf("%s %s %s %s\n", ctx->host, sshkey_type(l->key), fp, l->comment); free(fp); } else @@ -1162,7 +1156,7 @@ /* Retain non-matching hosts when deleting */ if (l->status == HKF_STATUS_INVALID) { ctx->invalid = 1; - logit("%s:%ld: invalid line", l->path, l->linenum); + logit("%s:%lu: invalid line", l->path, l->linenum); } fprintf(ctx->out, "%s\n", l->line); } @@ -1302,7 +1296,7 @@ fatal("Failed to load key %s: %s", identity_file, ssh_err(r)); } if (comment) - printf("Key has comment '%s'\n", comment); + mprintf("Key has comment '%s'\n", comment); /* Ask the new passphrase (twice). */ if (identity_new_passphrase) { @@ -1418,15 +1412,17 @@ } } - if (private->type != KEY_RSA1 && private->type != KEY_ED25519 && - !use_new_format) { - error("Comments are only supported for RSA1 or keys stored in " + if (private->type != KEY_ED25519 && !use_new_format) { + error("Comments are only supported for keys stored in " "the new format (-o)."); explicit_bzero(passphrase, strlen(passphrase)); sshkey_free(private); exit(1); } - printf("Key now has comment '%s'\n", comment); + if (comment) + printf("Key now has comment '%s'\n", comment); + else + printf("Key now has no comment\n"); if (identity_comment) { strlcpy(new_comment, identity_comment, sizeof(new_comment)); @@ -1510,6 +1506,8 @@ static void prepare_options_buf(struct sshbuf *c, int which) { + size_t i; + sshbuf_reset(c); if ((which & OPTIONS_CRITICAL) != 0 && certflags_command != NULL) @@ -1532,6 +1530,17 @@ if ((which & OPTIONS_CRITICAL) != 0 && certflags_src_addr != NULL) add_string_option(c, "source-address", certflags_src_addr); + for (i = 0; i < ncert_userext; i++) { + if ((cert_userext[i].crit && (which & OPTIONS_EXTENSIONS)) || + (!cert_userext[i].crit && (which & OPTIONS_CRITICAL))) + continue; + if (cert_userext[i].val == NULL) + add_flag_option(c, cert_userext[i].key); + else { + add_string_option(c, cert_userext[i].key, + cert_userext[i].val); + } + } } static struct sshkey * @@ -1768,7 +1777,8 @@ static void add_cert_option(char *opt) { - char *val; + char *val, *cp; + int iscrit = 0; if (strcasecmp(opt, "clear") == 0) certflags_flags = 0; @@ -1808,6 +1818,18 @@ if (addr_match_cidr_list(NULL, val) != 0) fatal("Invalid source-address list"); certflags_src_addr = xstrdup(val); + } else if (strncasecmp(opt, "extension:", 10) == 0 || + (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) { + val = xstrdup(strchr(opt, ':') + 1); + if ((cp = strchr(val, '=')) != NULL) + *cp++ = '\0'; + cert_userext = xreallocarray(cert_userext, ncert_userext + 1, + sizeof(*cert_userext)); + cert_userext[ncert_userext].key = val; + cert_userext[ncert_userext].val = cp == NULL ? + NULL : xstrdup(cp); + cert_userext[ncert_userext].crit = iscrit; + ncert_userext++; } else fatal("Unsupported certificate option \"%s\"", opt); } @@ -2194,7 +2216,7 @@ usage(void) { fprintf(stderr, - "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1]\n" + "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa]\n" " [-N new_passphrase] [-C comment] [-f output_keyfile]\n" " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n" " ssh-keygen -i [-m key_format] [-f input_keyfile]\n" @@ -2261,6 +2283,8 @@ OpenSSL_add_all_algorithms(); log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); + setlocale(LC_CTYPE, ""); + /* we need this for the home * directory. */ pw = getpwuid(getuid()); if (!pw) @@ -2437,10 +2461,10 @@ break; case 'J': lines_to_process = strtoul(optarg, NULL, 10); - break; + break; case 'j': start_lineno = strtoul(optarg, NULL, 10); - break; + break; case 'K': if (strlen(optarg) >= PATH_MAX) fatal("Checkpoint filename too long");