* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2013 */
+/* Copyright (c) University of Cambridge 1995 - 2014 */
/* See the file NOTICE for conditions of use and distribution. */
/* Copyright (c) Phil Pennock 2012 */
*error = NULL;
-rc = peer_status(state);
-if (rc != OK)
+if ((rc = peer_status(state)) != OK)
{
verify = GNUTLS_CERT_INVALID;
- *error = "not supplied";
+ *error = "certificate not supplied";
}
else
- {
rc = gnutls_certificate_verify_peers2(state->session, &verify);
- }
/* Handle the result of verification. INVALID seems to be set as well
as REVOKED, but leave the test for both. */
-if ((rc < 0) || (verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
+if (rc < 0 || verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED))
{
state->peer_cert_verified = FALSE;
- if (*error == NULL)
- *error = ((verify & GNUTLS_CERT_REVOKED) != 0) ? "revoked" : "invalid";
+ if (!*error)
+ *error = verify & GNUTLS_CERT_REVOKED
+ ? "certificate revoked" : "certificate invalid";
DEBUG(D_tls)
debug_printf("TLS certificate verification failed (%s): peerdn=%s\n",
require_ciphers list of allowed ciphers or NULL
dh_min_bits minimum number of bits acceptable in server's DH prime
timeout startup timeout
+ verify_hosts mandatory client verification
+ try_verify_hosts optional client verification
Returns: OK/DEFER/FAIL (because using common functions),
but for a client, DEFER and FAIL have the same meaning
#ifdef EXPERIMENTAL_OCSP
uschar *require_ocsp ARG_UNUSED,
#endif
- int dh_min_bits, int timeout)
+ int dh_min_bits, int timeout,
+ uschar *verify_hosts, uschar *try_verify_hosts)
{
int rc;
const char *error;
dh_min_bits);
gnutls_dh_set_prime_bits(state->session, dh_min_bits);
-if (state->exp_tls_verify_certificates == NULL)
+/* stick to the old behaviour for compatibility if tls_verify_certificates is
+ set but both tls_verify_hosts and tls_try_verify_hosts is not set. Check only
+ the specified host patterns if one of them is defined */
+if (((state->exp_tls_verify_certificates != NULL) && (verify_hosts == NULL) && (try_verify_hosts == NULL)) ||
+ (verify_check_host(&verify_hosts) == OK))
{
- DEBUG(D_tls) debug_printf("TLS: server certificate verification not required\n");
- state->verify_requirement = VERIFY_NONE;
- /* we still ask for it, to log it, etc */
+ DEBUG(D_tls) debug_printf("TLS: server certificate verification required.\n");
+ state->verify_requirement = VERIFY_REQUIRED;
+ gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUIRE);
+ }
+else if (verify_check_host(&try_verify_hosts) == OK)
+ {
+ DEBUG(D_tls) debug_printf("TLS: server certificate verification optional.\n");
+ state->verify_requirement = VERIFY_OPTIONAL;
gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUEST);
}
else
{
- DEBUG(D_tls) debug_printf("TLS: server certificate verification required\n");
- state->verify_requirement = VERIFY_REQUIRED;
- gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUIRE);
+ DEBUG(D_tls) debug_printf("TLS: server certificate verification not required.\n");
+ state->verify_requirement = VERIFY_NONE;
+ gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_IGNORE);
}
gnutls_transport_set_ptr(state->session, (gnutls_transport_ptr)fd);