From 6fc0d9657d169aea8e05874c7f953f47c82deb33 Mon Sep 17 00:00:00 2001 From: manuel Date: Fri, 24 Jul 2015 14:16:16 +0200 Subject: update DANE support to libval 2.1 (+fixes) --- qmail-remote.c | 55 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/qmail-remote.c b/qmail-remote.c index ece335d..4119228 100644 --- a/qmail-remote.c +++ b/qmail-remote.c @@ -74,6 +74,7 @@ char **myargv; val_context_t *dane_context = NULL; int dane_context_failed = 0; struct val_danestatus *dane_status = NULL; +struct val_ssl_data *dane_ssl_data = NULL; #endif void out(s) char *s; { if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); } @@ -301,7 +302,7 @@ void smtp_quit() /* waiting for remote side is just too ridiculous */ } -void quit2(char *prepend, char *append, int flagdie) +void quit2(const char *prepend, const char *append, int flagdie) { smtp_quit(); out(prepend); @@ -430,25 +431,26 @@ int tls_init() int tls_required = (smtps || servercert != NULL); if (partner_fqdn && !servercert && !dane_context_failed) { - if (val_create_context(NULL, &dane_context) == VAL_NO_ERROR) { + if (dane_context == NULL && val_create_context(NULL, &dane_context) + != VAL_NO_ERROR) { + dane_context_failed = 1; + out("lUnable to initialize libval context\n"); + zeroflush(); + } + + if (dane_context) { + val_free_dane(dane_status); + val_free_dane_ssl(dane_ssl_data); + /* DANE: lookup TLSA records */ struct val_daneparams dane_params = { .port = smtp_port, .proto = DANE_PARAM_PROTO_TCP }; - if (dane_status != NULL) - val_free_dane(dane_status); dane_retval = val_getdaneinfo(dane_context, partner_fqdn, &dane_params, &dane_status); - if (dane_status == NULL) // insecure domain without TLSA RR will return VAL_DANE_NOERROR - dane_retval = VAL_DANE_CHECK_FAILED; - else if (dane_retval == VAL_DANE_NOERROR) + if (dane_retval == VAL_DANE_NOERROR) tls_required = 1; } - else { - dane_context_failed = 1; - out("lUnable to initialize libval context\n"); - zeroflush(); - } } if (!smtps) { @@ -480,6 +482,19 @@ int tls_init() /* set the callback here; SSL_set_verify didn't work before 0.9.6c */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb); } + else if (dane_retval == VAL_DANE_NOERROR) { + /* DANE: treat PKIX-EE as it were DANE-EE */ + struct val_danestatus *dane_cur; + for (dane_cur = dane_status; dane_cur; dane_cur = dane_cur->next) { + if (dane_cur->usage == DANE_USE_SVC_CONSTRAINT) + dane_cur->usage = DANE_USE_DOMAIN_ISSUED; + } + /* DANE: set verify callback */ + int err = val_enable_dane_ssl(dane_context, ctx, partner_fqdn, dane_status, + &dane_ssl_data); + if (err != VAL_NO_ERROR) + tls_quit("ZCould not enable dane verification", p_val_error(err)); + } /* let the other side complain if it needs a cert and we don't have one */ if (SSL_CTX_use_certificate_chain_file(ctx, CLIENTCERT)) @@ -532,10 +547,12 @@ int tls_init() if (tls_required) tls_quit("ZTLS connect failed", ssl_error_str()); else { - smtp_quit(); - - out("lTLS connect failed: "); - out(ssl_error_str()); + out("lTLS connect failed"); + const char *err = ssl_error_str(); + if (err) { + out(": "); + out(err); + } out("; retrying without TLS\n"); zeroflush(); @@ -597,11 +614,9 @@ int tls_init() X509_free(peercert); } - /* DANE: verify tls connection */ + /* DANE: verify result */ else if (dane_retval == VAL_DANE_NOERROR) { - int do_certcheck = 0; // ignored. DANE SMTP doesn't do any PKIX checks - dane_retval = val_dane_check(dane_context, ssl, dane_status, &do_certcheck); - if (dane_retval != VAL_DANE_NOERROR) { + if (!SSL_get_peer_certificate(ssl) || SSL_get_verify_result(ssl) != X509_V_OK) { out("lNo TLSA record matched: "); out(partner_fqdn); quit2("/", NULL, 0); -- cgit v1.2.3