From 9641b6648d2d2d87e14856f9c3383deb86772757 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 20 Aug 2022 16:43:03 +0100 Subject: [PATCH] OpenSSL: fix reload of changed OCSP proof --- doc/doc-txt/ChangeLog | 4 ++++ src/src/tls-openssl.c | 14 ++++++++++---- src/src/tls.c | 2 ++ test/confs/1102 | 4 +++- test/log/1102 | 2 +- test/scripts/1100-Basic-TLS/1102 | 19 +++++++++++-------- test/src/client.c | 4 +++- test/stdout/1102 | 4 ++-- 8 files changed, 36 insertions(+), 17 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index d17370589..6a4e10915 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -26,6 +26,10 @@ JH/05 Follow symlinks for placing a watch on TLS creds files. This means JH/06 Check for bad chars in rDNS for sender_host_name. The OpenBSD (at least) dn_expand() is happy to pass them through. +JH/07 OpenSSL Fix auto-reload of changed server OCSP proof. Previously, if + the file with the proof had an unchanged name, the new proof(s) were + loaded on top of the old ones (and nover used; the old ones were stapled). + Exim version 4.96 ----------------- diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index c46bc75a5..c63e56c0e 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1477,12 +1477,12 @@ return; static void -ocsp_free_response_list(exim_openssl_state_st * cbinfo) +ocsp_free_response_list(exim_openssl_state_st * state) { -for (ocsp_resplist * olist = cbinfo->u_ocsp.server.olist; olist; +for (ocsp_resplist * olist = state->u_ocsp.server.olist; olist; olist = olist->next) OCSP_RESPONSE_free(olist->resp); -cbinfo->u_ocsp.server.olist = NULL; +state->u_ocsp.server.olist = NULL; } #endif /*!DISABLE_OCSP*/ @@ -1574,6 +1574,11 @@ else if (olist && !*olist) olist = NULL; + /* If doing a re-expand after SNI, avoid reloading the OCSP + responses when the list of filenames has not changed. + The creds-invali on content change wipes file_expanded, so that + always reloads here. */ + if ( state->u_ocsp.server.file_expanded && olist && (Ustrcmp(olist, state->u_ocsp.server.file_expanded) == 0)) { @@ -1918,6 +1923,7 @@ tls_server_creds_invalidate(void) { SSL_CTX_free(state_server.lib_state.lib_ctx); state_server.lib_state = null_tls_preload; +state_server.u_ocsp.server.file_expanded = NULL; } @@ -2763,7 +2769,7 @@ if (state->lib_state.conn_certs) else { #ifndef DISABLE_OCSP - if (!host) + if (!host) /* server */ { state->u_ocsp.server.file = ocsp_file; state->u_ocsp.server.file_expanded = NULL; diff --git a/src/src/tls.c b/src/src/tls.c index 32b29ee3e..d7cefce67 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -361,6 +361,8 @@ tls_watch_invalidate(); #endif tls_server_creds_invalidate(); + +/* _expire is for a time-limited selfsign server cert */ tls_creds_expire = (lifetime = tls_server_creds_init()) ? time(NULL) + lifetime : 0; diff --git a/test/confs/1102 b/test/confs/1102 index 2bab6e804..23afc36ee 100644 --- a/test/confs/1102 +++ b/test/confs/1102 @@ -9,7 +9,9 @@ primary_hostname = myhost.test.ex tls_advertise_hosts = * tls_certificate = DIR/tmp/certs/servercert -tls_privatekey = DIR/tmp/certs/serverkey +tls_privatekey = DIR/tmp/certs/serverkey +tls_ocsp_file = DIR/tmp/certs/ocsp_proof + #tls_verify_certificates = DIR/aux-fixed/cert2 tls_verify_certificates = system,cache diff --git a/test/log/1102 b/test/log/1102 index 9bbca1052..89933f709 100644 --- a/test/log/1102 +++ b/test/log/1102 @@ -1,5 +1,5 @@ ******** SERVER ******** 2017-07-30 18:51:05.712 exim x.yz daemon started: pid=p1234, no queue runs, listening for SMTP on port PORT_D -2017-07-30 18:51:05.712 server cert: CN=Phil Pennock 2017-07-30 18:51:05.712 server cert: CN=server1.example.com +2017-07-30 18:51:05.712 server cert: CN=server1.example.net diff --git a/test/scripts/1100-Basic-TLS/1102 b/test/scripts/1100-Basic-TLS/1102 index 862d26a6e..285b3be09 100644 --- a/test/scripts/1100-Basic-TLS/1102 +++ b/test/scripts/1100-Basic-TLS/1102 @@ -2,13 +2,14 @@ # # mkdir -p DIR/tmp/certs -cp DIR/aux-fixed/cert1 DIR/tmp/certs/servercert -cp DIR/aux-fixed/cert1 DIR/tmp/certs/serverkey +cp DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.pem DIR/tmp/certs/servercert +cp DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key DIR/tmp/certs/serverkey +cp DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.good.resp DIR/tmp/certs/ocsp_proof # #exim -d-all+tls+receive+timestamp -DSERVER=server -bd -oX PORT_D exim -DSERVER=server -bd -oX PORT_D **** -client-anytls 127.0.0.1 PORT_D +client-anytls -ocsp DIR/aux-fixed/exim-ca/example.com/server1.example.com/ca_chain.pem 127.0.0.1 PORT_D ??? 220 EHLO rhu.barb ????250 @@ -24,12 +25,14 @@ QUIT ??? 221 **** sleep 1 -# Now overwrite the cert. key? -cp DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.pem DIR/tmp/certs/servercert -cp DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key DIR/tmp/certs/serverkey -# The watch mech waits 5 sec after the last trigger, so give that time to expire the send another message +# Now overwrite the cert +# XXX using server2.com fails here, on the ocsp verify. Why? +cp DIR/aux-fixed/exim-ca/example.net/server1.example.net/server1.example.net.pem DIR/tmp/certs/servercert +cp DIR/aux-fixed/exim-ca/example.net/server1.example.net/server1.example.net.unlocked.key DIR/tmp/certs/serverkey +cp DIR/aux-fixed/exim-ca/example.net/server1.example.net/server1.example.net.ocsp.good.resp DIR/tmp/certs/ocsp_proof +# The watch mech waits 5 sec after the last trigger, so give that time to expire then send another message sleep 7 -client-anytls 127.0.0.1 PORT_D +client-anytls -ocsp DIR/aux-fixed/exim-ca/example.net/server1.example.net/ca_chain.pem 127.0.0.1 PORT_D ??? 220 EHLO rhu.barb ????250 diff --git a/test/src/client.c b/test/src/client.c index 9beaf25bb..29712bb5e 100644 --- a/test/src/client.c +++ b/test/src/client.c @@ -802,6 +802,8 @@ nextinput: } fflush(stdout); } + else + printf("Succeeded in starting TLS (with OCSP)\n"); #endif } #endif @@ -1341,7 +1343,7 @@ if (tls_on_connect) printf("Failed to verify certificate status\n"); #endif else - printf("Succeeded in starting TLS\n"); + printf("Succeeded in starting TLS%s\n", ocsp_stapling ? " (with OCSP)":""); } #endif diff --git a/test/stdout/1102 b/test/stdout/1102 index 0e9c0b366..908c37d34 100644 --- a/test/stdout/1102 +++ b/test/stdout/1102 @@ -7,7 +7,7 @@ Connecting to 127.0.0.1 port 1225 ... connected ??? 220 <<< 220 TLS go ahead Attempting to start TLS -Succeeded in starting TLS +Succeeded in starting TLS (with OCSP) >>> EHLO rhu.barb ????250 >>> MAIL FROM:<> @@ -29,7 +29,7 @@ Connecting to 127.0.0.1 port 1225 ... connected ??? 220 <<< 220 TLS go ahead Attempting to start TLS -Succeeded in starting TLS +Succeeded in starting TLS (with OCSP) >>> EHLO rhu.barb ????250 >>> MAIL FROM:<> -- 2.30.2