=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-keygen.c,v retrieving revision 1.458 retrieving revision 1.463 diff -u -r1.458 -r1.463 --- src/usr.bin/ssh/ssh-keygen.c 2022/08/05 05:01:40 1.458 +++ src/usr.bin/ssh/ssh-keygen.c 2023/02/28 08:45:24 1.463 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.458 2022/08/05 05:01:40 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.463 2023/02/28 08:45:24 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1314,7 +1314,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 +1456,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 +1482,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; @@ -1894,6 +1904,21 @@ } static void +parse_hex_u64(const char *s, uint64_t *up) +{ + char *ep; + unsigned long long ull; + + errno = 0; + ull = strtoull(s, &ep, 16); + if (*s == '\0' || *ep != '\0') + fatal("Invalid certificate time: not a number"); + if (errno == ERANGE && ull == ULONG_MAX) + fatal_fr(SSH_ERR_SYSTEM_ERROR, "Invalid certificate time"); + *up = (uint64_t)ull; +} + +static void parse_cert_times(char *timespec) { char *from, *to; @@ -1915,8 +1940,8 @@ /* * from:to, where - * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "always" - * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "forever" + * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "always" + * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "forever" */ from = xstrdup(timespec); to = strchr(from, ':'); @@ -1928,6 +1953,8 @@ cert_valid_from = parse_relative_time(from, now); else if (strcmp(from, "always") == 0) cert_valid_from = 0; + else if (strncmp(from, "0x", 2) == 0) + parse_hex_u64(from, &cert_valid_from); else if (parse_absolute_time(from, &cert_valid_from) != 0) fatal("Invalid from time \"%s\"", from); @@ -1935,6 +1962,8 @@ cert_valid_to = parse_relative_time(to, now); else if (strcmp(to, "forever") == 0) cert_valid_to = ~(u_int64_t)0; + else if (strncmp(to, "0x", 2) == 0) + parse_hex_u64(to, &cert_valid_to); else if (parse_absolute_time(to, &cert_valid_to) != 0) fatal("Invalid to time \"%s\"", to); @@ -3501,7 +3530,6 @@ else fatal("Unsupported moduli option %s", optarg); break; - case '?': default: usage(); } @@ -3681,7 +3709,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); @@ -3689,19 +3717,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);