X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/b50e778f1011c618e6f7fd73ac544a5903a29e1a..3c90bbcdc7cf73298156f7bcd5f5e750e7814e72:/src/src/tls-openssl.c diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 3f3fd8aa8..50384cbd5 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2019 */ +/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ /* Portions Copyright (c) The OpenSSL Project 1999 */ @@ -115,7 +116,7 @@ change this guard and punt the issue for a while longer. */ # define DISABLE_OCSP #endif -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME # if OPENSSL_VERSION_NUMBER < 0x0101010L # error OpenSSL version too old for session-resumption # endif @@ -291,7 +292,7 @@ for (struct exim_openssl_option * o = exim_openssl_options; builtin_macro_create(buf); } -# ifdef EXPERIMENTAL_TLS_RESUME +# ifndef DISABLE_TLS_RESUME builtin_macro_create_var(US"_RESUME_DECODE", RESUME_DECODE_STRING ); # endif # ifdef SSL_OP_NO_TLSv1_3 @@ -371,10 +372,10 @@ typedef struct ocsp_resp { } ocsp_resplist; typedef struct tls_ext_ctx_cb { - tls_support * tlsp; - uschar *certificate; - uschar *privatekey; - BOOL is_server; + tls_support * tlsp; + uschar * certificate; + uschar * privatekey; + BOOL is_server; #ifndef DISABLE_OCSP STACK_OF(X509) *verify_stack; /* chain for verifying the proof */ union { @@ -389,14 +390,14 @@ typedef struct tls_ext_ctx_cb { } client; } u_ocsp; #endif - uschar *dhparam; + uschar * dhparam; /* these are cached from first expand */ - uschar *server_cipher_list; + uschar * server_cipher_list; /* only passed down to tls_error: */ - host_item *host; + host_item * host; const uschar * verify_cert_hostnames; #ifndef DISABLE_EVENT - uschar * event_action; + uschar * event_action; #endif } tls_ext_ctx_cb; @@ -421,7 +422,7 @@ static int tls_server_stapling_cb(SSL *s, void *arg); /* Daemon-called, before every connection, key create/rotate */ -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME static void tk_init(void); static int tls_exdata_idx = -1; #endif @@ -429,7 +430,7 @@ static int tls_exdata_idx = -1; void tls_daemon_init(void) { -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME tk_init(); #endif return; @@ -495,7 +496,6 @@ RSA *rsa_key; BIGNUM *bn = BN_new(); #endif -export = export; /* Shut picky compilers up */ DEBUG(D_tls) debug_printf("Generating %d bit RSA key...\n", keylength); #ifdef EXIM_HAVE_RSA_GENKEY_EX @@ -890,7 +890,7 @@ fclose(fp); #endif -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME /* Manage the keysets used for encrypting the session tickets, on the server. */ typedef struct { /* Session ticket encryption key */ @@ -2175,12 +2175,12 @@ availability of the option value macros from OpenSSL. */ if (!tls_openssl_options_parse(openssl_options, &init_options)) return tls_error(US"openssl_options parsing failed", host, NULL, errstr); -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME tlsp->resumption = RESUME_SUPPORTED; #endif if (init_options) { -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME /* Should the server offer session resumption? */ if (!host && verify_check_host(&tls_resumption_hosts) == OK) { @@ -2684,12 +2684,12 @@ else if (verify_check_host(&tls_try_verify_hosts) == OK) server_verify_optional = TRUE; } -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, ticket_key_callback); /* despite working, appears to always return failure, so ignoring */ #endif #ifdef OPENSSL_HAVE_NUM_TICKETS -# ifdef EXPERIMENTAL_TLS_RESUME +# ifndef DISABLE_TLS_RESUME SSL_CTX_set_num_tickets(server_ctx, tls_in.host_resumable ? 1 : 0); # else SSL_CTX_set_num_tickets(server_ctx, 0); /* send no TLS1.3 stateful-tickets */ @@ -2737,6 +2737,7 @@ SSL_set_accept_state(server_ssl); DEBUG(D_tls) debug_printf("Calling SSL_accept\n"); +ERR_clear_error(); sigalrm_seen = FALSE; if (smtp_receive_timeout > 0) ALARM(smtp_receive_timeout); rc = SSL_accept(server_ssl); @@ -2766,6 +2767,9 @@ if (rc <= 0) uschar * s = US"SSL_accept"; int r = ERR_GET_REASON(ERR_peek_error()); if ( r == SSL_R_WRONG_VERSION_NUMBER +#ifdef SSL_R_VERSION_TOO_LOW + || r == SSL_R_VERSION_TOO_LOW +#endif || r == SSL_R_UNKNOWN_PROTOCOL || r == SSL_R_UNSUPPORTED_PROTOCOL) s = string_sprintf("%s (%s)", s, SSL_get_version(server_ssl)); (void) tls_error(s, NULL, sigalrm_seen ? US"timed out" : NULL, errstr); @@ -2783,7 +2787,10 @@ if (rc <= 0) } DEBUG(D_tls) debug_printf(" - syscall %s\n", strerror(errno)); } - (void) tls_error(US"SSL_accept", NULL, sigalrm_seen ? US"timed out" : NULL, errstr); + (void) tls_error(US"SSL_accept", NULL, + sigalrm_seen ? US"timed out" + : ERR_peek_error() ? NULL : string_sprintf("ret %d", error), + errstr); return FAIL; } } @@ -2792,7 +2799,7 @@ DEBUG(D_tls) debug_printf("SSL_accept was successful\n"); ERR_clear_error(); /* Even success can leave errors in the stack. Seen with anon-authentication ciphersuite negotiated. */ -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME if (SSL_session_reused(server_ssl)) { tls_in.resumption |= RESUME_USED; @@ -2911,9 +2918,9 @@ if (verify_check_given_host(CUSS &ob->tls_verify_cert_hostnames, host) == OK) { cbinfo->verify_cert_hostnames = #ifdef SUPPORT_I18N - string_domain_utf8_to_alabel(host->name, NULL); + string_domain_utf8_to_alabel(host->certname, NULL); #else - host->name; + host->certname; #endif DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n", cbinfo->verify_cert_hostnames); @@ -2979,7 +2986,7 @@ return DEFER; -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME /* On the client, get any stashed session for the given IP from hints db and apply it to the ssl-connection for attempted resumption. */ @@ -3141,7 +3148,7 @@ if (SSL_session_reused(exim_client_ctx->ssl)) tlsp->resumption |= RESUME_USED; } } -#endif /* EXPERIMENTAL_TLS_RESUME */ +#endif /* !DISABLE_TLS_RESUME */ /************************************************* @@ -3290,7 +3297,7 @@ else client_static_cbinfo, errstr) != OK) return FALSE; -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME tls_client_ctx_resume_prehandshake(exim_client_ctx, tlsp, ob, host); #endif @@ -3361,7 +3368,7 @@ if (request_ocsp) } #endif -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME if (!tls_client_ssl_resume_prehandshake(exim_client_ctx->ssl, tlsp, host, errstr)) return FALSE; @@ -3402,7 +3409,7 @@ DEBUG(D_tls) #endif } -#ifdef EXPERIMENTAL_TLS_RESUME +#ifndef DISABLE_TLS_RESUME tls_client_resume_posthandshake(exim_client_ctx, tlsp); #endif @@ -3454,6 +3461,7 @@ int inbytes; DEBUG(D_tls) debug_printf("Calling SSL_read(%p, %p, %u)\n", server_ssl, ssl_xfer_buffer, ssl_xfer_buffer_size); +ERR_clear_error(); if (smtp_receive_timeout > 0) ALARM(smtp_receive_timeout); inbytes = SSL_read(server_ssl, CS ssl_xfer_buffer, MIN(ssl_xfer_buffer_size, lim)); @@ -3603,6 +3611,7 @@ int error; DEBUG(D_tls) debug_printf("Calling SSL_read(%p, %p, %u)\n", ssl, buff, (unsigned int)len); +ERR_clear_error(); inbytes = SSL_read(ssl, CS buff, len); error = SSL_get_error(ssl, inbytes); @@ -3692,6 +3701,7 @@ if ((more || corked)) for (int left = len; left > 0;) { DEBUG(D_tls) debug_printf("SSL_write(%p, %p, %d)\n", ssl, buff, left); + ERR_clear_error(); outbytes = SSL_write(ssl, CS buff, left); error = SSL_get_error(ssl, outbytes); DEBUG(D_tls) debug_printf("outbytes=%d error=%d\n", outbytes, error);