mirror of git://anongit.mindrot.org/openssh.git
upstream: Ensure that all returned SSHFP records for the specified host
name and hostkey type match instead of only one. While there, simplify the code somewhat and add some debugging. Based on discussion in bz#3322, ok djm@. OpenBSD-Commit-ID: 0a6a0a476eb7f9dfe8fe2c05a1a395e3e9b22ee4
This commit is contained in:
parent
1cc1fd0953
commit
b75a80fa83
58
dns.c
58
dns.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: dns.c,v 1.40 2021/07/05 01:16:46 dtucker Exp $ */
|
/* $OpenBSD: dns.c,v 1.41 2021/07/19 03:13:28 dtucker Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
||||||
|
@ -75,6 +75,7 @@ dns_result_totext(unsigned int res)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read SSHFP parameters from key buffer.
|
* Read SSHFP parameters from key buffer.
|
||||||
|
* Caller must free digest which is allocated by sshkey_fingerprint_raw().
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
|
dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
|
||||||
|
@ -86,32 +87,21 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
case KEY_RSA:
|
case KEY_RSA:
|
||||||
*algorithm = SSHFP_KEY_RSA;
|
*algorithm = SSHFP_KEY_RSA;
|
||||||
if (!*digest_type)
|
|
||||||
*digest_type = SSHFP_HASH_SHA1;
|
|
||||||
break;
|
break;
|
||||||
case KEY_DSA:
|
case KEY_DSA:
|
||||||
*algorithm = SSHFP_KEY_DSA;
|
*algorithm = SSHFP_KEY_DSA;
|
||||||
if (!*digest_type)
|
|
||||||
*digest_type = SSHFP_HASH_SHA1;
|
|
||||||
break;
|
break;
|
||||||
case KEY_ECDSA:
|
case KEY_ECDSA:
|
||||||
*algorithm = SSHFP_KEY_ECDSA;
|
*algorithm = SSHFP_KEY_ECDSA;
|
||||||
if (!*digest_type)
|
|
||||||
*digest_type = SSHFP_HASH_SHA256;
|
|
||||||
break;
|
break;
|
||||||
case KEY_ED25519:
|
case KEY_ED25519:
|
||||||
*algorithm = SSHFP_KEY_ED25519;
|
*algorithm = SSHFP_KEY_ED25519;
|
||||||
if (!*digest_type)
|
|
||||||
*digest_type = SSHFP_HASH_SHA256;
|
|
||||||
break;
|
break;
|
||||||
case KEY_XMSS:
|
case KEY_XMSS:
|
||||||
*algorithm = SSHFP_KEY_XMSS;
|
*algorithm = SSHFP_KEY_XMSS;
|
||||||
if (!*digest_type)
|
|
||||||
*digest_type = SSHFP_HASH_SHA256;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*algorithm = SSHFP_KEY_RESERVED; /* 0 */
|
*algorithm = SSHFP_KEY_RESERVED; /* 0 */
|
||||||
*digest_type = SSHFP_HASH_RESERVED; /* 0 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (*digest_type) {
|
switch (*digest_type) {
|
||||||
|
@ -133,7 +123,6 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
|
||||||
} else {
|
} else {
|
||||||
*digest = NULL;
|
*digest = NULL;
|
||||||
*digest_len = 0;
|
*digest_len = 0;
|
||||||
success = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
@ -212,7 +201,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
|
||||||
struct rrsetinfo *fingerprints = NULL;
|
struct rrsetinfo *fingerprints = NULL;
|
||||||
|
|
||||||
u_int8_t hostkey_algorithm;
|
u_int8_t hostkey_algorithm;
|
||||||
u_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED;
|
|
||||||
u_char *hostkey_digest;
|
u_char *hostkey_digest;
|
||||||
size_t hostkey_digest_len;
|
size_t hostkey_digest_len;
|
||||||
|
|
||||||
|
@ -248,14 +236,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
|
||||||
fingerprints->rri_nrdatas);
|
fingerprints->rri_nrdatas);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize default host key parameters */
|
|
||||||
if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type,
|
|
||||||
&hostkey_digest, &hostkey_digest_len, hostkey)) {
|
|
||||||
error("Error calculating host key fingerprint.");
|
|
||||||
freerrset(fingerprints);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fingerprints->rri_nrdatas)
|
if (fingerprints->rri_nrdatas)
|
||||||
*flags |= DNS_VERIFY_FOUND;
|
*flags |= DNS_VERIFY_FOUND;
|
||||||
|
|
||||||
|
@ -271,35 +251,41 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
|
||||||
verbose("Error parsing fingerprint from DNS.");
|
verbose("Error parsing fingerprint from DNS.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
debug3_f("checking SSHFP type %d fptype %d", dnskey_algorithm,
|
||||||
|
dnskey_digest_type);
|
||||||
|
|
||||||
if (hostkey_digest_type != dnskey_digest_type) {
|
/* Calculate host key fingerprint. */
|
||||||
hostkey_digest_type = dnskey_digest_type;
|
if (!dns_read_key(&hostkey_algorithm, &dnskey_digest_type,
|
||||||
free(hostkey_digest);
|
&hostkey_digest, &hostkey_digest_len, hostkey)) {
|
||||||
|
|
||||||
/* Initialize host key parameters */
|
|
||||||
if (!dns_read_key(&hostkey_algorithm,
|
|
||||||
&hostkey_digest_type, &hostkey_digest,
|
|
||||||
&hostkey_digest_len, hostkey)) {
|
|
||||||
error("Error calculating key fingerprint.");
|
error("Error calculating key fingerprint.");
|
||||||
freerrset(fingerprints);
|
freerrset(fingerprints);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the current key is the same as the given key */
|
/* Check if the current key is the same as the given key */
|
||||||
if (hostkey_algorithm == dnskey_algorithm &&
|
if (hostkey_algorithm == dnskey_algorithm &&
|
||||||
hostkey_digest_type == dnskey_digest_type) {
|
hostkey_digest_len == dnskey_digest_len) {
|
||||||
if (hostkey_digest_len == dnskey_digest_len &&
|
if (timingsafe_bcmp(hostkey_digest, dnskey_digest,
|
||||||
timingsafe_bcmp(hostkey_digest, dnskey_digest,
|
hostkey_digest_len) == 0) {
|
||||||
hostkey_digest_len) == 0)
|
debug_f("matched SSHFP type %d fptype %d",
|
||||||
|
dnskey_algorithm, dnskey_digest_type);
|
||||||
*flags |= DNS_VERIFY_MATCH;
|
*flags |= DNS_VERIFY_MATCH;
|
||||||
|
} else {
|
||||||
|
debug_f("failed SSHFP type %d fptype %d",
|
||||||
|
dnskey_algorithm, dnskey_digest_type);
|
||||||
|
*flags |= DNS_VERIFY_FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(dnskey_digest);
|
free(dnskey_digest);
|
||||||
|
free(hostkey_digest); /* from sshkey_fingerprint_raw() */
|
||||||
}
|
}
|
||||||
|
|
||||||
free(hostkey_digest); /* from sshkey_fingerprint_raw() */
|
|
||||||
freerrset(fingerprints);
|
freerrset(fingerprints);
|
||||||
|
|
||||||
|
/* If any fingerprint failed to validate, return failure. */
|
||||||
|
if (*flags & DNS_VERIFY_FAILED)
|
||||||
|
*flags &= ~DNS_VERIFY_MATCH;
|
||||||
|
|
||||||
if (*flags & DNS_VERIFY_FOUND)
|
if (*flags & DNS_VERIFY_FOUND)
|
||||||
if (*flags & DNS_VERIFY_MATCH)
|
if (*flags & DNS_VERIFY_MATCH)
|
||||||
debug("matching host key fingerprint found in DNS");
|
debug("matching host key fingerprint found in DNS");
|
||||||
|
|
3
dns.h
3
dns.h
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: dns.h,v 1.18 2018/02/23 15:58:37 markus Exp $ */
|
/* $OpenBSD: dns.h,v 1.19 2021/07/19 03:13:28 dtucker Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
||||||
|
@ -50,6 +50,7 @@ enum sshfp_hashes {
|
||||||
#define DNS_VERIFY_FOUND 0x00000001
|
#define DNS_VERIFY_FOUND 0x00000001
|
||||||
#define DNS_VERIFY_MATCH 0x00000002
|
#define DNS_VERIFY_MATCH 0x00000002
|
||||||
#define DNS_VERIFY_SECURE 0x00000004
|
#define DNS_VERIFY_SECURE 0x00000004
|
||||||
|
#define DNS_VERIFY_FAILED 0x00000008
|
||||||
|
|
||||||
int verify_host_key_dns(const char *, struct sockaddr *,
|
int verify_host_key_dns(const char *, struct sockaddr *,
|
||||||
struct sshkey *, int *);
|
struct sshkey *, int *);
|
||||||
|
|
Loading…
Reference in New Issue