upstream: let ssh-keygen and ssh-keyscan accept

-Ohashalg=sha1|sha256 when outputting SSHFP fingerprints to allow algorithm
selection. bz3493 ok dtucker@

OpenBSD-Commit-ID: e6e07fe21318a873bd877f333e189eb963a11b3d
This commit is contained in:
djm@openbsd.org 2023-02-10 04:56:30 +00:00 committed by Damien Miller
parent 18938d11a9
commit d651f5c9fe
No known key found for this signature in database
6 changed files with 77 additions and 24 deletions

7
dns.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: dns.c,v 1.42 2022/02/01 23:32:51 djm Exp $ */ /* $OpenBSD: dns.c,v 1.43 2023/02/10 04:56:30 djm Exp $ */
/* /*
* Copyright (c) 2003 Wesley Griffin. All rights reserved. * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@ -301,7 +301,8 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
* Export the fingerprint of a key as a DNS resource record * Export the fingerprint of a key as a DNS resource record
*/ */
int int
export_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic) export_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic,
int alg)
{ {
u_int8_t rdata_pubkey_algorithm = 0; u_int8_t rdata_pubkey_algorithm = 0;
u_int8_t rdata_digest_type = SSHFP_HASH_RESERVED; u_int8_t rdata_digest_type = SSHFP_HASH_RESERVED;
@ -311,6 +312,8 @@ export_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic)
int success = 0; int success = 0;
for (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) { for (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) {
if (alg != -1 && dtype != alg)
continue;
rdata_digest_type = dtype; rdata_digest_type = dtype;
if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type,
&rdata_digest, &rdata_digest_len, key)) { &rdata_digest, &rdata_digest_len, key)) {

4
dns.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: dns.h,v 1.19 2021/07/19 03:13:28 dtucker Exp $ */ /* $OpenBSD: dns.h,v 1.20 2023/02/10 04:56:30 djm Exp $ */
/* /*
* Copyright (c) 2003 Wesley Griffin. All rights reserved. * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@ -54,6 +54,6 @@ enum sshfp_hashes {
int verify_host_key_dns(const char *, struct sockaddr *, int verify_host_key_dns(const char *, struct sockaddr *,
struct sshkey *, int *); struct sshkey *, int *);
int export_dns_rr(const char *, struct sshkey *, FILE *, int); int export_dns_rr(const char *, struct sshkey *, FILE *, int, int);
#endif /* DNS_H */ #endif /* DNS_H */

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-keygen.1,v 1.226 2022/09/10 08:50:53 jsg Exp $ .\" $OpenBSD: ssh-keygen.1,v 1.227 2023/02/10 04:56:30 djm Exp $
.\" .\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd $Mdocdate: September 10 2022 $ .Dd $Mdocdate: February 10 2023 $
.Dt SSH-KEYGEN 1 .Dt SSH-KEYGEN 1
.Os .Os
.Sh NAME .Sh NAME
@ -518,6 +518,21 @@ suffixed with a Z character, which causes them to be interpreted in the
UTC time zone. UTC time zone.
.El .El
.Pp .Pp
When generating SSHFP DNS records from public keys using the
.Fl r
flag, the following options are accepted:
.Bl -tag -width Ds
.It Cm hashalg Ns = Ns Ar algorithm
Selects a hash algorithm to use when printing SSHFP records using the
.Fl D
flag.
Valid algorithms are
.Dq sha1
and
.Dq sha256.
The default is to print both.
.El
.Pp
The The
.Fl O .Fl O
option may be specified multiple times. option may be specified multiple times.

View File

@ -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.462 2023/02/10 04:56:30 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1479,13 +1479,23 @@ do_change_passphrase(struct passwd *pw)
*/ */
static int static int
do_print_resource_record(struct passwd *pw, char *fname, char *hname, 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; struct sshkey *public;
char *comment = NULL; char *comment = NULL;
struct stat st; 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) if (fname == NULL)
fatal_f("no filename"); fatal_f("no filename");
if (stat(fname, &st) == -1) { if (stat(fname, &st) == -1) {
@ -1495,7 +1505,7 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname,
} }
if ((r = sshkey_load_public(fname, &public, &comment)) != 0) if ((r = sshkey_load_public(fname, &public, &comment)) != 0)
fatal_r(r, "Failed to read v2 public key from \"%s\"", fname); 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); sshkey_free(public);
free(comment); free(comment);
return 1; return 1;
@ -3725,7 +3735,7 @@ main(int argc, char **argv)
if (have_identity) { if (have_identity) {
n = do_print_resource_record(pw, identity_file, n = do_print_resource_record(pw, identity_file,
rr_hostname, print_generic); rr_hostname, print_generic, opts, nopts);
if (n == 0) if (n == 0)
fatal("%s: %s", identity_file, strerror(errno)); fatal("%s: %s", identity_file, strerror(errno));
exit(0); exit(0);
@ -3733,19 +3743,19 @@ main(int argc, char **argv)
n += do_print_resource_record(pw, n += do_print_resource_record(pw,
_PATH_HOST_RSA_KEY_FILE, rr_hostname, _PATH_HOST_RSA_KEY_FILE, rr_hostname,
print_generic); print_generic, opts, nopts);
n += do_print_resource_record(pw, n += do_print_resource_record(pw,
_PATH_HOST_DSA_KEY_FILE, rr_hostname, _PATH_HOST_DSA_KEY_FILE, rr_hostname,
print_generic); print_generic, opts, nopts);
n += do_print_resource_record(pw, n += do_print_resource_record(pw,
_PATH_HOST_ECDSA_KEY_FILE, rr_hostname, _PATH_HOST_ECDSA_KEY_FILE, rr_hostname,
print_generic); print_generic, opts, nopts);
n += do_print_resource_record(pw, n += do_print_resource_record(pw,
_PATH_HOST_ED25519_KEY_FILE, rr_hostname, _PATH_HOST_ED25519_KEY_FILE, rr_hostname,
print_generic); print_generic, opts, nopts);
n += do_print_resource_record(pw, n += do_print_resource_record(pw,
_PATH_HOST_XMSS_KEY_FILE, rr_hostname, _PATH_HOST_XMSS_KEY_FILE, rr_hostname,
print_generic); print_generic, opts, nopts);
if (n == 0) if (n == 0)
fatal("no keys found."); fatal("no keys found.");
exit(0); exit(0);

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-keyscan.1,v 1.47 2022/10/28 02:29:34 djm Exp $ .\" $OpenBSD: ssh-keyscan.1,v 1.48 2023/02/10 04:56:30 djm Exp $
.\" .\"
.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. .\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
.\" .\"
@ -6,7 +6,7 @@
.\" permitted provided that due credit is given to the author and the .\" permitted provided that due credit is given to the author and the
.\" OpenBSD project by leaving this copyright notice intact. .\" OpenBSD project by leaving this copyright notice intact.
.\" .\"
.Dd $Mdocdate: October 28 2022 $ .Dd $Mdocdate: February 10 2023 $
.Dt SSH-KEYSCAN 1 .Dt SSH-KEYSCAN 1
.Os .Os
.Sh NAME .Sh NAME
@ -16,6 +16,7 @@
.Nm ssh-keyscan .Nm ssh-keyscan
.Op Fl 46cDHv .Op Fl 46cDHv
.Op Fl f Ar file .Op Fl f Ar file
.Op Fl O Ar option
.Op Fl p Ar port .Op Fl p Ar port
.Op Fl T Ar timeout .Op Fl T Ar timeout
.Op Fl t Ar type .Op Fl t Ar type
@ -97,6 +98,20 @@ and
.Xr sshd 8 , .Xr sshd 8 ,
but they do not reveal identifying information should the file's contents but they do not reveal identifying information should the file's contents
be disclosed. be disclosed.
.It Fl O Ar option
Specify a key/value option.
At present, only a single option is supported:
.Bl -tag -width Ds
.It Cm hashalg Ns = Ns Ar algorithm
Selects a hash algorithm to use when printing SSHFP records using the
.Fl D
flag.
Valid algorithms are
.Dq sha1
and
.Dq sha256.
The default is to print both.
.El
.It Fl p Ar port .It Fl p Ar port
Connect to Connect to
.Ar port .Ar port

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.149 2022/12/26 19:16:03 jmc Exp $ */ /* $OpenBSD: ssh-keyscan.c,v 1.150 2023/02/10 04:56:30 djm Exp $ */
/* /*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
* *
@ -40,6 +40,7 @@
#include "sshbuf.h" #include "sshbuf.h"
#include "sshkey.h" #include "sshkey.h"
#include "cipher.h" #include "cipher.h"
#include "digest.h"
#include "kex.h" #include "kex.h"
#include "compat.h" #include "compat.h"
#include "myproposal.h" #include "myproposal.h"
@ -80,6 +81,8 @@ int print_sshfp = 0; /* Print SSHFP records instead of known_hosts */
int found_one = 0; /* Successfully found a key */ int found_one = 0; /* Successfully found a key */
int hashalg = -1; /* Hash for SSHFP records or -1 for all */
#define MAXMAXFD 256 #define MAXMAXFD 256
/* The number of seconds after which to give up on a TCP connection */ /* The number of seconds after which to give up on a TCP connection */
@ -314,7 +317,7 @@ keyprint_one(const char *host, struct sshkey *key)
found_one = 1; found_one = 1;
if (print_sshfp) { if (print_sshfp) {
export_dns_rr(host, key, stdout, 0); export_dns_rr(host, key, stdout, 0, hashalg);
return; return;
} }
@ -698,9 +701,8 @@ static void
usage(void) usage(void)
{ {
fprintf(stderr, fprintf(stderr,
"usage: %s [-46cDHv] [-f file] [-p port] [-T timeout] [-t type]\n" "usage: ssh-keyscan [-46cDHv] [-f file] [-p port] [-T timeout] [-t type]\n"
"\t\t [host | addrlist namelist]\n", " [-O option] [host | addrlist namelist]\n");
__progname);
exit(1); exit(1);
} }
@ -726,7 +728,7 @@ main(int argc, char **argv)
if (argc <= 1) if (argc <= 1)
usage(); usage();
while ((opt = getopt(argc, argv, "cDHv46p:T:t:f:")) != -1) { while ((opt = getopt(argc, argv, "cDHv46O:p:T:t:f:")) != -1) {
switch (opt) { switch (opt) {
case 'H': case 'H':
hash_hosts = 1; hash_hosts = 1;
@ -766,6 +768,14 @@ main(int argc, char **argv)
optarg = NULL; optarg = NULL;
argv[fopt_count++] = optarg; argv[fopt_count++] = optarg;
break; break;
case 'O':
/* Maybe other misc options in the future too */
if (strncmp(optarg, "hashalg=", 8) != 0)
fatal("Unsupported -O option");
if ((hashalg = ssh_digest_alg_by_name(
optarg + 8)) == -1)
fatal("Unsupported hash algorithm");
break;
case 't': case 't':
get_keytypes = 0; get_keytypes = 0;
tname = strtok(optarg, ","); tname = strtok(optarg, ",");