From 594706ea2e56fe8c972eab772bd3e58c7a0c89ab Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 17 Aug 2014 00:41:17 +0100 Subject: [PATCH] Add observability variables and provision for avoiding OCSP conflicts --- doc/doc-txt/experimental-spec.txt | 25 +++++++++++++++++++++++- src/src/expand.c | 6 ++++++ src/src/globals.c | 2 ++ src/src/globals.h | 1 + src/src/tls-openssl.c | 32 ++++++++++++++++++++++++------- test/confs/5840 | 3 +++ 6 files changed, 61 insertions(+), 8 deletions(-) diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt index b1b89e007..c060a6c5a 100644 --- a/doc/doc-txt/experimental-spec.txt +++ b/doc/doc-txt/experimental-spec.txt @@ -1235,7 +1235,25 @@ must have a correct name (SubjectName or SubjectAltName). The use of OCSP-stapling should be considered, allowing for fast revocation of certificates (which would otherwise be limited by the DNS TTL on the TLSA records). However, -this is likely to only be usable with DANE_TA. +this is likely to only be usable with DANE_TA. NOTE: the +default is to request OCSP for all hosts; the certificate +chain in DANE_EE usage will be insufficient to validate +the OCSP proof and verification will fail. Either disable +OCSP completely or use the (new) variable $tls_out_tlsa_usage +like so: + + hosts_request_ocsp = ${if or { {= {4}{$tls_out_tlsa_usage}} \ + {= {0}{$tls_out_tlsa_usage}} } \ + {*}{}} +The variable is a bitfield with numbered bits set for TLSA +record usage codes. The zero above means DANE was not in use, +the four means that only DANE_TA usage TLSA records were +found. If the definition of hosts_require_ocsp or +hosts_request_ocsp includes the string "tls_out_tlsa_usage", +they are re-expanded in time to control the OCSP request. + +[ All a bit complicated. Should we make that definition +the default? Should we override the user's definition? ] For client-side DANE there are two new smtp transport options, @@ -1260,6 +1278,11 @@ and dnssec_require_domains is ignored. If verification was successful using DANE then the "CV" item in the delivery log line will show as "CV=dane". +There is a new variable $tls_out_dane which will have "yes" if +verification succeeded using DANE and "no" otherwise (only useful +in combination with EXPERIMENTAL_TPDA), and a new variable +$tls_out_tlsa_usage (detailed above). + -------------------------------------------------------------- End of file diff --git a/src/src/expand.c b/src/src/expand.c index e5af63d89..ba2c6f7cd 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -684,6 +684,9 @@ static var_entry var_table[] = { { "tls_out_bits", vtype_int, &tls_out.bits }, { "tls_out_certificate_verified", vtype_int,&tls_out.certificate_verified }, { "tls_out_cipher", vtype_stringptr, &tls_out.cipher }, +#ifdef EXPERIMENTAL_DANE + { "tls_out_dane", vtype_bool, &tls_out.dane_verified }, +#endif { "tls_out_ocsp", vtype_int, &tls_out.ocsp }, { "tls_out_ourcert", vtype_cert, &tls_out.ourcert }, { "tls_out_peercert", vtype_cert, &tls_out.peercert }, @@ -691,6 +694,9 @@ static var_entry var_table[] = { #if defined(SUPPORT_TLS) { "tls_out_sni", vtype_stringptr, &tls_out.sni }, #endif +#ifdef EXPERIMENTAL_DANE + { "tls_out_tlsa_usage", vtype_int, &tls_out.tlsa_usage }, +#endif { "tls_peerdn", vtype_stringptr, &tls_in.peerdn }, /* mind the alphabetical order! */ #if defined(SUPPORT_TLS) diff --git a/src/src/globals.c b/src/src/globals.c index d09903d65..409c324e9 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -105,6 +105,7 @@ tls_support tls_in = { FALSE,/* tls_certificate_verified */ #ifdef EXPERIMENTAL_DANE FALSE,/* dane_verified */ + 0, /* tlsa_usage */ #endif NULL, /* tls_cipher */ FALSE,/* tls_on_connect */ @@ -121,6 +122,7 @@ tls_support tls_out = { FALSE,/* tls_certificate_verified */ #ifdef EXPERIMENTAL_DANE FALSE,/* dane_verified */ + 0, /* tlsa_usage */ #endif NULL, /* tls_cipher */ FALSE,/* tls_on_connect */ diff --git a/src/src/globals.h b/src/src/globals.h index 654114848..1adda6411 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -84,6 +84,7 @@ typedef struct { BOOL certificate_verified; /* Client certificate verified */ #ifdef EXPERIMENTAL_DANE BOOL dane_verified; /* ... via DANE */ + int tlsa_usage; /* TLSA record(s) usage */ #endif uschar *cipher; /* Cipher used */ BOOL on_connect; /* For older MTAs that don't STARTTLS */ diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 144be6f63..57b0808fb 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1693,6 +1693,8 @@ for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); return tls_error(US"tlsa load", host, NULL); case 1: break; } + + tls_out.tlsa_usage |= 1<hosts_require_dane, NULL, host->name, host->address, NULL) == OK; @@ -1764,7 +1767,6 @@ else if (dane_required) log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC"); return FAIL; } - #endif #ifndef DISABLE_OCSP @@ -1855,9 +1857,31 @@ if (ob->tls_sni) } } +#ifdef EXPERIMENTAL_DANE +if (dane) + if ((rc = dane_tlsa_load(client_ssl, host, &tlsa_dnsa)) != OK) + return rc; +#endif + #ifndef DISABLE_OCSP /* Request certificate status at connection-time. If the server does OCSP stapling we will get the callback (set in tls_init()) */ +if (request_ocsp) + { + const uschar * s; + if ( (s = ob->hosts_require_ocsp) && Ustrstr(s, US"tls_out_tlsa_usage") + || (s = ob->hosts_request_ocsp) && Ustrstr(s, US"tls_out_tlsa_usage") + ) + { /* Re-eval now $tls_out_tlsa_usage is populated. If + this means we avoid the OCSP request, we wasted the setup + cost in tls_init(). */ + require_ocsp = verify_check_this_host(&ob->hosts_require_ocsp, + NULL, host->name, host->address, NULL) == OK; + request_ocsp = require_ocsp ? TRUE + : verify_check_this_host(&ob->hosts_request_ocsp, + NULL, host->name, host->address, NULL) == OK; + } + } if (request_ocsp) { SSL_set_tlsext_status_type(client_ssl, TLSEXT_STATUSTYPE_ocsp); @@ -1866,12 +1890,6 @@ if (request_ocsp) } #endif -#ifdef EXPERIMENTAL_DANE -if (dane) - if ((rc = dane_tlsa_load(client_ssl, host, &tlsa_dnsa)) != OK) - return rc; -#endif - /* There doesn't seem to be a built-in timeout on connection. */ diff --git a/test/confs/5840 b/test/confs/5840 index c381ef616..4359b9a59 100644 --- a/test/confs/5840 +++ b/test/confs/5840 @@ -67,6 +67,9 @@ send_to_server: # hosts_try_dane = * hosts_require_dane = * + hosts_request_ocsp = ${if or { {= {4}{$tls_out_tlsa_usage}} \ + {= {0}{$tls_out_tlsa_usage}} } \ + {*}{}} # ----- Retry ----- -- 2.25.1