From: Phil Pennock Date: Wed, 16 May 2012 16:35:40 +0000 (-0400) Subject: Merge branch 'experimental_ocsp' X-Git-Tag: exim-4_80_RC1~18 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/53947857fdb3c00bb673f6d2ac326dc4ccf01c6e?hp=-c Merge branch 'experimental_ocsp' --- 53947857fdb3c00bb673f6d2ac326dc4ccf01c6e diff --combined doc/doc-txt/ChangeLog index fdb0074ab,7c6ce246f..991f59f08 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@@ -91,22 -91,8 +91,24 @@@ PP/20 Revert part of NM/04, it broke lo PP/21 Defaulting "accept_8bitmime" to true, not false. -PP/22 Added EXPERIMENTAL_OCSP for OpenSSL. +PP/22 Added -bw for inetd wait mode support. + +PP/23 Added PCRE_CONFIG=yes support to Makefile for using pcre-config to + locate the relevant includes and libraries. Made this the default. + +PP/24 Fixed headers_only on smtp transports (was not sending trailing dot). + Bugzilla 1246, report and most of solution from Tomasz Kusy. + +JH/02 ${eval } now uses 64-bit and supports a "g" suffix (like to "k" and "m"). + This may cause build issues on older platforms. + +PP/25 Revamped GnuTLS support, passing tls_require_ciphers to + gnutls_priority_init, ignoring Exim options gnutls_require_kx, + gnutls_require_mac & gnutls_require_protocols (no longer supported). + Added SNI support via GnuTLS too. + ++PP/26 Added EXPERIMENTAL_OCSP for OpenSSL. + Exim version 4.77 ----------------- diff --combined doc/doc-txt/NewStuff index 57102958a,96839cde6..d41d79c83 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@@ -26,9 -26,6 +26,9 @@@ Version 4.7 "LOOKUP_LIBS" directly. Similarly for handling the TLS library support without adjusting "TLS_INCLUDE" and "TLS_LIBS". + In addition, setting PCRE_CONFIG=yes will query the pcre-config tool to + find the headers and libraries for PCRE. + 4. New expansion variable $tls_bits. 5. New lookup type, "dbmjz". Key is an Exim list, the elements of which will @@@ -57,29 -54,22 +57,37 @@@ A new log_selector, +tls_sni, has been added, to log received SNI values for Exim as a server. - Currently OpenSSL only. - 8. The existing "accept_8bitmime" option now defaults to true. This means that Exim is deliberately not strictly RFC compliant. We're following Dan Bernstein's advice in http://cr.yp.to/smtp/8bitmime.html by default. Those who disagree, or know that they are talking to mail servers that, even today, are not 8-bit clean, need to turn off this option. - 9. With OpenSSL, if built with EXPERIMENTAL_OCSP, a new option tls_ocsp_file + 9. Exim can now be started with -bw (with an optional timeout, given as + -bw). With this, stdin at startup is a socket that is + already listening for connections. This has a more modern name of + "socket activation", but forcing the activated socket to fd 0. We're + interested in adding more support for modern variants. + +10. ${eval } now uses 64-bit values on supporting platforms. A new "G" suffux + for numbers indicates multiplication by 1024^3. + +11. The GnuTLS support has been revamped; the three options gnutls_require_kx, + gnutls_require_mac & gnutls_require_protocols are no longer supported. + tls_require_ciphers is now parsed by gnutls_priority_init(3) as a priority + string, documentation for which is at: + http://www.gnu.org/software/gnutls/manual/html_node/Priority-Strings.html + + SNI support has been added to Exim's GnuTLS integration too. + ++12. With OpenSSL, if built with EXPERIMENTAL_OCSP, a new option tls_ocsp_file + is now available. If the contents of the file are valid, then Exim will + send that back in response to a TLS status request; this is OCSP Stapling. + Exim will not maintain the contents of the file in any way: administrators + are responsible for ensuring that it is up-to-date. + + See "experimental-spec.txt" for more details. + Version 4.77 ------------ diff --combined src/src/EDITME index d972e9c15,f4e788ae5..1f717a988 --- a/src/src/EDITME +++ b/src/src/EDITME @@@ -342,13 -342,10 +342,13 @@@ LOOKUP_DNSDB=ye # In either case you must specify the library link info here. If the # PCRE header files are not in the standard search path you must also # modify the INCLUDE path (above) -# The default setting of PCRE_LIBS should work on the vast majority of -# systems +# +# Use PCRE_CONFIG to query the pcre-config command (first found in $PATH) +# to find the include files and libraries, else use PCRE_LIBS and set INCLUDE +# too if needed. -PCRE_LIBS=-lpcre +# PCRE_CONFIG=yes +# PCRE_LIBS=-lpcre #------------------------------------------------------------------------------ @@@ -442,6 -439,11 +442,11 @@@ EXIM_MONITOR=eximon.bi # CFLAGS += -I/opt/brightmail/bsdk-6.0/include # LDFLAGS += -lxml2_single -lbmiclient_single -L/opt/brightmail/bsdk-6.0/lib + # Uncomment the following line to add OCSP stapling support in TLS, if Exim + # was built using OpenSSL. + + # EXPERIMENTAL_OCSP=yes + ############################################################################### diff --combined src/src/config.h.defaults index 61b2f38e0,a5e12d2ab..14dbd0a00 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@@ -158,10 -158,11 +158,11 @@@ it's a default value. * #define WITH_OLD_CLAMAV_STREAM /* EXPERIMENTAL features */ - #define EXPERIMENTAL_SPF - #define EXPERIMENTAL_SRS #define EXPERIMENTAL_BRIGHTMAIL #define EXPERIMENTAL_DCC + #define EXPERIMENTAL_OCSP + #define EXPERIMENTAL_SPF + #define EXPERIMENTAL_SRS /* Things that are not routinely changed but are nevertheless configurable just in case. */ @@@ -171,18 -172,4 +172,18 @@@ #define ROOT_UID 0 #define ROOT_GID 0 +/* Sizes for integer arithmetic. Go for 64bit; can be overridden in OS/os.h-FOO */ +#ifndef int_eximarith_t + #define int_eximarith_t int64_t +#endif +#ifndef PR_EXIM_ARITH + #define PR_EXIM_ARITH "%" PRId64 /* C99 standard, printf %lld */ +#endif +#ifndef SC_EXIM_ARITH + #define SC_EXIM_ARITH "%" SCNi64 /* scanf incl. 0x prefix */ +#endif +#ifndef SC_EXIM_DEC + #define SC_EXIM_DEC "%" SCNd64 /* scanf decimal */ +#endif + /* End of config.h.defaults */ diff --combined src/src/globals.c index d341ceb4a,5ea432912..666f5e78a --- a/src/src/globals.c +++ b/src/src/globals.c @@@ -112,11 -112,16 +112,14 @@@ uschar *tls_advertise_hosts = NULL uschar *tls_certificate = NULL; uschar *tls_crl = NULL; uschar *tls_dhparam = NULL; + #if defined(EXPERIMENTAL_OCSP) && !defined(USE_GNUTLS) + uschar *tls_ocsp_file = NULL; + #endif BOOL tls_offered = FALSE; uschar *tls_privatekey = NULL; BOOL tls_remember_esmtp = FALSE; uschar *tls_require_ciphers = NULL; -#ifndef USE_GNUTLS uschar *tls_sni = NULL; -#endif uschar *tls_try_verify_hosts = NULL; uschar *tls_verify_certificates= NULL; uschar *tls_verify_hosts = NULL; @@@ -657,8 -662,6 +660,8 @@@ uschar *hosts_connection_nolog = NULL int ignore_bounce_errors_after = 10*7*24*60*60; /* 10 weeks */ BOOL ignore_fromline_local = FALSE; uschar *ignore_fromline_hosts = NULL; +BOOL inetd_wait_mode = FALSE; +int inetd_wait_timeout = -1; uschar *interface_address = NULL; int interface_port = -1; BOOL is_inetd = FALSE; diff --combined src/src/globals.h index 37b0f6cf0,ec19d0a23..f0bc09f35 --- a/src/src/globals.h +++ b/src/src/globals.h @@@ -94,11 -94,16 +94,14 @@@ extern uschar *tls_certificate; extern uschar *tls_channelbinding_b64; /* string of base64 channel binding */ extern uschar *tls_crl; /* CRL File */ extern uschar *tls_dhparam; /* DH param file */ + #if defined(EXPERIMENTAL_OCSP) && !defined(USE_GNUTLS) + extern uschar *tls_ocsp_file; /* OCSP stapling proof file */ + #endif extern BOOL tls_offered; /* Server offered TLS */ extern uschar *tls_privatekey; /* Private key file */ extern BOOL tls_remember_esmtp; /* For YAEB */ extern uschar *tls_require_ciphers; /* So some can be avoided */ -#ifndef USE_GNUTLS extern uschar *tls_sni; /* Server Name Indication */ -#endif extern uschar *tls_try_verify_hosts; /* Optional client verification */ extern uschar *tls_verify_certificates;/* Path for certificates to check */ extern uschar *tls_verify_hosts; /* Mandatory client verification */ @@@ -422,8 -427,6 +425,8 @@@ extern uschar *hosts_treat_as_local; extern int ignore_bounce_errors_after; /* Keep them for this time. */ extern BOOL ignore_fromline_local; /* Local SMTP ignore fromline */ extern uschar *ignore_fromline_hosts; /* Hosts permitted to send "From " */ +extern BOOL inetd_wait_mode; /* Whether running in inetd wait mode */ +extern int inetd_wait_timeout; /* Timeout for inetd wait mode */ extern BOOL is_inetd; /* True for inetd calls */ extern uschar *iterate_item; /* Item from iterate list */ diff --combined src/src/readconf.c index cdd32be58,badb6a276..95e155ff3 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@@ -235,7 -235,6 +235,7 @@@ static optionlist optionlist_config[] { "gecos_pattern", opt_stringptr, &gecos_pattern }, #ifdef SUPPORT_TLS { "gnutls_compat_mode", opt_bool, &gnutls_compat_mode }, + /* These three gnutls_require_* options stopped working in Exim 4.78 */ { "gnutls_require_kx", opt_stringptr, &gnutls_require_kx }, { "gnutls_require_mac", opt_stringptr, &gnutls_require_mac }, { "gnutls_require_protocols", opt_stringptr, &gnutls_require_proto }, @@@ -416,6 -415,9 +416,9 @@@ { "tls_certificate", opt_stringptr, &tls_certificate }, { "tls_crl", opt_stringptr, &tls_crl }, { "tls_dhparam", opt_stringptr, &tls_dhparam }, + #if defined(EXPERIMENTAL_OCSP) && !defined(USE_GNUTLS) + { "tls_ocsp_file", opt_stringptr, &tls_ocsp_file }, + #endif { "tls_on_connect_ports", opt_stringptr, &tls_on_connect_ports }, { "tls_privatekey", opt_stringptr, &tls_privatekey }, { "tls_remember_esmtp", opt_bool, &tls_remember_esmtp }, diff --combined src/src/tls-openssl.c index 316fd5a90,9ead7945d..e485aa67d --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@@ -20,6 -20,14 +20,14 @@@ functions from the OpenSSL library. * #include #include #include + #ifdef EXPERIMENTAL_OCSP + #include + #endif + + #ifdef EXPERIMENTAL_OCSP + #define EXIM_OCSP_SKEW_SECONDS (300L) + #define EXIM_OCSP_MAX_AGE (-1L) + #endif /* Structure for collecting random data for seeding. */ @@@ -48,6 -56,11 +56,11 @@@ static BOOL reexpand_tls_files_for_s typedef struct tls_ext_ctx_cb { uschar *certificate; uschar *privatekey; + #ifdef EXPERIMENTAL_OCSP + uschar *ocsp_file; + uschar *ocsp_file_expanded; + OCSP_RESPONSE *ocsp_response; + #endif uschar *dhparam; /* these are cached from first expand */ uschar *server_cipher_list; @@@ -63,6 -76,12 +76,12 @@@ tls_ext_ctx_cb *static_cbinfo = NULL static int setup_certs(SSL_CTX *sctx, uschar *certs, uschar *crl, host_item *host, BOOL optional); + /* Callbacks */ + static int tls_servername_cb(SSL *s, int *ad ARG_UNUSED, void *arg); + #ifdef EXPERIMENTAL_OCSP + static int tls_stapling_cb(SSL *s, void *arg); + #endif + /************************************************* * Handle TLS error * @@@ -298,6 -317,131 +317,131 @@@ return yield + #ifdef EXPERIMENTAL_OCSP + /************************************************* + * Load OCSP information into state * + *************************************************/ + + /* Called to load the OCSP response from the given file into memory, once + caller has determined this is needed. Checks validity. Debugs a message + if invalid. + + ASSUMES: single response, for single cert. + + Arguments: + sctx the SSL_CTX* to update + cbinfo various parts of session state + expanded the filename putatively holding an OCSP response + + */ + + static void + ocsp_load_response(SSL_CTX *sctx, + tls_ext_ctx_cb *cbinfo, + const uschar *expanded) + { + BIO *bio; + OCSP_RESPONSE *resp; + OCSP_BASICRESP *basic_response; + OCSP_SINGLERESP *single_response; + ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; + X509_STORE *store; + unsigned long verify_flags; + int status, reason, i; + + cbinfo->ocsp_file_expanded = string_copy(expanded); + if (cbinfo->ocsp_response) + { + OCSP_RESPONSE_free(cbinfo->ocsp_response); + cbinfo->ocsp_response = NULL; + } + + bio = BIO_new_file(CS cbinfo->ocsp_file_expanded, "rb"); + if (!bio) + { + DEBUG(D_tls) debug_printf("Failed to open OCSP response file \"%s\"\n", + cbinfo->ocsp_file_expanded); + return; + } + + resp = d2i_OCSP_RESPONSE_bio(bio, NULL); + BIO_free(bio); + if (!resp) + { + DEBUG(D_tls) debug_printf("Error reading OCSP response.\n"); + return; + } + + status = OCSP_response_status(resp); + if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) + { + DEBUG(D_tls) debug_printf("OCSP response not valid: %s (%d)\n", + OCSP_response_status_str(status), status); + return; + } + + basic_response = OCSP_response_get1_basic(resp); + if (!basic_response) + { + DEBUG(D_tls) + debug_printf("OCSP response parse error: unable to extract basic response.\n"); + return; + } + + store = SSL_CTX_get_cert_store(sctx); + verify_flags = OCSP_NOVERIFY; /* check sigs, but not purpose */ + + /* May need to expose ability to adjust those flags? + OCSP_NOSIGS OCSP_NOVERIFY OCSP_NOCHAIN OCSP_NOCHECKS OCSP_NOEXPLICIT + OCSP_TRUSTOTHER OCSP_NOINTERN */ + + i = OCSP_basic_verify(basic_response, NULL, store, verify_flags); + if (i <= 0) + { + DEBUG(D_tls) { + ERR_error_string(ERR_get_error(), ssl_errstring); + debug_printf("OCSP response verify failure: %s\n", US ssl_errstring); + } + return; + } + + /* Here's the simplifying assumption: there's only one response, for the + one certificate we use, and nothing for anything else in a chain. If this + proves false, we need to extract a cert id from our issued cert + (tls_certificate) and use that for OCSP_resp_find_status() (which finds the + right cert in the stack and then calls OCSP_single_get0_status()). + + I'm hoping to avoid reworking a bunch more of how we handle state here. */ + single_response = OCSP_resp_get0(basic_response, 0); + if (!single_response) + { + DEBUG(D_tls) + debug_printf("Unable to get first response from OCSP basic response.\n"); + return; + } + + status = OCSP_single_get0_status(single_response, &reason, &rev, &thisupd, &nextupd); + /* how does this status differ from the one above? */ + if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) + { + DEBUG(D_tls) debug_printf("OCSP response not valid (take 2): %s (%d)\n", + OCSP_response_status_str(status), status); + return; + } + + if (!OCSP_check_validity(thisupd, nextupd, EXIM_OCSP_SKEW_SECONDS, EXIM_OCSP_MAX_AGE)) + { + DEBUG(D_tls) debug_printf("OCSP status invalid times.\n"); + return; + } + + cbinfo->ocsp_response = resp; + } + #endif + + + + /************************************************* * Expand key and cert file specs * *************************************************/ @@@ -314,7 -458,7 +458,7 @@@ Returns: OK/DEFER/FAI */ static int - tls_expand_session_files(SSL_CTX *sctx, const tls_ext_ctx_cb *cbinfo) + tls_expand_session_files(SSL_CTX *sctx, tls_ext_ctx_cb *cbinfo) { uschar *expanded; @@@ -352,6 -496,27 +496,27 @@@ if (expanded != NULL && *expanded != 0 "SSL_CTX_use_PrivateKey_file file=%s", expanded), cbinfo->host, NULL); } + #ifdef EXPERIMENTAL_OCSP + if (cbinfo->ocsp_file != NULL) + { + if (!expand_check(cbinfo->ocsp_file, US"tls_ocsp_file", &expanded)) + return DEFER; + + if (expanded != NULL && *expanded != 0) + { + DEBUG(D_tls) debug_printf("tls_ocsp_file %s\n", expanded); + if (cbinfo->ocsp_file_expanded && + (Ustrcmp(expanded, cbinfo->ocsp_file_expanded) == 0)) + { + DEBUG(D_tls) + debug_printf("tls_ocsp_file value unchanged, using existing values.\n"); + } else { + ocsp_load_response(sctx, cbinfo, expanded); + } + } + } + #endif + return OK; } @@@ -375,15 -540,11 +540,11 @@@ Arguments Returns: SSL_TLSEXT_ERR_{OK,ALERT_WARNING,ALERT_FATAL,NOACK} */ - static int - tls_servername_cb(SSL *s, int *ad ARG_UNUSED, void *arg); - /* pre-declared for SSL_CTX_set_tlsext_servername_callback call within func */ - static int tls_servername_cb(SSL *s, int *ad ARG_UNUSED, void *arg) { const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); - const tls_ext_ctx_cb *cbinfo = (tls_ext_ctx_cb *) arg; + tls_ext_ctx_cb *cbinfo = (tls_ext_ctx_cb *) arg; int rc; int old_pool = store_pool; @@@ -424,11 -585,20 +585,20 @@@ SSL_CTX_set_tlsext_servername_callback( SSL_CTX_set_tlsext_servername_arg(ctx_sni, cbinfo); if (cbinfo->server_cipher_list) SSL_CTX_set_cipher_list(ctx_sni, CS cbinfo->server_cipher_list); + #ifdef EXPERIMENTAL_OCSP + if (cbinfo->ocsp_file) + { + SSL_CTX_set_tlsext_status_cb(ctx_sni, tls_stapling_cb); + SSL_CTX_set_tlsext_status_arg(ctx, cbinfo); + } + #endif - rc = tls_expand_session_files(ctx_sni, cbinfo); + rc = setup_certs(ctx_sni, tls_verify_certificates, tls_crl, NULL, FALSE); if (rc != OK) return SSL_TLSEXT_ERR_NOACK; - rc = setup_certs(ctx_sni, tls_verify_certificates, tls_crl, NULL, FALSE); + /* do this after setup_certs, because this can require the certs for verifying + OCSP information. */ + rc = tls_expand_session_files(ctx_sni, cbinfo); if (rc != OK) return SSL_TLSEXT_ERR_NOACK; DEBUG(D_tls) debug_printf("Switching SSL context.\n"); @@@ -440,6 -610,45 +610,45 @@@ return SSL_TLSEXT_ERR_OK + #ifdef EXPERIMENTAL_OCSP + /************************************************* + * Callback to handle OCSP Stapling * + *************************************************/ + + /* Called when acting as server during the TLS session setup if the client + requests OCSP information with a Certificate Status Request. + + Documentation via openssl s_server.c and the Apache patch from the OpenSSL + project. + + */ + + static int + tls_stapling_cb(SSL *s, void *arg) + { + const tls_ext_ctx_cb *cbinfo = (tls_ext_ctx_cb *) arg; + uschar *response_der; + int response_der_len; + + DEBUG(D_tls) debug_printf("Received TLS status request (OCSP stapling); %s response.\n", + cbinfo->ocsp_response ? "have" : "lack"); + if (!cbinfo->ocsp_response) + return SSL_TLSEXT_ERR_NOACK; + + response_der = NULL; + response_der_len = i2d_OCSP_RESPONSE(cbinfo->ocsp_response, &response_der); + if (response_der_len <= 0) + return SSL_TLSEXT_ERR_NOACK; + + SSL_set_tlsext_status_ocsp_resp(ssl, response_der, response_der_len); + return SSL_TLSEXT_ERR_OK; + } + + #endif /* EXPERIMENTAL_OCSP */ + + + + /************************************************* * Initialize for TLS * *************************************************/ @@@ -459,7 -668,11 +668,11 @@@ Returns: OK/DEFER/FAI static int tls_init(host_item *host, uschar *dhparam, uschar *certificate, - uschar *privatekey, address_item *addr) + uschar *privatekey, + #ifdef EXPERIMENTAL_OCSP + uschar *ocsp_file, + #endif + address_item *addr) { long init_options; int rc; @@@ -469,6 -682,9 +682,9 @@@ tls_ext_ctx_cb *cbinfo cbinfo = store_malloc(sizeof(tls_ext_ctx_cb)); cbinfo->certificate = certificate; cbinfo->privatekey = privatekey; + #ifdef EXPERIMENTAL_OCSP + cbinfo->ocsp_file = ocsp_file; + #endif cbinfo->dhparam = dhparam; cbinfo->host = host; @@@ -546,7 -762,7 +762,7 @@@ els if (!init_dh(dhparam, host)) return DEFER; - /* Set up certificate and key */ + /* Set up certificate and key (and perhaps OCSP info) */ rc = tls_expand_session_files(ctx, cbinfo); if (rc != OK) return rc; @@@ -555,6 -771,17 +771,17 @@@ #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) if (host == NULL) { + #ifdef EXPERIMENTAL_OCSP + /* We check ocsp_file, not ocsp_response, because we care about if + the option exists, not what the current expansion might be, as SNI might + change the certificate and OCSP file in use between now and the time the + callback is invoked. */ + if (cbinfo->ocsp_file) + { + SSL_CTX_set_tlsext_status_cb(ctx, tls_stapling_cb); + SSL_CTX_set_tlsext_status_arg(ctx, cbinfo); + } + #endif /* We always do this, so that $tls_sni is available even if not used in tls_certificate */ SSL_CTX_set_tlsext_servername_callback(ctx, tls_servername_cb); @@@ -779,6 -1006,11 +1006,6 @@@ a TLS session Arguments: require_ciphers allowed ciphers - ------------------------------------------------------ - require_mac list of allowed MACs ) Not used - require_kx list of allowed key_exchange methods ) for - require_proto list of allowed protocols ) OpenSSL - ------------------------------------------------------ Returns: OK on success DEFER for errors before the start of the negotiation @@@ -787,7 -1019,8 +1014,7 @@@ */ int -tls_server_start(uschar *require_ciphers, uschar *require_mac, - uschar *require_kx, uschar *require_proto) +tls_server_start(const uschar *require_ciphers) { int rc; uschar *expciphers; @@@ -805,7 -1038,11 +1032,11 @@@ if (tls_active >= 0 /* Initialize the SSL library. If it fails, it will already have logged the error. */ - rc = tls_init(NULL, tls_dhparam, tls_certificate, tls_privatekey, NULL); + rc = tls_init(NULL, tls_dhparam, tls_certificate, tls_privatekey, + #ifdef EXPERIMENTAL_OCSP + tls_ocsp_file, + #endif + NULL); if (rc != OK) return rc; cbinfo = static_cbinfo; @@@ -813,9 -1050,8 +1044,9 @@@ if (!expand_check(require_ciphers, US"t return FAIL; /* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they -are separated by underscores. So that I can use either form in my tests, and -also for general convenience, we turn underscores into hyphens here. */ +were historically separated by underscores. So that I can use either form in my +tests, and also for general convenience, we turn underscores into hyphens here. +*/ if (expciphers != NULL) { @@@ -949,6 -1185,11 +1180,6 @@@ Argument verify_certs file for certificate verify crl file containing CRL require_ciphers list of allowed ciphers - ------------------------------------------------------ - require_mac list of allowed MACs ) Not used - require_kx list of allowed key_exchange methods ) for - require_proto list of allowed protocols ) OpenSSL - ------------------------------------------------------ timeout startup timeout Returns: OK on success @@@ -960,14 -1201,19 +1191,18 @@@ in tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam, uschar *certificate, uschar *privatekey, uschar *sni, uschar *verify_certs, uschar *crl, - uschar *require_ciphers, uschar *require_mac, uschar *require_kx, - uschar *require_proto, int timeout) + uschar *require_ciphers, int timeout) { static uschar txt[256]; uschar *expciphers; X509* server_cert; int rc; - rc = tls_init(host, dhparam, certificate, privatekey, addr); + rc = tls_init(host, dhparam, certificate, privatekey, + #ifdef EXPERIMENTAL_OCSP + NULL, + #endif + addr); if (rc != OK) return rc; tls_certificate_verified = FALSE; @@@ -1281,7 -1527,7 +1516,7 @@@ fprintf(f, "Library version: OpenSSL: C /************************************************* -* Pseudo-random number generation * +* Random number generation * *************************************************/ /* Pseudo-random number generation. The result is not expected to be @@@ -1296,7 -1542,7 +1531,7 @@@ Returns a random number in range [0 */ int -pseudo_random_number(int max) +vaguely_random_number(int max) { unsigned int r; int i, needed_len; @@@ -1332,14 -1578,7 +1567,14 @@@ if (i < needed_len needed_len = i; /* We do not care if crypto-strong */ -(void) RAND_pseudo_bytes(smallbuf, needed_len); +i = RAND_pseudo_bytes(smallbuf, needed_len); +if (i < 0) + { + DEBUG(D_all) + debug_printf("OpenSSL RAND_pseudo_bytes() not supported by RAND method, using fallback.\n"); + return vaguely_random_number_fallback(max); + } + r = 0; for (p = smallbuf; needed_len; --needed_len, ++p) {