/* only passed down to tls_error: */
host_item *host;
const uschar * verify_cert_hostnames;
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
uschar * event_action;
#endif
} tls_ext_ctx_cb;
*/
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
static int
verify_event(tls_support * tlsp, X509 * cert, int depth, const uschar * dn,
BOOL *calledp, const BOOL *optionalp, const uschar * what)
ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action;
if (ev)
{
+ DEBUG(D_tls) debug_printf("verify_event: %s %d\n", what, depth);
old_cert = tlsp->peercert;
tlsp->peercert = X509_dup(cert);
/* NB we do not bother setting peerdn */
for a given "depth" in the certificate chain.
Arguments:
- state current yes/no state as 1/0
- x509ctx certificate information.
- client TRUE for client startup, FALSE for server startup
+ preverify_ok current yes/no state as 1/0
+ x509ctx certificate information.
+ tlsp per-direction (client vs. server) support data
+ calledp has-been-called flag
+ optionalp verification-is-optional flag
-Returns: 1 if verified, 0 if not
+Returns: 0 if verification should fail, otherwise 1
*/
static int
-verify_callback(int state, X509_STORE_CTX *x509ctx,
+verify_callback(int preverify_ok, X509_STORE_CTX *x509ctx,
tls_support *tlsp, BOOL *calledp, BOOL *optionalp)
{
X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
X509_NAME_oneline(X509_get_subject_name(cert), CS dn, sizeof(dn));
dn[sizeof(dn)-1] = '\0';
-if (state == 0)
+if (preverify_ok == 0)
{
log_write(0, LOG_MAIN, "[%s] SSL verify error: depth=%d error=%s cert=%s",
tlsp == &tls_out ? deliver_host_address : sender_host_address,
{ /* client, wanting stapling */
/* Add the server cert's signing chain as the one
for the verification of the OCSP stapled information. */
-
+
if (!X509_STORE_add_cert(client_static_cbinfo->u_ocsp.client.verify_store,
cert))
ERR_clear_error();
}
#endif
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (verify_event(tlsp, cert, depth, dn, calledp, optionalp, US"SSL"))
return 0; /* reject, with peercert set */
#endif
}
}
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (verify_event(tlsp, cert, depth, dn, calledp, optionalp, US"SSL"))
return 0; /* reject, with peercert set */
#endif
}
static int
-verify_callback_client(int state, X509_STORE_CTX *x509ctx)
+verify_callback_client(int preverify_ok, X509_STORE_CTX *x509ctx)
{
-return verify_callback(state, x509ctx, &tls_out, &client_verify_callback_called, &client_verify_optional);
+return verify_callback(preverify_ok, x509ctx, &tls_out,
+ &client_verify_callback_called, &client_verify_optional);
}
static int
-verify_callback_server(int state, X509_STORE_CTX *x509ctx)
+verify_callback_server(int preverify_ok, X509_STORE_CTX *x509ctx)
{
-return verify_callback(state, x509ctx, &tls_in, &server_verify_callback_called, &server_verify_optional);
+return verify_callback(preverify_ok, x509ctx, &tls_in,
+ &server_verify_callback_called, &server_verify_optional);
}
itself.
*/
static int
-verify_callback_client_dane(int state, X509_STORE_CTX * x509ctx)
+verify_callback_client_dane(int preverify_ok, X509_STORE_CTX * x509ctx)
{
X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
uschar dn[256];
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
int depth = X509_STORE_CTX_get_error_depth(x509ctx);
BOOL dummy_called, optional = FALSE;
#endif
X509_NAME_oneline(X509_get_subject_name(cert), CS dn, sizeof(dn));
dn[sizeof(dn)-1] = '\0';
-DEBUG(D_tls) debug_printf("verify_callback_client_dane: %s\n", dn);
+DEBUG(D_tls) debug_printf("verify_callback_client_dane: %s depth %d %s\n",
+ preverify_ok ? "ok":"BAD", depth, dn);
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (verify_event(&tls_out, cert, depth, dn,
&dummy_called, &optional, US"DANE"))
return 0; /* reject, with peercert set */
#endif
-if (state == 1)
+if (preverify_ok == 1)
tls_out.dane_verified =
tls_out.certificate_verified = TRUE;
-return 1;
+else
+ {
+ int err = X509_STORE_CTX_get_error(x509ctx);
+ DEBUG(D_tls)
+ debug_printf(" - err %d '%s'\n", err, X509_verify_cert_error_string(err));
+ if (err = X509_V_ERR_APPLICATION_VERIFICATION)
+ preverify_ok = 1;
+ }
+return preverify_ok;
}
#endif /*EXPERIMENTAL_DANE*/
static BOOL
init_ecdh(SSL_CTX * sctx, host_item * host)
{
+#ifdef OPENSSL_NO_ECDH
+return TRUE;
+#else
+
EC_KEY * ecdh;
uschar * exp_curve;
int nid;
BOOL rv;
-#ifdef OPENSSL_NO_ECDH
-return TRUE;
-#else
-
if (host) /* No ECDH setup for clients, only for servers */
return TRUE;
if (!(ecdh = EC_KEY_new_by_curve_name(nid)))
{
- tls_error("Unable to create ec curve", host, NULL);
+ tls_error(US"Unable to create ec curve", host, NULL);
return FALSE;
}
if(!p)
{
/* Expect this when we requested ocsp but got none */
- if ( cbinfo->u_ocsp.client.verify_required
- && log_extra_selector & LX_tls_cipher)
+ if (cbinfo->u_ocsp.client.verify_required && LOGGING(tls_cipher))
log_write(0, LOG_MAIN, "Received TLS status callback, null content");
else
DEBUG(D_tls) debug_printf(" null\n");
if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
{
tls_out.ocsp = OCSP_FAILED;
- if (log_extra_selector & LX_tls_cipher)
+ if (LOGGING(tls_cipher))
log_write(0, LOG_MAIN, "Received TLS cert status response, parse error");
else
DEBUG(D_tls) debug_printf(" parse error\n");
if(!(bs = OCSP_response_get1_basic(rsp)))
{
tls_out.ocsp = OCSP_FAILED;
- if (log_extra_selector & LX_tls_cipher)
+ if (LOGGING(tls_cipher))
log_write(0, LOG_MAIN, "Received TLS cert status response, error parsing response");
else
DEBUG(D_tls) debug_printf(" error parsing response\n");
cbinfo->u_ocsp.client.verify_store, 0)) <= 0)
{
tls_out.ocsp = OCSP_FAILED;
- if (log_extra_selector & LX_tls_cipher)
+ if (LOGGING(tls_cipher))
log_write(0, LOG_MAIN, "Received TLS cert status response, itself unverifiable");
BIO_printf(bp, "OCSP response verify failure\n");
ERR_print_errors(bp);
cbinfo->dhparam = dhparam;
cbinfo->server_cipher_list = NULL;
cbinfo->host = host;
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
cbinfo->event_action = NULL;
#endif
certificates are recognized, but the error message is still misleading (it
says no certificate was supplied.) But this is better. */
- if ((file == NULL || statbuf.st_size > 0) &&
- !SSL_CTX_load_verify_locations(sctx, CS file, CS dir))
+ if ( (!file || statbuf.st_size > 0)
+ && !SSL_CTX_load_verify_locations(sctx, CS file, CS dir))
return tls_error(US"SSL_CTX_load_verify_locations", host, NULL);
/* Load the list of CAs for which we will accept certs, for sending
Because of this, and that the dir variant is likely only used for
the public-CA bundle (not for a private CA), not worth fixing.
*/
- if (file != NULL)
+ if (file)
{
STACK_OF(X509_NAME) * names = SSL_load_client_CA_file(CS file);
- DEBUG(D_tls) debug_printf("Added %d certificate authorities.\n",
+
+ DEBUG(D_tls) debug_printf("Added %d certificate authorities.\n",
sk_X509_NAME_num(names));
SSL_CTX_set_client_CA_list(sctx, names);
}
)
{
int rc;
-/* stick to the old behaviour for compatibility if tls_verify_certificates is
+/* 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 (verify_check_given_host(&ob->tls_verify_cert_hostnames, host) == OK)
{
cbinfo->verify_cert_hostnames =
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
string_domain_utf8_to_alabel(host->name, NULL);
#else
host->name;
}
#endif
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
client_static_cbinfo->event_action = tb->event_action;
#endif