diff --git a/dns.c b/dns.c index e8589f68d..1cfc38e7c 100644 --- a/dns.c +++ b/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. @@ -75,6 +75,7 @@ dns_result_totext(unsigned int res) /* * Read SSHFP parameters from key buffer. + * Caller must free digest which is allocated by sshkey_fingerprint_raw(). */ static int 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) { case KEY_RSA: *algorithm = SSHFP_KEY_RSA; - if (!*digest_type) - *digest_type = SSHFP_HASH_SHA1; break; case KEY_DSA: *algorithm = SSHFP_KEY_DSA; - if (!*digest_type) - *digest_type = SSHFP_HASH_SHA1; break; case KEY_ECDSA: *algorithm = SSHFP_KEY_ECDSA; - if (!*digest_type) - *digest_type = SSHFP_HASH_SHA256; break; case KEY_ED25519: *algorithm = SSHFP_KEY_ED25519; - if (!*digest_type) - *digest_type = SSHFP_HASH_SHA256; break; case KEY_XMSS: *algorithm = SSHFP_KEY_XMSS; - if (!*digest_type) - *digest_type = SSHFP_HASH_SHA256; break; default: *algorithm = SSHFP_KEY_RESERVED; /* 0 */ - *digest_type = SSHFP_HASH_RESERVED; /* 0 */ } switch (*digest_type) { @@ -133,7 +123,6 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, } else { *digest = NULL; *digest_len = 0; - success = 0; } return success; @@ -212,7 +201,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, struct rrsetinfo *fingerprints = NULL; u_int8_t hostkey_algorithm; - u_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED; u_char *hostkey_digest; size_t hostkey_digest_len; @@ -248,14 +236,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, 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) *flags |= DNS_VERIFY_FOUND; @@ -271,35 +251,41 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, verbose("Error parsing fingerprint from DNS."); continue; } + debug3_f("checking SSHFP type %d fptype %d", dnskey_algorithm, + dnskey_digest_type); - if (hostkey_digest_type != dnskey_digest_type) { - hostkey_digest_type = dnskey_digest_type; - free(hostkey_digest); - - /* Initialize host key parameters */ - if (!dns_read_key(&hostkey_algorithm, - &hostkey_digest_type, &hostkey_digest, - &hostkey_digest_len, hostkey)) { - error("Error calculating key fingerprint."); - freerrset(fingerprints); - return -1; - } + /* Calculate host key fingerprint. */ + if (!dns_read_key(&hostkey_algorithm, &dnskey_digest_type, + &hostkey_digest, &hostkey_digest_len, hostkey)) { + error("Error calculating key fingerprint."); + freerrset(fingerprints); + return -1; } /* Check if the current key is the same as the given key */ if (hostkey_algorithm == dnskey_algorithm && - hostkey_digest_type == dnskey_digest_type) { - if (hostkey_digest_len == dnskey_digest_len && - timingsafe_bcmp(hostkey_digest, dnskey_digest, - hostkey_digest_len) == 0) + hostkey_digest_len == dnskey_digest_len) { + if (timingsafe_bcmp(hostkey_digest, dnskey_digest, + hostkey_digest_len) == 0) { + debug_f("matched SSHFP type %d fptype %d", + dnskey_algorithm, dnskey_digest_type); *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(hostkey_digest); /* from sshkey_fingerprint_raw() */ } - free(hostkey_digest); /* from sshkey_fingerprint_raw() */ 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_MATCH) debug("matching host key fingerprint found in DNS"); diff --git a/dns.h b/dns.h index 91f3c632d..c9b61c4f2 100644 --- a/dns.h +++ b/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. @@ -50,6 +50,7 @@ enum sshfp_hashes { #define DNS_VERIFY_FOUND 0x00000001 #define DNS_VERIFY_MATCH 0x00000002 #define DNS_VERIFY_SECURE 0x00000004 +#define DNS_VERIFY_FAILED 0x00000008 int verify_host_key_dns(const char *, struct sockaddr *, struct sshkey *, int *);