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,
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
{ "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 },
#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)
FALSE,/* tls_certificate_verified */
#ifdef EXPERIMENTAL_DANE
FALSE,/* dane_verified */
+ 0, /* tlsa_usage */
#endif
NULL, /* tls_cipher */
FALSE,/* tls_on_connect */
FALSE,/* tls_certificate_verified */
#ifdef EXPERIMENTAL_DANE
FALSE,/* dane_verified */
+ 0, /* tlsa_usage */
#endif
NULL, /* tls_cipher */
FALSE,/* tls_on_connect */
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 */
return tls_error(US"tlsa load", host, NULL);
case 1: break;
}
+
+ tls_out.tlsa_usage |= 1<<usage;
}
if (found)
#ifdef EXPERIMENTAL_DANE
tls_out.dane_verified = FALSE;
+tls_out.tlsa_usage = 0;
dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL,
host->name, host->address, NULL) == OK;
log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC");
return FAIL;
}
-
#endif
#ifndef DISABLE_OCSP
}
}
+#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);
}
#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. */
# hosts_try_dane = *
hosts_require_dane = *
+ hosts_request_ocsp = ${if or { {= {4}{$tls_out_tlsa_usage}} \
+ {= {0}{$tls_out_tlsa_usage}} } \
+ {*}{}}
# ----- Retry -----