[openssh-commits] [openssh] 01/01: upstream: Ensure that all returned SSHFP records for the specified host

git+noreply at mindrot.org git+noreply at mindrot.org
Mon Jul 19 13:46:43 AEST 2021


This is an automated email from the git hooks/post-receive script.

dtucker pushed a commit to branch master
in repository openssh.

commit b75a80fa8369864916d4c93a50576155cad4df03
Author: dtucker at openbsd.org <dtucker at openbsd.org>
Date:   Mon Jul 19 03:13:28 2021 +0000

    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 at .
    
    OpenBSD-Commit-ID: 0a6a0a476eb7f9dfe8fe2c05a1a395e3e9b22ee4
---
 dns.c | 66 ++++++++++++++++++++++++++----------------------------------------
 dns.h |  3 ++-
 2 files changed, 28 insertions(+), 41 deletions(-)

diff --git a/dns.c b/dns.c
index e8589f68..1cfc38e7 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;
 		}
-
-		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;
-			}
+		debug3_f("checking SSHFP type %d fptype %d", dnskey_algorithm,
+		    dnskey_digest_type);
+
+		/* 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 91f3c632..c9b61c4f 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 *);

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list