diff options
author | Colin Watson <cjwatson@debian.org> | 2012-09-06 23:20:10 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2012-09-06 23:20:10 +0100 |
commit | c6a2c0334e45419875687d250aed9bea78480f2e (patch) | |
tree | d8f01bef9f3921fa1ca7592a19474be9c8349f76 /dns.c | |
parent | dd5ed53e20d218607260916a6b04d1c8c5b3d88f (diff) | |
parent | 8b13b5bdc4f19bd52ee673104d66b71c21153b96 (diff) |
merge 6.1p1
Diffstat (limited to 'dns.c')
-rw-r--r-- | dns.c | 103 |
1 files changed, 69 insertions, 34 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: dns.c,v 1.27 2010/08/31 11:54:45 djm Exp $ */ | 1 | /* $OpenBSD: dns.c,v 1.28 2012/05/23 03:28:28 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2003 Wesley Griffin. All rights reserved. | 4 | * Copyright (c) 2003 Wesley Griffin. All rights reserved. |
@@ -78,27 +78,46 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, | |||
78 | u_char **digest, u_int *digest_len, Key *key) | 78 | u_char **digest, u_int *digest_len, Key *key) |
79 | { | 79 | { |
80 | int success = 0; | 80 | int success = 0; |
81 | enum fp_type fp_type = 0; | ||
81 | 82 | ||
82 | switch (key->type) { | 83 | switch (key->type) { |
83 | case KEY_RSA: | 84 | case KEY_RSA: |
84 | *algorithm = SSHFP_KEY_RSA; | 85 | *algorithm = SSHFP_KEY_RSA; |
86 | if (!*digest_type) | ||
87 | *digest_type = SSHFP_HASH_SHA1; | ||
85 | break; | 88 | break; |
86 | case KEY_DSA: | 89 | case KEY_DSA: |
87 | *algorithm = SSHFP_KEY_DSA; | 90 | *algorithm = SSHFP_KEY_DSA; |
91 | if (!*digest_type) | ||
92 | *digest_type = SSHFP_HASH_SHA1; | ||
93 | break; | ||
94 | case KEY_ECDSA: | ||
95 | *algorithm = SSHFP_KEY_ECDSA; | ||
96 | if (!*digest_type) | ||
97 | *digest_type = SSHFP_HASH_SHA256; | ||
88 | break; | 98 | break; |
89 | /* XXX KEY_ECDSA */ | ||
90 | default: | 99 | default: |
91 | *algorithm = SSHFP_KEY_RESERVED; /* 0 */ | 100 | *algorithm = SSHFP_KEY_RESERVED; /* 0 */ |
101 | *digest_type = SSHFP_HASH_RESERVED; /* 0 */ | ||
102 | } | ||
103 | |||
104 | switch (*digest_type) { | ||
105 | case SSHFP_HASH_SHA1: | ||
106 | fp_type = SSH_FP_SHA1; | ||
107 | break; | ||
108 | case SSHFP_HASH_SHA256: | ||
109 | fp_type = SSH_FP_SHA256; | ||
110 | break; | ||
111 | default: | ||
112 | *digest_type = SSHFP_HASH_RESERVED; /* 0 */ | ||
92 | } | 113 | } |
93 | 114 | ||
94 | if (*algorithm) { | 115 | if (*algorithm && *digest_type) { |
95 | *digest_type = SSHFP_HASH_SHA1; | 116 | *digest = key_fingerprint_raw(key, fp_type, digest_len); |
96 | *digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len); | ||
97 | if (*digest == NULL) | 117 | if (*digest == NULL) |
98 | fatal("dns_read_key: null from key_fingerprint_raw()"); | 118 | fatal("dns_read_key: null from key_fingerprint_raw()"); |
99 | success = 1; | 119 | success = 1; |
100 | } else { | 120 | } else { |
101 | *digest_type = SSHFP_HASH_RESERVED; | ||
102 | *digest = NULL; | 121 | *digest = NULL; |
103 | *digest_len = 0; | 122 | *digest_len = 0; |
104 | success = 0; | 123 | success = 0; |
@@ -180,7 +199,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, | |||
180 | struct rrsetinfo *fingerprints = NULL; | 199 | struct rrsetinfo *fingerprints = NULL; |
181 | 200 | ||
182 | u_int8_t hostkey_algorithm; | 201 | u_int8_t hostkey_algorithm; |
183 | u_int8_t hostkey_digest_type; | 202 | u_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED; |
184 | u_char *hostkey_digest; | 203 | u_char *hostkey_digest; |
185 | u_int hostkey_digest_len; | 204 | u_int hostkey_digest_len; |
186 | 205 | ||
@@ -216,7 +235,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, | |||
216 | fingerprints->rri_nrdatas); | 235 | fingerprints->rri_nrdatas); |
217 | } | 236 | } |
218 | 237 | ||
219 | /* Initialize host key parameters */ | 238 | /* Initialize default host key parameters */ |
220 | if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type, | 239 | if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type, |
221 | &hostkey_digest, &hostkey_digest_len, hostkey)) { | 240 | &hostkey_digest, &hostkey_digest_len, hostkey)) { |
222 | error("Error calculating host key fingerprint."); | 241 | error("Error calculating host key fingerprint."); |
@@ -240,16 +259,27 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, | |||
240 | continue; | 259 | continue; |
241 | } | 260 | } |
242 | 261 | ||
262 | if (hostkey_digest_type != dnskey_digest_type) { | ||
263 | hostkey_digest_type = dnskey_digest_type; | ||
264 | xfree(hostkey_digest); | ||
265 | |||
266 | /* Initialize host key parameters */ | ||
267 | if (!dns_read_key(&hostkey_algorithm, | ||
268 | &hostkey_digest_type, &hostkey_digest, | ||
269 | &hostkey_digest_len, hostkey)) { | ||
270 | error("Error calculating key fingerprint."); | ||
271 | freerrset(fingerprints); | ||
272 | return -1; | ||
273 | } | ||
274 | } | ||
275 | |||
243 | /* Check if the current key is the same as the given key */ | 276 | /* Check if the current key is the same as the given key */ |
244 | if (hostkey_algorithm == dnskey_algorithm && | 277 | if (hostkey_algorithm == dnskey_algorithm && |
245 | hostkey_digest_type == dnskey_digest_type) { | 278 | hostkey_digest_type == dnskey_digest_type) { |
246 | |||
247 | if (hostkey_digest_len == dnskey_digest_len && | 279 | if (hostkey_digest_len == dnskey_digest_len && |
248 | memcmp(hostkey_digest, dnskey_digest, | 280 | timingsafe_bcmp(hostkey_digest, dnskey_digest, |
249 | hostkey_digest_len) == 0) { | 281 | hostkey_digest_len) == 0) |
250 | |||
251 | *flags |= DNS_VERIFY_MATCH; | 282 | *flags |= DNS_VERIFY_MATCH; |
252 | } | ||
253 | } | 283 | } |
254 | xfree(dnskey_digest); | 284 | xfree(dnskey_digest); |
255 | } | 285 | } |
@@ -275,31 +305,36 @@ int | |||
275 | export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) | 305 | export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) |
276 | { | 306 | { |
277 | u_int8_t rdata_pubkey_algorithm = 0; | 307 | u_int8_t rdata_pubkey_algorithm = 0; |
278 | u_int8_t rdata_digest_type = SSHFP_HASH_SHA1; | 308 | u_int8_t rdata_digest_type = SSHFP_HASH_RESERVED; |
309 | u_int8_t dtype; | ||
279 | u_char *rdata_digest; | 310 | u_char *rdata_digest; |
280 | u_int rdata_digest_len; | 311 | u_int i, rdata_digest_len; |
281 | |||
282 | u_int i; | ||
283 | int success = 0; | 312 | int success = 0; |
284 | 313 | ||
285 | if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, | 314 | for (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) { |
286 | &rdata_digest, &rdata_digest_len, key)) { | 315 | rdata_digest_type = dtype; |
287 | 316 | if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, | |
288 | if (generic) | 317 | &rdata_digest, &rdata_digest_len, key)) { |
289 | fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", hostname, | 318 | if (generic) { |
290 | DNS_RDATATYPE_SSHFP, 2 + rdata_digest_len, | 319 | fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", |
291 | rdata_pubkey_algorithm, rdata_digest_type); | 320 | hostname, DNS_RDATATYPE_SSHFP, |
292 | else | 321 | 2 + rdata_digest_len, |
293 | fprintf(f, "%s IN SSHFP %d %d ", hostname, | 322 | rdata_pubkey_algorithm, rdata_digest_type); |
294 | rdata_pubkey_algorithm, rdata_digest_type); | 323 | } else { |
324 | fprintf(f, "%s IN SSHFP %d %d ", hostname, | ||
325 | rdata_pubkey_algorithm, rdata_digest_type); | ||
326 | } | ||
327 | for (i = 0; i < rdata_digest_len; i++) | ||
328 | fprintf(f, "%02x", rdata_digest[i]); | ||
329 | fprintf(f, "\n"); | ||
330 | xfree(rdata_digest); /* from key_fingerprint_raw() */ | ||
331 | success = 1; | ||
332 | } | ||
333 | } | ||
295 | 334 | ||
296 | for (i = 0; i < rdata_digest_len; i++) | 335 | /* No SSHFP record was generated at all */ |
297 | fprintf(f, "%02x", rdata_digest[i]); | 336 | if (success == 0) { |
298 | fprintf(f, "\n"); | 337 | error("%s: unsupported algorithm and/or digest_type", __func__); |
299 | xfree(rdata_digest); /* from key_fingerprint_raw() */ | ||
300 | success = 1; | ||
301 | } else { | ||
302 | error("export_dns_rr: unsupported algorithm"); | ||
303 | } | 338 | } |
304 | 339 | ||
305 | return success; | 340 | return success; |