X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Ftls-openssl.c;h=e37b1add5001ad6ba8b6a2f02f07dee08f8b34df;hb=e5cccda9bbf169ea7dc97fa3859735523dd4cec0;hp=201636db046b34a354c33a7ba72358d129bc55e8;hpb=12ee8cf9db5b6c81b0e492c64f305d7ba1cf4dc2;p=exim.git diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 201636db0..e37b1add5 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -361,7 +361,7 @@ else return 0; /* reject */ } # endif -#endif +#endif /*EXPERIMENTAL_CERTNAMES*/ DEBUG(D_tls) debug_printf("SSL%s verify ok: depth=0 SN=%s\n", *calledp ? "" : " authenticated", txt); @@ -385,6 +385,28 @@ return verify_callback(state, x509ctx, &tls_in, &server_verify_callback_called, } +#ifdef EXPERIMENTAL_DANE +/* This gets called *by* the dane library verify callback, which interposes +itself. +*/ +static int +verify_callback_client_dane(int state, X509_STORE_CTX * x509ctx) +{ +X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx); +static uschar txt[256]; + +X509_NAME_oneline(X509_get_subject_name(cert), CS txt, sizeof(txt)); + +DEBUG(D_tls) debug_printf("verify_callback_client_dane: %s\n", txt); +tls_out.peerdn = txt; +tls_out.peercert = X509_dup(cert); + +if (state == 1) + tls_out.certificate_verified = TRUE; +return 1; +} +#endif + /************************************************* * Information callback * @@ -999,7 +1021,6 @@ return i; #endif /*!DISABLE_OCSP*/ - /************************************************* * Initialize for TLS * *************************************************/ @@ -1618,15 +1639,8 @@ BOOL dane_required; #endif #ifdef EXPERIMENTAL_DANE -/*XXX TBD: test for transport options, and for TLSA records */ -/*dane = TRUE;*/ - -# ifdef notyet dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL, host->name, host->address, NULL) == OK; -# else -dane_required = FALSE; -#endif if (host->dnssec == DS_YES) { @@ -1637,11 +1651,10 @@ if (host->dnssec == DS_YES) { /* move this out to host.c given the similarity to dns_lookup() ? */ uschar buffer[300]; - int prefix_length; /* why do we want this? */ uschar * fullname = buffer; /* TLSA lookup string */ - (void)sprintf(CS buffer, "_%d._tcp.%n%.256s", host->port, &prefix_length, + (void)sprintf(CS buffer, "_%d._tcp.%.256s", host->port, host->name); switch (rc = dns_lookup(&tlsa_dnsa, buffer, T_TLSA, &fullname)) @@ -1653,7 +1666,7 @@ if (host->dnssec == DS_YES) case DNS_FAIL: if (dane_required) { - /* log that TLSA lookup failed */ + log_write(0, LOG_MAIN, "DANE error: TLSA lookup failed"); return FAIL; } break; @@ -1661,7 +1674,7 @@ if (host->dnssec == DS_YES) case DNS_SUCCEED: if (!dns_is_secure(&tlsa_dnsa)) { - /*log it - tlsa should never be non-dnssec */ + log_write(0, LOG_MAIN, "DANE error: TLSA lookup not DNSSEC"); return DEFER; } dane = TRUE; @@ -1669,9 +1682,11 @@ if (host->dnssec == DS_YES) } } } -else if (dane_required && !dane) +else if (dane_required) { - /* log that dnssec pre-req failed. Hmm - what? */ + /*XXX a shame we only find this after making tcp & smtp connection */ + /* move the test earlier? */ + log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC"); return FAIL; } @@ -1719,10 +1734,12 @@ if (expciphers != NULL) #ifdef EXPERIMENTAL_DANE if (dane) { + SSL_CTX_set_verify(client_ctx, SSL_VERIFY_PEER, verify_callback_client_dane); + if (!DANESSL_library_init()) - return tls_error(US"library init", host, US"DANE library error"); + return tls_error(US"library init", host, NULL); if (DANESSL_CTX_init(client_ctx) <= 0) - return tls_error(US"context init", host, US"DANE library error"); + return tls_error(US"context init", host, NULL); } else @@ -1783,7 +1800,7 @@ if (dane) uschar * hostnames[2] = { host->name, NULL }; if (DANESSL_init(client_ssl, NULL, hostnames) != 1) - return tls_error(US"hostnames load", host, US"DANE library error"); + return tls_error(US"hostnames load", host, NULL); for (rr = dns_next_rr(&tlsa_dnsa, &dnss, RESET_ANSWERS); rr; @@ -1802,8 +1819,8 @@ if (dane) { default: /* log bad */ return FAIL; case 0: mdname = NULL; break; - case 1: mdname = "SHA2-256"; break; - case 2: mdname = "SHA2-512"; break; + case 1: mdname = "sha256"; break; + case 2: mdname = "sha512"; break; } switch (DANESSL_add_tlsa(client_ssl, @@ -1811,8 +1828,8 @@ if (dane) mdname, p, rr->size - (p - rr->data))) { default: - case 0: /* action not taken; log error */ - return FAIL; + case 0: /* action not taken */ + return tls_error(US"tlsa load", host, NULL); case 1: break; } }