*/
static BOOL
-verify_certificate(exim_gnutls_state_st *state, uschar ** errstr)
+verify_certificate(exim_gnutls_state_st * state, uschar ** errstr)
{
int rc;
uint verify;
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
/* 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)
state->peerdn ? state->peerdn : US"<unset>");
}
-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);