From 28646fa9c74b94722eadd7bc2d9c285245aded80 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 20 Dec 2017 21:14:06 +0000 Subject: DANE/GnuTLS: ignore traditional CA anchor validation in DANE-EE mode Not quite right for a mixed TA+EE set of TLSA records, but better than always-enforcing --- src/src/tls-gnu.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 9f166691a..8c8a00f72 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -1573,7 +1573,7 @@ Returns: */ static BOOL -verify_certificate(exim_gnutls_state_st *state, uschar ** errstr) +verify_certificate(exim_gnutls_state_st * state, uschar ** errstr) { int rc; uint verify; @@ -1625,6 +1625,16 @@ else goto badcert; } state->peer_dane_verified = TRUE; + + /* If there were only EE-mode TLSA records present, no checks on cert anchor + valididation or cert names are required. For a TA record only, or a mixed + set, do them (we cannot tell if an EE record worked). */ + + if (!(tls_out.tlsa_usage & (1 << 2))) + { + state->peer_cert_verified = TRUE; + goto goodcert; + } } #endif @@ -1633,9 +1643,7 @@ else /* Handle the result of verification. INVALID is set if any others are. */ -if (rc < 0 || - verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED) - ) +if (rc < 0 || verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) { state->peer_cert_verified = FALSE; if (!*errstr) @@ -1676,8 +1684,9 @@ else state->peerdn ? state->peerdn : US""); } -state->tlsp->peerdn = state->peerdn; -return TRUE; +goodcert: + state->tlsp->peerdn = state->peerdn; + return TRUE; badcert: gnutls_alert_send(state->session, GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE); -- cgit v1.2.3