r1837435, r1834553, r1833598, r1833452, r1833383, r1833368.
Undoes the following:
mod_ssl: OpenSSL now initializes fully through APR, use that.
mod_ssl: build with LibreSSL.
LibreSSL seems to be openssl-1.1 API compatible only in version 2.8 (master).
So use that for MODSSL_USE_OPENSSL_PRE_1_1_API instead of 2.7, the two 2.7
compatibility-exceptions are handled explicitely but overall it's simpler.
Regarding CRYPTO_malloc_init vs OPENSSL_malloc_init, libreSSL uses none, the
former used to be a no-op but depends is LIBRESSL_INTERNAL in latest versions,
while the latter has never been (and will never be) defined. So don't call any
with LibreSSL.
Follow up to r1833368: share openssl between modules.
Both libapr[-util], the core PRNG, mod_ssl, mod_crypto and mod_session_crypto
can use the same crypto library (e.g. openssl), use the new APR crypto loading
API so that they can work together and initialize/terminate the lib either once
for all or on demand and reusable by the others.
Follow up to r1833368: apr_crypto_prng_after_fork() now used a PID.
Make use of the new apr_crypto_rng API if available.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@
1861947 13f79535-47bb-0310-9956-
ffa450edef68
apr_status_t rv;
rv = apr_crypto_init(p);
- if (APR_SUCCESS != rv && APR_EREINIT != rv) {
+ if (APR_SUCCESS != rv) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
APLOGNO(03427) "APR crypto could not be initialised");
return rv;
apr_status_t rv;
rv = apr_crypto_init(p);
- if (APR_SUCCESS != rv && APR_EREINIT != rv) {
+ if (APR_SUCCESS != rv) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01843)
"APR crypto could not be initialised");
return rv;
#include "ap_provider.h"
#include "http_config.h"
-#include "apr_crypto.h"
-#include "apr_version.h"
-#if APR_VERSION_AT_LEAST(2,0,0) && \
- defined(APU_HAVE_CRYPTO) && APU_HAVE_CRYPTO && \
- defined(APU_HAVE_OPENSSL) && APU_HAVE_OPENSSL
-#define USE_APR_CRYPTO_LIB_INIT 1
-#else
-#define USE_APR_CRYPTO_LIB_INIT 0
-#endif
-
#include "mod_proxy.h" /* for proxy_hook_section_post_config() */
#include <assert.h>
return 0;
}
-#if !USE_APR_CRYPTO_LIB_INIT
static apr_status_t ssl_cleanup_pre_config(void *data)
{
/*
*/
return APR_SUCCESS;
}
-#endif /* !USE_APR_CRYPTO_LIB_INIT */
static int ssl_hook_pre_config(apr_pool_t *pconf,
apr_pool_t *plog,
#endif
modssl_running_statically = modssl_is_prelinked();
-#if USE_APR_CRYPTO_LIB_INIT
- {
- /* When mod_ssl is builtin, no need to unload openssl on restart,
- * so use pglobal.
- */
- apr_pool_t *p = modssl_running_statically ? ap_pglobal : pconf;
- apr_status_t rv = apr_crypto_lib_init("openssl", NULL, NULL, p);
- if (rv != APR_SUCCESS && rv != APR_EREINIT) {
- ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pconf, APLOGNO(10155)
- "mod_ssl: can't initialize OpenSSL library");
- return !OK;
- }
- }
-#else /* USE_APR_CRYPTO_LIB_INIT */
- {
- /* We must register the library in full, to ensure our configuration
- * code can successfully test the SSL environment.
- */
-/* Both undefined (or no-op) with LibreSSL */
-#if !defined(LIBRESSL_VERSION_NUMBER)
-#if MODSSL_USE_OPENSSL_PRE_1_1_API
- CRYPTO_malloc_init();
-#else
- OPENSSL_malloc_init();
-#endif
-#endif
- ERR_load_crypto_strings();
-#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
- ENGINE_load_builtin_engines();
-#endif
- OpenSSL_add_all_algorithms();
- OPENSSL_load_builtin_modules();
-
- SSL_load_error_strings();
- SSL_library_init();
-
- /*
- * Let us cleanup the ssl library when the module is unloaded
- */
- apr_pool_cleanup_register(pconf, NULL, ssl_cleanup_pre_config,
- apr_pool_cleanup_null);
- }
-
-#if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
/* Some OpenSSL internals are allocated per-thread, make sure they
- * are associated to the/our same thread-id until cleaned up. Then
- * initialize all the thread locking stuff needed by the lib.
+ * are associated to the/our same thread-id until cleaned up.
*/
+#if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
ssl_util_thread_id_setup(pconf);
- ssl_util_thread_setup(pconf);
#endif
-#endif /* USE_APR_CRYPTO_LIB_INIT */
+
+ /* We must register the library in full, to ensure our configuration
+ * code can successfully test the SSL environment.
+ */
+#if MODSSL_USE_OPENSSL_PRE_1_1_API || defined(LIBRESSL_VERSION_NUMBER)
+ (void)CRYPTO_malloc_init();
+#else
+ OPENSSL_malloc_init();
+#endif
+ ERR_load_crypto_strings();
+ SSL_load_error_strings();
+ SSL_library_init();
+#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
+ ENGINE_load_builtin_engines();
+#endif
+ OpenSSL_add_all_algorithms();
+ OPENSSL_load_builtin_modules();
if (OBJ_txt2nid("id-on-dnsSRV") == NID_undef) {
(void)OBJ_create("1.3.6.1.5.5.7.8.7", "id-on-dnsSRV",
/* Start w/o errors (e.g. OBJ_txt2nid() above) */
ERR_clear_error();
+ /*
+ * Let us cleanup the ssl library when the module is unloaded
+ */
+ apr_pool_cleanup_register(pconf, NULL, ssl_cleanup_pre_config,
+ apr_pool_cleanup_null);
+
/* Register us to handle mod_log_config %c/%x variables */
ssl_var_log_config_register(pconf);
#define KEYTYPES "RSA or DSA"
#endif
-#if MODSSL_USE_OPENSSL_PRE_1_1_API && (!defined(LIBRESSL_VERSION_NUMBER) || \
- LIBRESSL_VERSION_NUMBER < 0x2070000f)
+#if MODSSL_USE_OPENSSL_PRE_1_1_API
/* OpenSSL Pre-1.1.0 compatibility */
/* Taken from OpenSSL 1.1.0 snapshot 20160410 */
static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
#endif
}
+#if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
+ ssl_util_thread_setup(p);
+#endif
+
/*
* SSL external crypto device ("engine") support
*/
}
#endif
-#if MODSSL_USE_OPENSSL_PRE_1_1_API
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L)
/*
* Enable/disable SSLProtocol. If the mod_ssl enables protocol
* which is disabled by default by OpenSSL, show a warning.
char *cp;
int protocol = mctx->protocol;
SSLSrvConfigRec *sc = mySrvConfig(s);
-#if !MODSSL_USE_OPENSSL_PRE_1_1_API
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
+ (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x20800000L)
int prot;
#endif
SSL_CTX_set_options(ctx, SSL_OP_ALL);
-#if MODSSL_USE_OPENSSL_PRE_1_1_API
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L)
/* always disable SSLv2, as per RFC 6176 */
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_TLSv1_3,
protocol & SSL_PROTOCOL_TLSV1_3, "TLSv1.3");
#endif
-#endif /* MODSSL_USE_OPENSSL_PRE_1_1_API */
+#endif
#else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
/* We first determine the maximum protocol version we should provide */
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
#define SSL_CTX_set_max_proto_version(ctx, version) \
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
-#endif /* LIBRESSL_VERSION_NUMBER < 0x2060000f */
+#elif LIBRESSL_VERSION_NUMBER < 0x2070000f
/* LibreSSL before 2.7 declares OPENSSL_VERSION_NUMBER == 2.0 but does not
* include most changes from OpenSSL >= 1.1 (new functions, macros,
* deprecations, ...), so we have to work around this...
*/
-#define MODSSL_USE_OPENSSL_PRE_1_1_API (LIBRESSL_VERSION_NUMBER < 0x2080000f)
+#define MODSSL_USE_OPENSSL_PRE_1_1_API (1)
+#endif /* LIBRESSL_VERSION_NUMBER < 0x2060000f */
#else /* defined(LIBRESSL_VERSION_NUMBER) */
#define MODSSL_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
#endif
#include "apr_fnmatch.h"
#include "apr_hash.h"
#include "apr_thread_proc.h" /* for RLIMIT stuff */
-
-#include "apr_crypto.h"
-#if defined(APU_HAVE_CRYPTO) && APU_HAVE_CRYPTO && \
- defined(APU_HAVE_CRYPTO_PRNG) && APU_HAVE_CRYPTO_PRNG
-#define USE_APR_CRYPTO_PRNG 1
-#else
-#define USE_APR_CRYPTO_PRNG 0
#include "apr_random.h"
-#endif
#include "apr_version.h"
#if APR_MAJOR_VERSION < 2
}
-#if !USE_APR_CRYPTO_PRNG
static apr_random_t *rng = NULL;
#if APR_HAS_THREADS
static apr_thread_mutex_t *rng_mutex = NULL;
#endif
-#endif /* !USE_APR_CRYPTO_PRNG */
static void core_child_init(apr_pool_t *pchild, server_rec *s)
{
- /* The MPMs use plain fork() and not apr_proc_fork(), so we have to
- * take care of the random generator manually in the child.
- */
apr_proc_t proc;
-
- memset(&proc, 0, sizeof(proc));
- proc.pid = getpid();
-
-#if USE_APR_CRYPTO_PRNG
- apr_crypto_prng_after_fork(NULL, 1);
-#else
#if APR_HAS_THREADS
{
int threaded_mpm;
}
}
#endif
+ /* The MPMs use plain fork() and not apr_proc_fork(), so we have to call
+ * apr_random_after_fork() manually in the child
+ */
+ proc.pid = getpid();
apr_random_after_fork(&proc);
-#endif /* USE_APR_CRYPTO_PRNG */
}
static void core_optional_fn_retrieve(void)
AP_CORE_DECLARE(void) ap_random_parent_after_fork(void)
{
-#if !USE_APR_CRYPTO_PRNG
/*
* To ensure that the RNG state in the parent changes after the fork, we
* pull some data from the RNG and discard it. This ensures that the RNG
*/
apr_uint16_t data;
apr_random_insecure_bytes(rng, &data, sizeof(data));
-#endif /* !USE_APR_CRYPTO_PRNG */
}
AP_CORE_DECLARE(void) ap_init_rng(apr_pool_t *p)
{
+ unsigned char seed[8];
apr_status_t rv;
-
-#if USE_APR_CRYPTO_PRNG
- rv = apr_crypto_init(p);
-#else
- {
- unsigned char seed[8];
- rng = apr_random_standard_new(p);
- do {
- rv = apr_generate_random_bytes(seed, sizeof(seed));
- if (rv != APR_SUCCESS)
- break;
- apr_random_add_entropy(rng, seed, sizeof(seed));
- rv = apr_random_insecure_ready(rng);
- } while (rv == APR_ENOTENOUGHENTROPY);
- }
-#endif /* USE_APR_CRYPTO_PRNG */
-
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(00141)
- "Could not initialize random number generator");
- exit(1);
- }
+ rng = apr_random_standard_new(p);
+ do {
+ rv = apr_generate_random_bytes(seed, sizeof(seed));
+ if (rv != APR_SUCCESS)
+ goto error;
+ apr_random_add_entropy(rng, seed, sizeof(seed));
+ rv = apr_random_insecure_ready(rng);
+ } while (rv == APR_ENOTENOUGHENTROPY);
+ if (rv == APR_SUCCESS)
+ return;
+error:
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(00141)
+ "Could not initialize random number generator");
+ exit(1);
}
AP_DECLARE(void) ap_random_insecure_bytes(void *buf, apr_size_t size)
{
-#if USE_APR_CRYPTO_PRNG
- apr_crypto_random_bytes(buf, size);
-#else
#if APR_HAS_THREADS
if (rng_mutex)
apr_thread_mutex_lock(rng_mutex);
if (rng_mutex)
apr_thread_mutex_unlock(rng_mutex);
#endif
-#endif /* USE_APR_CRYPTO_PRNG */
}
/*