=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-keygen.c,v retrieving revision 1.461 retrieving revision 1.469 diff -u -r1.461 -r1.469 --- src/usr.bin/ssh/ssh-keygen.c 2022/12/04 23:50:49 1.461 +++ src/usr.bin/ssh/ssh-keygen.c 2023/07/14 05:31:44 1.469 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.461 2022/12/04 23:50:49 cheloha Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.469 2023/07/14 05:31:44 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -459,6 +459,7 @@ { struct sshkey *key = NULL; char *type, *cipher; + const char *alg = NULL; u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345"; int r, rlen, ktype; u_int magic, i1, i2, i3, i4; @@ -567,6 +568,7 @@ if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) fatal_fr(r, "generate RSA parameters"); BN_clear_free(rsa_iqmp); + alg = "rsa-sha2-256"; break; } rlen = sshbuf_len(b); @@ -575,10 +577,10 @@ /* try the key */ if ((r = sshkey_sign(key, &sig, &slen, data, sizeof(data), - NULL, NULL, NULL, 0)) != 0) + alg, NULL, NULL, 0)) != 0) error_fr(r, "signing with converted key failed"); else if ((r = sshkey_verify(key, sig, slen, data, sizeof(data), - NULL, 0, NULL)) != 0) + alg, 0, NULL)) != 0) error_fr(r, "verification with converted key failed"); if (r != 0) { sshkey_free(key); @@ -974,6 +976,7 @@ * accept a public key prefixed with a hostname or options. * Try a bare key first, otherwise skip the leading stuff. */ + comment = NULL; if ((public = try_read_key(&cp)) == NULL) { i = strtol(cp, &ep, 10); if (i == 0 || ep == NULL || @@ -1161,7 +1164,7 @@ case HKF_STATUS_OK: case HKF_STATUS_MATCHED: /* - * Don't hash hosts already already hashed, with wildcard + * Don't hash hosts already hashed, with wildcard * characters or a CA/revocation marker. */ if (was_hashed || has_wild || l->marker != MRK_NONE) { @@ -1314,7 +1317,7 @@ unlink(tmp); fatal("fdopen: %s", strerror(oerrno)); } - fchmod(fd, sb.st_mode & 0644); + (void)fchmod(fd, sb.st_mode & 0644); inplace = 1; } /* XXX support identity_file == "-" for stdin */ @@ -1456,13 +1459,23 @@ */ static int do_print_resource_record(struct passwd *pw, char *fname, char *hname, - int print_generic) + int print_generic, char * const *opts, size_t nopts) { struct sshkey *public; char *comment = NULL; struct stat st; - int r; + int r, hash = -1; + size_t i; + for (i = 0; i < nopts; i++) { + if (strncasecmp(opts[i], "hashalg=", 8) == 0) { + if ((hash = ssh_digest_alg_by_name(opts[i] + 8)) == -1) + fatal("Unsupported hash algorithm"); + } else { + error("Invalid option \"%s\"", opts[i]); + return SSH_ERR_INVALID_ARGUMENT; + } + } if (fname == NULL) fatal_f("no filename"); if (stat(fname, &st) == -1) { @@ -1472,7 +1485,7 @@ } if ((r = sshkey_load_public(fname, &public, &comment)) != 0) fatal_r(r, "Failed to read v2 public key from \"%s\"", fname); - export_dns_rr(hname, public, stdout, print_generic); + export_dns_rr(hname, public, stdout, print_generic, hash); sshkey_free(public); free(comment); return 1; @@ -2210,7 +2223,8 @@ * OpenSSH base64 hashes omit trailing '=' * characters; put them back for decode. */ - tlen = strlen(cp); + if ((tlen = strlen(cp)) >= SIZE_MAX - 5) + fatal_f("hash too long: %zu bytes", tlen); tmp = xmalloc(tlen + 4 + 1); strlcpy(tmp, cp, tlen + 1); while ((tlen % 4) != 0) { @@ -2252,6 +2266,10 @@ if (!quiet) printf("Revoking from %s\n", path); while (getline(&line, &linesize, krl_spec) != -1) { + if (linesize >= INT_MAX) { + fatal_f("%s contains unparsable line, len=%zu", + path, linesize); + } lnum++; was_explicit_key = was_sha1 = was_sha256 = was_hash = 0; cp = line + strspn(line, " \t"); @@ -2982,6 +3000,7 @@ } else if (strncmp(opts[i], "start-line=", 11) == 0) { start_lineno = strtoul(opts[i]+11, NULL, 10); } else if (strncmp(opts[i], "checkpoint=", 11) == 0) { + free(checkpoint); checkpoint = xstrdup(opts[i]+11); } else if (strncmp(opts[i], "generator=", 10) == 0) { generator_wanted = (u_int32_t)strtonum( @@ -3020,6 +3039,9 @@ generator_wanted, checkpoint, start_lineno, lines_to_process) != 0) fatal("modulus screening failed"); + if (in != stdin) + (void)fclose(in); + free(checkpoint); #else /* WITH_OPENSSL */ fatal("Moduli screening is not supported"); #endif /* WITH_OPENSSL */ @@ -3699,7 +3721,7 @@ if (have_identity) { n = do_print_resource_record(pw, identity_file, - rr_hostname, print_generic); + rr_hostname, print_generic, opts, nopts); if (n == 0) fatal("%s: %s", identity_file, strerror(errno)); exit(0); @@ -3707,19 +3729,19 @@ n += do_print_resource_record(pw, _PATH_HOST_RSA_KEY_FILE, rr_hostname, - print_generic); + print_generic, opts, nopts); n += do_print_resource_record(pw, _PATH_HOST_DSA_KEY_FILE, rr_hostname, - print_generic); + print_generic, opts, nopts); n += do_print_resource_record(pw, _PATH_HOST_ECDSA_KEY_FILE, rr_hostname, - print_generic); + print_generic, opts, nopts); n += do_print_resource_record(pw, _PATH_HOST_ED25519_KEY_FILE, rr_hostname, - print_generic); + print_generic, opts, nopts); n += do_print_resource_record(pw, _PATH_HOST_XMSS_KEY_FILE, rr_hostname, - print_generic); + print_generic, opts, nopts); if (n == 0) fatal("no keys found."); exit(0);