From 3674140cddab39c76f4cd360a4b5c102e94d4759 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 20 Dec 2017 23:12:07 +0000 Subject: [PATCH] DANE/GnuTLS: filter TLSA records for usability --- src/src/tls-gnu.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 8c8a00f72..1fee6c107 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -2084,7 +2084,7 @@ use in DANE verification. We point at the dnsa data not copy it, so it must remain valid until after verification is done.*/ -static void +static BOOL dane_tlsa_load(exim_gnutls_state_st * state, dns_answer * dnsa) { dns_record * rr; @@ -2107,17 +2107,37 @@ for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS), i = 0; ) if (rr->type == T_TLSA) { const uschar * p = rr->data; - uint8_t usage = *p; + uint8_t usage = p[0], sel = p[1], type = p[2]; + + DEBUG(D_tls) + debug_printf("TLSA: %d %d %d size %d\n", usage, sel, type, rr->size); + + if (usage != 2 && usage != 3) continue; + if (sel != 0 && sel != 1) continue; + switch(type) + { + case 0: /* Full: cannot check at present */ + break; + case 1: if (rr->size != 3 + 256/8) continue; /* sha2-256 */ + break; + case 2: if (rr->size != 3 + 512/8) continue; /* sha2-512 */ + break; + default: continue; + } tls_out.tlsa_usage |= 1<size; } + +if (!i) return FALSE; + dane_data[i] = NULL; dane_data_len[i] = 0; state->dane_data = (char * const *)dane_data; state->dane_data_len = dane_data_len; +return TRUE; } #endif @@ -2194,13 +2214,12 @@ set but both tls_verify_hosts and tls_try_verify_hosts are unset. Check only the specified host patterns if one of them is defined */ #ifdef SUPPORT_DANE -if (tlsa_dnsa) +if (tlsa_dnsa && dane_tlsa_load(state, tlsa_dnsa)) { DEBUG(D_tls) debug_printf("TLS: server certificate DANE required.\n"); state->verify_requirement = VERIFY_DANE; gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUIRE); - dane_tlsa_load(state, tlsa_dnsa); } else #endif -- 2.25.1