Commit f1fa6989 authored by Yann Ylavic's avatar Yann Ylavic
Browse files

Make use of the new apr_crypto_rng API if available.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1833368 13f79535-47bb-0310-9956-ffa450edef68
parent 933b0a67
Loading
Loading
Loading
Loading
+41 −9
Changes for server/core.c: 41 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -20,7 +20,14 @@
#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_PRNG) && APU_HAVE_CRYPTO_PRNG
#define USE_APR_CRYPTO_PRNG 1
#else
#define USE_APR_CRYPTO_PRNG 0
#include "apr_random.h"
#endif

#define APR_WANT_IOVEC
#define APR_WANT_STRFUNC
@@ -5436,13 +5443,21 @@ AP_DECLARE(int) ap_state_query(int query)
    }
}

#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.
     */
#if USE_APR_CRYPTO_PRNG
    apr_crypto_prng_after_fork();
#else
    apr_proc_t proc;
#if APR_HAS_THREADS
    int threaded_mpm;
@@ -5451,12 +5466,10 @@ static void core_child_init(apr_pool_t *pchild, server_rec *s)
    {
        apr_thread_mutex_create(&rng_mutex, APR_THREAD_MUTEX_DEFAULT, pchild);
    }
#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
#endif /* USE_APR_CRYPTO_PRNG */
}

static void core_optional_fn_retrieve(void)
@@ -5466,6 +5479,7 @@ 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
@@ -5477,30 +5491,47 @@ AP_CORE_DECLARE(void) ap_random_parent_after_fork(void)
     */
    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
    {
        int flags = 0;
#if APR_HAS_THREADS
        flags = APR_CRYPTO_PRNG_PER_THREAD;
#endif
        rv = apr_crypto_prng_init(p, 0, NULL, flags);
    }
#else /* USE_APR_CRYPTO_PRNG */
    {
        unsigned char seed[8];
        rng = apr_random_standard_new(p);
        do {
            rv = apr_generate_random_bytes(seed, sizeof(seed));
            if (rv != APR_SUCCESS)
            goto error;
                break;
            apr_random_add_entropy(rng, seed, sizeof(seed));
            rv = apr_random_insecure_ready(rng);
        } while (rv == APR_ENOTENOUGHENTROPY);
    if (rv == APR_SUCCESS)
        return;
error:
    }
#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);
    }
}

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);
@@ -5514,6 +5545,7 @@ AP_DECLARE(void) ap_random_insecure_bytes(void *buf, apr_size_t size)
    if (rng_mutex)
        apr_thread_mutex_unlock(rng_mutex);
#endif
#endif /* USE_APR_CRYPTO_PRNG */
}

/*