version 1.40, 2021/07/05 01:16:46 |
version 1.41, 2021/07/19 03:13:28 |
|
|
|
|
/* |
/* |
* 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, |
|
|
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) { |
|
|
} else { |
} else { |
*digest = NULL; |
*digest = NULL; |
*digest_len = 0; |
*digest_len = 0; |
success = 0; |
|
} |
} |
|
|
return success; |
return success; |
|
|
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; |
|
|
|
|
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; |
|
|
|
|
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)) { |
|
error("Error calculating key fingerprint."); |
/* Initialize host key parameters */ |
freerrset(fingerprints); |
if (!dns_read_key(&hostkey_algorithm, |
return -1; |
&hostkey_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 */ |
/* 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) |