It compiles with OpenSSL, on Darwin (if restore Darwin OS).
It doesn't crash immediately, but more testing is needed from a place
where port 25 is not just blocked.
option.
+.new
+.option dane_require_tls_ciphers smtp string&!! unset
+.cindex "TLS" "requiring specific ciphers for DANE"
+.cindex "cipher" "requiring specific"
+.cindex DANE "TLS ciphers"
+This option may be used to override &%tls_require_ciphers%& for connections
+where DANE has been determined to be in effect.
+If not set, then &%tls_require_ciphers%& will be used.
+Normal SMTP delivery is not able to make strong demands of TLS cipher
+configuration, because delivery will fall back to plaintext. Once DANE has
+been determined to be in effect, there is no plaintext fallback and making the
+TLS cipherlist configuration stronger will increase security, rather than
+counter-intuitively decreasing it.
+If the option expands to be empty or is forced to fail, then it will
+be treated as unset and &%tls_require_ciphers%& will be used instead.
+.wen
+
+
.option data_timeout smtp time 5m
This sets a timeout for the transmission of each block in the data portion of
the message. As a result, the overall timeout for a message depends on the size
1, 0))
|| (rc = dane_verify_crt_raw(s, certlist, lsize,
gnutls_certificate_type_get(state->session),
- r, 0,
+ r, 0,
# ifdef GNUTLS_BROKEN_DANE_VALIDATION
usage == (1 << DANESSL_USAGE_DANE_EE)
? DANE_VFLAG_ONLY_CHECK_EE_USAGE : 0,
(smtp_transport_options_block *)tb->options_block;
int rc;
exim_gnutls_state_st * state = NULL;
+uschar *cipher_list = NULL;
#ifndef DISABLE_OCSP
BOOL require_ocsp =
verify_check_given_host(&ob->hosts_require_ocsp, host) == OK;
DEBUG(D_tls) debug_printf("initialising GnuTLS as a client on fd %d\n", fd);
+#ifdef SUPPORT_DANE
+if (ob->dane_require_tls_ciphers)
+ {
+ /* not using expand_check_tlsvar because not yet in state */
+ if (!expand_check(ob->dane_require_tls_ciphers, US"dane_require_tls_ciphers",
+ &cipher_list, errstr))
+ return DEFER;
+ if (cipher_list && *cipher_list)
+ cipher_list = ob->dane_require_tls_ciphers;
+ else
+ cipher_list = ob->tls_require_ciphers;
+ }
+#endif
+
+if (!cipher_list)
+ cipher_list = ob->tls_require_ciphers;
+
if ((rc = tls_init(host, ob->tls_certificate, ob->tls_privatekey,
ob->tls_sni, ob->tls_verify_certificates, ob->tls_crl,
- ob->tls_require_ciphers, &state, errstr)) != OK)
+ cipher_list, &state, errstr)) != OK)
return rc;
{
SNI handling.
Separately we might try to replace using OCSP_basic_verify() - which seems to not
-be a public interface into the OpenSSL library (there's no manual entry) -
+be a public interface into the OpenSSL library (there's no manual entry) -
But what with? We also use OCSP_basic_verify in the client stapling callback.
And there we NEED it; we must verify that status... unless the
library does it for us anyway? */
tls_out.certificate_verified = FALSE;
client_verify_callback_called = FALSE;
-if (!expand_check(ob->tls_require_ciphers, US"tls_require_ciphers",
- &expciphers, errstr))
+expciphers = NULL;
+#ifdef SUPPORT_DANE
+if (tlsa_dnsa)
+ {
+ /* We fall back to tls_require_ciphers if unset, empty or forced failure, but
+ other failures should be treated as problems. */
+ if (ob->dane_require_tls_ciphers &&
+ !expand_check(ob->dane_require_tls_ciphers, US"dane_require_tls_ciphers",
+ &expciphers, errstr))
+ return FAIL;
+ if (expciphers && *expciphers == '\0')
+ expciphers = NULL;
+ }
+#endif
+if (!expciphers &&
+ !expand_check(ob->tls_require_ciphers, US"tls_require_ciphers",
+ &expciphers, errstr))
return FAIL;
/* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
(void *)offsetof(smtp_transport_options_block, connect_timeout) },
{ "connection_max_messages", opt_int | opt_public,
(void *)offsetof(transport_instance, connection_max_messages) },
+# ifdef SUPPORT_DANE
+ { "dane_require_tls_ciphers", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block, dane_require_tls_ciphers) },
+# endif
{ "data_timeout", opt_time,
(void *)offsetof(smtp_transport_options_block, data_timeout) },
{ "delay_after_cutoff", opt_bool,
#ifdef SUPPORT_DANE
.hosts_try_dane = NULL,
.hosts_require_dane = NULL,
+ .dane_require_tls_ciphers = NULL,
#endif
.hosts_try_fastopen = NULL,
#ifndef DISABLE_PRDR
#ifdef SUPPORT_DANE
uschar *hosts_try_dane;
uschar *hosts_require_dane;
+ uschar *dane_require_tls_ciphers;
#endif
uschar *hosts_try_fastopen;
#ifndef DISABLE_PRDR