-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 diff -r -U4 openssh-5.8p2/dns.c openssh-5.8p2+sshfp3/dns.c - --- openssh-5.8p2/dns.c 2010-08-31 13:41:14.000000000 +0100 +++ openssh-5.8p2+sshfp3/dns.c 2011-08-16 20:49:14.000000000 +0100 @@ -33,8 +33,9 @@ #include #include #include #include +#include #include "xmalloc.h" #include "key.h" #include "dns.h" @@ -85,19 +86,32 @@ break; case KEY_DSA: *algorithm = SSHFP_KEY_DSA; break; - - /* XXX KEY_ECDSA */ + case KEY_ECDSA: + *algorithm = SSHFP_KEY_ECDSA; + break; default: *algorithm = SSHFP_KEY_RESERVED; /* 0 */ } if (*algorithm) { - - *digest_type = SSHFP_HASH_SHA1; - - *digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len); - - if (*digest == NULL) - - fatal("dns_read_key: null from key_fingerprint_raw()"); - - success = 1; + if (*digest_type == SSHFP_HASH_SHA1) { + *digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len); + if (*digest == NULL) + fatal("dns_read_key: null from key_fingerprint_raw()"); + success = 1; + } else if (*digest_type == SSHFP_HASH_SHA256) { + *digest = key_fingerprint_raw(key, SSH_FP_SHA256, digest_len); + if (*digest == NULL) + fatal("dns_read_key: null from key_fingerprint_raw()"); + success = 1; + } else { + *digest_type = SSHFP_HASH_RESERVED; + *digest = NULL; + *digest_len = 0; + success = 0; + } } else { *digest_type = SSHFP_HASH_RESERVED; *digest = NULL; *digest_len = 0; @@ -174,16 +188,17 @@ int verify_host_key_dns(const char *hostname, struct sockaddr *address, Key *hostkey, int *flags) { - - u_int counter; + u_int counter, i; int result; struct rrsetinfo *fingerprints = NULL; + u_char *hex_tmp; - - u_int8_t hostkey_algorithm; - - u_int8_t hostkey_digest_type; - - u_char *hostkey_digest; - - u_int hostkey_digest_len; + u_int8_t hostkey_algorithm[2]; + u_int8_t hostkey_digest_type[2] = { SSHFP_HASH_SHA1, SSHFP_HASH_SHA256 }; + u_char *hostkey_digest[2]; + u_int hostkey_digest_len[2]; u_int8_t dnskey_algorithm; u_int8_t dnskey_digest_type; u_char *dnskey_digest; @@ -216,13 +231,19 @@ fingerprints->rri_nrdatas); } /* Initialize 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; + for (i = 0; i < 2; i++) { + if (!dns_read_key(&hostkey_algorithm[i], &hostkey_digest_type[i], + &hostkey_digest[i], &hostkey_digest_len[i], hostkey)) { + error("Error calculating host key SHA1 fingerprint."); + freerrset(fingerprints); + return -1; + } + + hex_tmp = tohex(hostkey_digest[i], hostkey_digest_len[i]); + debug2("dns_read_key: %d %d %s", hostkey_algorithm[i], hostkey_digest_type[i], hex_tmp); + xfree(hex_tmp); } if (fingerprints->rri_nrdatas) *flags |= DNS_VERIFY_FOUND; @@ -239,27 +260,36 @@ verbose("Error parsing fingerprint from DNS."); continue; } - - /* 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 && - - memcmp(hostkey_digest, dnskey_digest, - - hostkey_digest_len) == 0) { + hex_tmp = tohex(dnskey_digest, dnskey_digest_len); + debug2("dns_read_rdata: %d %d %s", dnskey_algorithm, dnskey_digest_type, hex_tmp); + xfree(hex_tmp); - - *flags |= DNS_VERIFY_MATCH; + /* Check if the current key is the same as the given key */ + for (i = 0; i < 2; i++) { + if (hostkey_algorithm[i] == dnskey_algorithm && + hostkey_digest_type[i] == dnskey_digest_type) { + + if (hostkey_digest_len[i] == dnskey_digest_len && + memcmp(hostkey_digest[i], dnskey_digest, + hostkey_digest_len[i]) == 0) { + + *flags |= DNS_VERIFY_MATCH; + } else { + *flags |= DNS_VERIFY_MISMATCH; + } } } xfree(dnskey_digest); } - - xfree(hostkey_digest); /* from key_fingerprint_raw() */ + for (i = 0; i < 2; i++) + xfree(hostkey_digest[i]); /* from key_fingerprint_raw() */ freerrset(fingerprints); if (*flags & DNS_VERIFY_FOUND) - - if (*flags & DNS_VERIFY_MATCH) + if ((*flags & DNS_VERIFY_MATCH) && !(*flags & DNS_VERIFY_MISMATCH)) debug("matching host key fingerprint found in DNS"); else debug("mismatching host key fingerprint found in DNS"); else @@ -274,33 +304,35 @@ int export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) { u_int8_t rdata_pubkey_algorithm = 0; - - u_int8_t rdata_digest_type = SSHFP_HASH_SHA1; + u_int8_t rdata_digest_type[2] = { SSHFP_HASH_SHA1, SSHFP_HASH_SHA256 }; u_char *rdata_digest; u_int rdata_digest_len; - - u_int i; + u_int i, j; int success = 0; - - 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; - - } else { - - error("export_dns_rr: unsupported algorithm"); + for (i = 0; i < 2; i++) { + if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type[i], + &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[i]); + else + fprintf(f, "%s IN SSHFP %d %d ", hostname, + rdata_pubkey_algorithm, rdata_digest_type[i]); + + for (j = 0; j < rdata_digest_len; j++) + fprintf(f, "%02x", rdata_digest[j]); + fprintf(f, "\n"); + xfree(rdata_digest); /* from key_fingerprint_raw() */ + success = 1; + } else { + error("export_dns_rr: unsupported algorithm"); + } } return success; } diff -r -U4 openssh-5.8p2/dns.h openssh-5.8p2+sshfp3/dns.h - --- openssh-5.8p2/dns.h 2010-02-26 20:55:05.000000000 +0000 +++ openssh-5.8p2+sshfp3/dns.h 2011-08-16 20:47:50.000000000 +0100 @@ -30,22 +30,25 @@ enum sshfp_types { SSHFP_KEY_RESERVED, SSHFP_KEY_RSA, - - SSHFP_KEY_DSA + SSHFP_KEY_DSA, + SSHFP_KEY_ECDSA }; enum sshfp_hashes { SSHFP_HASH_RESERVED, - - SSHFP_HASH_SHA1 + SSHFP_HASH_SHA1, + SSHFP_HASH_SHA256 }; #define DNS_RDATACLASS_IN 1 #define DNS_RDATATYPE_SSHFP 44 #define DNS_VERIFY_FOUND 0x00000001 #define DNS_VERIFY_MATCH 0x00000002 #define DNS_VERIFY_SECURE 0x00000004 +#define DNS_VERIFY_MISMATCH 0x00000008 int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *); int export_dns_rr(const char *, Key *, FILE *, int); diff -r -U4 openssh-5.8p2/key.c openssh-5.8p2+sshfp3/key.c - --- openssh-5.8p2/key.c 2011-02-04 00:48:34.000000000 +0000 +++ openssh-5.8p2+sshfp3/key.c 2011-08-16 19:28:38.000000000 +0100 @@ -341,8 +341,11 @@ break; case SSH_FP_SHA1: md = EVP_sha1(); break; + case SSH_FP_SHA256: + md = EVP_sha256(); + break; default: fatal("key_fingerprint_raw: bad digest type %d", dgst_type); } diff -r -U4 openssh-5.8p2/key.h openssh-5.8p2+sshfp3/key.h - --- openssh-5.8p2/key.h 2010-11-04 23:19:49.000000000 +0000 +++ openssh-5.8p2+sshfp3/key.h 2011-08-16 19:28:44.000000000 +0100 @@ -47,9 +47,10 @@ KEY_UNSPEC }; enum fp_type { SSH_FP_SHA1, - - SSH_FP_MD5 + SSH_FP_MD5, + SSH_FP_SHA256 }; enum fp_rep { SSH_FP_HEX, SSH_FP_BUBBLEBABBLE, diff -r -U4 openssh-5.8p2/ssh-keygen.c openssh-5.8p2+sshfp3/ssh-keygen.c - --- openssh-5.8p2/ssh-keygen.c 2011-01-11 06:20:31.000000000 +0000 +++ openssh-5.8p2+sshfp3/ssh-keygen.c 2011-08-16 19:17:52.000000000 +0100 @@ -2061,8 +2061,10 @@ n += do_print_resource_record(pw, _PATH_HOST_RSA_KEY_FILE, rr_hostname); n += do_print_resource_record(pw, _PATH_HOST_DSA_KEY_FILE, rr_hostname); + n += do_print_resource_record(pw, + _PATH_HOST_ECDSA_KEY_FILE, rr_hostname); if (n == 0) fatal("no keys found."); exit(0); -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iQIcBAEBAgAGBQJOSsnQAAoJEKRtx1WjQ8ihEakQAJUEgoN+kFsrolnDyvOr9zTO 9FicIz+XQ4UwugtM5pJ0j/ZTgwTb4Z2uOHUbTsCGEMh5IAMfrAqpEEy32ihwAnT5 Z4sIlRbT9y7+NBzg05r7NnjXkT6zMJLdBMHDUJmdlw3yR+XoF67lcVgJaslFzzAk dhFUUfpXASkkh9qXdapZrnVXrq/7VO9QAyxEOsnES1i6q87pVhT6qftJS255QEIA nGy2nZzITs/fmgnjqrgrSCcKuo9IZ936FkOunRWLiz5GwBOIWRY496xGPYiNogjC 25BmheGQEoqxU2nQ93flhbJbmttkXHnlV2H2txuiSGGv9Z9weygEoYstYmtK8aEV 3k8u11X7Wy06mHIwCIelsK4r0rsHODA0Q9nLoQ/T/b6DGPfuQhiKnrH0NXM9tMXJ dtAWlhQloGdVNyqOTsUghsaTk7JzOB3NLQEIiV8KMB7XZJneci+W5Whu6iCu+zJi xX0bL9eCeJJ1awajFyMEBYpb4iu1UcrNugyk28cJ3oPPzFg/l0BGQllXdiJMc7t1 318e5+d0C3c2JawD3ara8iUXG5eVJ19SGKjsxxZHAve6ASWnsPGWUi1HkCb7Yeo9 F5kOQma/jE74YKwybjvweMgZNhesDFQyvsdLMI7uE9pqwqTq7eoXSf+li5Uo5wVW pQdSsRwPAdnDCWgi8u2p =7+dH -----END PGP SIGNATURE-----