version 1.27, 2010/08/31 11:54:45 |
version 1.28, 2012/05/23 03:28:28 |
|
|
u_char **digest, u_int *digest_len, Key *key) |
u_char **digest, u_int *digest_len, Key *key) |
{ |
{ |
int success = 0; |
int success = 0; |
|
enum fp_type fp_type = 0; |
|
|
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; |
/* XXX KEY_ECDSA */ |
case KEY_ECDSA: |
|
*algorithm = SSHFP_KEY_ECDSA; |
|
if (!*digest_type) |
|
*digest_type = SSHFP_HASH_SHA256; |
|
break; |
default: |
default: |
*algorithm = SSHFP_KEY_RESERVED; /* 0 */ |
*algorithm = SSHFP_KEY_RESERVED; /* 0 */ |
|
*digest_type = SSHFP_HASH_RESERVED; /* 0 */ |
} |
} |
|
|
if (*algorithm) { |
switch (*digest_type) { |
*digest_type = SSHFP_HASH_SHA1; |
case SSHFP_HASH_SHA1: |
*digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len); |
fp_type = SSH_FP_SHA1; |
|
break; |
|
case SSHFP_HASH_SHA256: |
|
fp_type = SSH_FP_SHA256; |
|
break; |
|
default: |
|
*digest_type = SSHFP_HASH_RESERVED; /* 0 */ |
|
} |
|
|
|
if (*algorithm && *digest_type) { |
|
*digest = key_fingerprint_raw(key, fp_type, digest_len); |
if (*digest == NULL) |
if (*digest == NULL) |
fatal("dns_read_key: null from key_fingerprint_raw()"); |
fatal("dns_read_key: null from key_fingerprint_raw()"); |
success = 1; |
success = 1; |
} else { |
} else { |
*digest_type = SSHFP_HASH_RESERVED; |
|
*digest = NULL; |
*digest = NULL; |
*digest_len = 0; |
*digest_len = 0; |
success = 0; |
success = 0; |
|
|
struct rrsetinfo *fingerprints = NULL; |
struct rrsetinfo *fingerprints = NULL; |
|
|
u_int8_t hostkey_algorithm; |
u_int8_t hostkey_algorithm; |
u_int8_t hostkey_digest_type; |
u_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED; |
u_char *hostkey_digest; |
u_char *hostkey_digest; |
u_int hostkey_digest_len; |
u_int hostkey_digest_len; |
|
|
|
|
fingerprints->rri_nrdatas); |
fingerprints->rri_nrdatas); |
} |
} |
|
|
/* Initialize host key parameters */ |
/* Initialize default host key parameters */ |
if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type, |
if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type, |
&hostkey_digest, &hostkey_digest_len, hostkey)) { |
&hostkey_digest, &hostkey_digest_len, hostkey)) { |
error("Error calculating host key fingerprint."); |
error("Error calculating host key fingerprint."); |
|
|
continue; |
continue; |
} |
} |
|
|
|
if (hostkey_digest_type != dnskey_digest_type) { |
|
hostkey_digest_type = dnskey_digest_type; |
|
xfree(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; |
|
} |
|
} |
|
|
/* 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_type == dnskey_digest_type) { |
|
|
if (hostkey_digest_len == dnskey_digest_len && |
if (hostkey_digest_len == dnskey_digest_len && |
memcmp(hostkey_digest, dnskey_digest, |
timingsafe_bcmp(hostkey_digest, dnskey_digest, |
hostkey_digest_len) == 0) { |
hostkey_digest_len) == 0) |
|
|
*flags |= DNS_VERIFY_MATCH; |
*flags |= DNS_VERIFY_MATCH; |
} |
|
} |
} |
xfree(dnskey_digest); |
xfree(dnskey_digest); |
} |
} |
|
|
export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) |
export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) |
{ |
{ |
u_int8_t rdata_pubkey_algorithm = 0; |
u_int8_t rdata_pubkey_algorithm = 0; |
u_int8_t rdata_digest_type = SSHFP_HASH_SHA1; |
u_int8_t rdata_digest_type = SSHFP_HASH_RESERVED; |
|
u_int8_t dtype; |
u_char *rdata_digest; |
u_char *rdata_digest; |
u_int rdata_digest_len; |
u_int i, rdata_digest_len; |
|
|
u_int i; |
|
int success = 0; |
int success = 0; |
|
|
if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, |
for (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) { |
&rdata_digest, &rdata_digest_len, key)) { |
rdata_digest_type = dtype; |
|
if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, |
|
&rdata_digest, &rdata_digest_len, key)) { |
|
if (generic) { |
|
fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", |
|
hostname, DNS_RDATATYPE_SSHFP, |
|
2 + rdata_digest_len, |
|
rdata_pubkey_algorithm, rdata_digest_type); |
|
} else { |
|
fprintf(f, "%s IN SSHFP %d %d ", hostname, |
|
rdata_pubkey_algorithm, rdata_digest_type); |
|
} |
|
for (i = 0; i < rdata_digest_len; i++) |
|
fprintf(f, "%02x", rdata_digest[i]); |
|
fprintf(f, "\n"); |
|
xfree(rdata_digest); /* from key_fingerprint_raw() */ |
|
success = 1; |
|
} |
|
} |
|
|
if (generic) |
/* No SSHFP record was generated at all */ |
fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", hostname, |
if (success == 0) { |
DNS_RDATATYPE_SSHFP, 2 + rdata_digest_len, |
error("%s: unsupported algorithm and/or digest_type", __func__); |
rdata_pubkey_algorithm, rdata_digest_type); |
|
else |
|
fprintf(f, "%s IN SSHFP %d %d ", hostname, |
|
rdata_pubkey_algorithm, rdata_digest_type); |
|
|
|
for (i = 0; i < rdata_digest_len; i++) |
|
fprintf(f, "%02x", rdata_digest[i]); |
|
fprintf(f, "\n"); |
|
xfree(rdata_digest); /* from key_fingerprint_raw() */ |
|
success = 1; |
|
} else { |
|
error("export_dns_rr: unsupported algorithm"); |
|
} |
} |
|
|
return success; |
return success; |