diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/src/tls-gnu.c | 59 |
1 files changed, 50 insertions, 9 deletions
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index e2ac17c88..8aabc5c6c 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -176,6 +176,8 @@ static const char * const exim_default_gnutls_priority = "NORMAL"; static BOOL exim_gnutls_base_init_done = FALSE; +static BOOL gnutls_buggy_ocsp = FALSE; + /* ------------------------------------------------------------------------ */ /* macros */ @@ -831,18 +833,25 @@ if ( !host /* server */ && tls_ocsp_file ) { - if (!expand_check(tls_ocsp_file, US"tls_ocsp_file", - &state->exp_tls_ocsp_file)) - return DEFER; + if (gnutls_buggy_ocsp) + { + DEBUG(D_tls) debug_printf("GnuTLS library is buggy for OCSP; avoiding\n"); + } + else + { + if (!expand_check(tls_ocsp_file, US"tls_ocsp_file", + &state->exp_tls_ocsp_file)) + return DEFER; - /* Use the full callback method for stapling just to get observability. - More efficient would be to read the file once only, if it never changed - (due to SNI). Would need restart on file update, or watch datestamp. */ + /* Use the full callback method for stapling just to get observability. + More efficient would be to read the file once only, if it never changed + (due to SNI). Would need restart on file update, or watch datestamp. */ - gnutls_certificate_set_ocsp_status_request_function(state->x509_cred, - server_ocsp_stapling_cb, state->exp_tls_ocsp_file); + gnutls_certificate_set_ocsp_status_request_function(state->x509_cred, + server_ocsp_stapling_cb, state->exp_tls_ocsp_file); - DEBUG(D_tls) debug_printf("OCSP response file = %s\n", state->exp_tls_ocsp_file); + DEBUG(D_tls) debug_printf("OCSP response file = %s\n", state->exp_tls_ocsp_file); + } } #endif @@ -1011,6 +1020,35 @@ return OK; * Initialize for GnuTLS * *************************************************/ + +static BOOL +tls_is_buggy_ocsp(void) +{ +const uschar * s; +uschar maj, mid, mic; + +s = CUS gnutls_check_version(NULL); +maj = atoi(CCS s); +if (maj == 3) + { + while (*s && *s != '.') s++; + mid = atoi(CCS ++s); + if (mid <= 2) + return TRUE; + else if (mid >= 5) + return FALSE; + else + { + while (*s && *s != '.') s++; + mic = atoi(CCS ++s); + return mic <= (mid == 3 ? 16 : 3); + } + } +return FALSE; +} + + + /* Called from both server and client code. In the case of a server, errors before actual TLS negotiation return DEFER. @@ -1074,6 +1112,9 @@ if (!exim_gnutls_base_init_done) } #endif + if ((gnutls_buggy_ocsp = tls_is_buggy_ocsp())) + log_write(0, LOG_MAIN, "OCSP unusable with this GnuTLS library version"); + exim_gnutls_base_init_done = TRUE; } |