Blame modules/ssl/ssl_util.c

Packit 90a5c9
/* Licensed to the Apache Software Foundation (ASF) under one or more
Packit 90a5c9
 * contributor license agreements.  See the NOTICE file distributed with
Packit 90a5c9
 * this work for additional information regarding copyright ownership.
Packit 90a5c9
 * The ASF licenses this file to You under the Apache License, Version 2.0
Packit 90a5c9
 * (the "License"); you may not use this file except in compliance with
Packit 90a5c9
 * the License.  You may obtain a copy of the License at
Packit 90a5c9
 *
Packit 90a5c9
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 90a5c9
 *
Packit 90a5c9
 * Unless required by applicable law or agreed to in writing, software
Packit 90a5c9
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 90a5c9
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 90a5c9
 * See the License for the specific language governing permissions and
Packit 90a5c9
 * limitations under the License.
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
/*                      _             _
Packit 90a5c9
 *  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
Packit 90a5c9
 * | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
Packit 90a5c9
 * | | | | | | (_) | (_| |   \__ \__ \ |
Packit 90a5c9
 * |_| |_| |_|\___/ \__,_|___|___/___/_|
Packit 90a5c9
 *                      |_____|
Packit 90a5c9
 *  ssl_util.c
Packit 90a5c9
 *  Utility Functions
Packit 90a5c9
 */
Packit 90a5c9
                             /* ``Every day of my life
Packit 90a5c9
                                  I am forced to add another
Packit 90a5c9
                                  name to the list of people
Packit 90a5c9
                                  who piss me off!''
Packit 90a5c9
                                            -- Calvin          */
Packit 90a5c9
Packit 90a5c9
#include "ssl_private.h"
Packit 90a5c9
#include "ap_mpm.h"
Packit 90a5c9
#include "apr_thread_mutex.h"
Packit 90a5c9
Packit 90a5c9
/*  _________________________________________________________________
Packit 90a5c9
**
Packit 90a5c9
**  Utility Functions
Packit 90a5c9
**  _________________________________________________________________
Packit 90a5c9
*/
Packit 90a5c9
Packit 90a5c9
char *ssl_util_vhostid(apr_pool_t *p, server_rec *s)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc;
Packit 90a5c9
    apr_port_t port;
Packit 90a5c9
Packit 90a5c9
    if (s->port != 0)
Packit 90a5c9
        port = s->port;
Packit 90a5c9
    else {
Packit 90a5c9
        sc = mySrvConfig(s);
Packit 90a5c9
        port = sc->enabled == TRUE ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return apr_psprintf(p, "%s:%lu", s->server_hostname, (unsigned long)port);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 * Return TRUE iff the given servername matches the server record when
Packit 90a5c9
 * selecting virtual hosts.
Packit 90a5c9
 */
Packit 90a5c9
BOOL ssl_util_vhost_matches(const char *servername, server_rec *s)
Packit 90a5c9
{
Packit 90a5c9
    apr_array_header_t *names;
Packit 90a5c9
    int i;
Packit 90a5c9
    
Packit 90a5c9
    /* check ServerName */
Packit 90a5c9
    if (!strcasecmp(servername, s->server_hostname)) {
Packit 90a5c9
        return TRUE;
Packit 90a5c9
    }
Packit 90a5c9
    
Packit 90a5c9
    /*
Packit 90a5c9
     * if not matched yet, check ServerAlias entries
Packit 90a5c9
     * (adapted from vhost.c:matches_aliases())
Packit 90a5c9
     */
Packit 90a5c9
    names = s->names;
Packit 90a5c9
    if (names) {
Packit 90a5c9
        char **name = (char **)names->elts;
Packit 90a5c9
        for (i = 0; i < names->nelts; ++i) {
Packit 90a5c9
            if (!name[i])
Packit 90a5c9
                continue;
Packit 90a5c9
            if (!strcasecmp(servername, name[i])) {
Packit 90a5c9
                return TRUE;
Packit 90a5c9
            }
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
    
Packit 90a5c9
    /* if still no match, check ServerAlias entries with wildcards */
Packit 90a5c9
    names = s->wild_names;
Packit 90a5c9
    if (names) {
Packit 90a5c9
        char **name = (char **)names->elts;
Packit 90a5c9
        for (i = 0; i < names->nelts; ++i) {
Packit 90a5c9
            if (!name[i])
Packit 90a5c9
                continue;
Packit 90a5c9
            if (!ap_strcasecmp_match(servername, name[i])) {
Packit 90a5c9
                return TRUE;
Packit 90a5c9
            }
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
    
Packit 90a5c9
    return FALSE;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd,
Packit 90a5c9
                            const char * const *argv)
Packit 90a5c9
{
Packit 90a5c9
    apr_procattr_t *procattr;
Packit 90a5c9
    apr_proc_t *proc;
Packit 90a5c9
Packit 90a5c9
    if (apr_procattr_create(&procattr, p) != APR_SUCCESS)
Packit 90a5c9
        return NULL;
Packit 90a5c9
    if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK,
Packit 90a5c9
                            APR_FULL_BLOCK) != APR_SUCCESS)
Packit 90a5c9
        return NULL;
Packit 90a5c9
    if (apr_procattr_dir_set(procattr,
Packit 90a5c9
                             ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS)
Packit 90a5c9
        return NULL;
Packit 90a5c9
    if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
Packit 90a5c9
        return NULL;
Packit 90a5c9
    proc = apr_pcalloc(p, sizeof(apr_proc_t));
Packit 90a5c9
    if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
Packit 90a5c9
        return NULL;
Packit 90a5c9
    return proc->out;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
void ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp)
Packit 90a5c9
{
Packit 90a5c9
    apr_file_close(fp);
Packit 90a5c9
    return;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 * Run a filter program and read the first line of its stdout output
Packit 90a5c9
 */
Packit 90a5c9
char *ssl_util_readfilter(server_rec *s, apr_pool_t *p, const char *cmd,
Packit 90a5c9
                          const char * const *argv)
Packit 90a5c9
{
Packit 90a5c9
    static char buf[MAX_STRING_LEN];
Packit 90a5c9
    apr_file_t *fp;
Packit 90a5c9
    apr_size_t nbytes = 1;
Packit 90a5c9
    char c;
Packit 90a5c9
    int k;
Packit 90a5c9
Packit 90a5c9
    if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL)
Packit 90a5c9
        return NULL;
Packit 90a5c9
    /* XXX: we are reading 1 byte at a time here */
Packit 90a5c9
    for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
Packit 90a5c9
                && nbytes == 1 && (k < MAX_STRING_LEN-1)     ; ) {
Packit 90a5c9
        if (c == '\n' || c == '\r')
Packit 90a5c9
            break;
Packit 90a5c9
        buf[k++] = c;
Packit 90a5c9
    }
Packit 90a5c9
    buf[k] = NUL;
Packit 90a5c9
    ssl_util_ppclose(s, p, fp);
Packit 90a5c9
Packit 90a5c9
    return buf;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
Packit 90a5c9
{
Packit 90a5c9
    apr_finfo_t finfo;
Packit 90a5c9
Packit 90a5c9
    if (path == NULL)
Packit 90a5c9
        return FALSE;
Packit 90a5c9
    if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path,
Packit 90a5c9
                                APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
Packit 90a5c9
        return FALSE;
Packit 90a5c9
    AP_DEBUG_ASSERT((pcm & SSL_PCM_EXISTS) ||
Packit 90a5c9
                    !(pcm & (SSL_PCM_ISREG|SSL_PCM_ISDIR|SSL_PCM_ISNONZERO)));
Packit 90a5c9
    if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
Packit 90a5c9
        return FALSE;
Packit 90a5c9
    if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
Packit 90a5c9
        return FALSE;
Packit 90a5c9
    if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0)
Packit 90a5c9
        return FALSE;
Packit 90a5c9
    return TRUE;
Packit 90a5c9
}
Packit 90a5c9
Packit 70c855
/* Decrypted private keys are cached to survive restarts.  The cached
Packit 70c855
 * data must have lifetime of the process (hence malloc/free rather
Packit 70c855
 * than pools), and uses raw DER since the EVP_PKEY structure
Packit 70c855
 * internals may not survive across a module reload. */
Packit 70c855
ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key,
Packit 70c855
                               EVP_PKEY *pkey)
Packit 90a5c9
{
Packit 90a5c9
    apr_ssize_t klen = strlen(key);
Packit 90a5c9
    ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
Packit 70c855
    apr_size_t length = i2d_PrivateKey(pkey, NULL);
Packit 70c855
    unsigned char *p;
Packit 90a5c9
Packit 70c855
    /* Re-use structure if cached previously. */
Packit 90a5c9
    if (asn1) {
Packit 90a5c9
        if (asn1->nData != length) {
Packit 70c855
            asn1->cpData = ap_realloc(asn1->cpData, length);
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        asn1 = ap_malloc(sizeof(*asn1));
Packit 90a5c9
        asn1->source_mtime = 0; /* used as a note for encrypted private keys */
Packit 90a5c9
        asn1->cpData = ap_malloc(length);
Packit 70c855
Packit 70c855
        apr_hash_set(table, key, klen, asn1);
Packit 90a5c9
    }
Packit 90a5c9
Packit 70c855
    asn1->nData = length;
Packit 70c855
    p = asn1->cpData;
Packit 70c855
    i2d_PrivateKey(pkey, &p); /* increases p by length */
Packit 90a5c9
Packit 70c855
    return asn1;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
Packit 90a5c9
                               const char *key)
Packit 90a5c9
{
Packit 90a5c9
    return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
void ssl_asn1_table_unset(apr_hash_t *table,
Packit 90a5c9
                          const char *key)
Packit 90a5c9
{
Packit 90a5c9
    apr_ssize_t klen = strlen(key);
Packit 90a5c9
    ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
Packit 90a5c9
Packit 90a5c9
    if (!asn1) {
Packit 90a5c9
        return;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (asn1->cpData) {
Packit 90a5c9
        free(asn1->cpData);
Packit 90a5c9
    }
Packit 90a5c9
    free(asn1);
Packit 90a5c9
Packit 90a5c9
    apr_hash_set(table, key, klen, NULL);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 * To ensure thread-safetyness in OpenSSL - work in progress
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
static apr_thread_mutex_t **lock_cs;
Packit 90a5c9
static int                  lock_num_locks;
Packit 90a5c9
Packit 90a5c9
static void ssl_util_thr_lock(int mode, int type,
Packit 90a5c9
                              const char *file, int line)
Packit 90a5c9
{
Packit 90a5c9
    if (type < lock_num_locks) {
Packit 90a5c9
        if (mode & CRYPTO_LOCK) {
Packit 90a5c9
            apr_thread_mutex_lock(lock_cs[type]);
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            apr_thread_mutex_unlock(lock_cs[type]);
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/* Dynamic lock structure */
Packit 90a5c9
struct CRYPTO_dynlock_value {
Packit 90a5c9
    apr_pool_t *pool;
Packit 90a5c9
    const char* file;
Packit 90a5c9
    int line;
Packit 90a5c9
    apr_thread_mutex_t *mutex;
Packit 90a5c9
};
Packit 90a5c9
Packit 90a5c9
/* Global reference to the pool passed into ssl_util_thread_setup() */
Packit 90a5c9
apr_pool_t *dynlockpool = NULL;
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 * Dynamic lock creation callback
Packit 90a5c9
 */
Packit 90a5c9
static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
Packit 90a5c9
                                                     int line)
Packit 90a5c9
{
Packit 90a5c9
    struct CRYPTO_dynlock_value *value;
Packit 90a5c9
    apr_pool_t *p;
Packit 90a5c9
    apr_status_t rv;
Packit 90a5c9
Packit 90a5c9
    /*
Packit 90a5c9
     * We need a pool to allocate our mutex.  Since we can't clear
Packit 90a5c9
     * allocated memory from a pool, create a subpool that we can blow
Packit 90a5c9
     * away in the destruction callback.
Packit 90a5c9
     */
Packit 90a5c9
    apr_pool_create(&p, dynlockpool);
Packit 90a5c9
    ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p,
Packit 90a5c9
                  "Creating dynamic lock");
Packit 90a5c9
Packit 90a5c9
    value = apr_palloc(p, sizeof(struct CRYPTO_dynlock_value));
Packit 90a5c9
    value->pool = p;
Packit 90a5c9
    /* Keep our own copy of the place from which we were created,
Packit 90a5c9
       using our own pool. */
Packit 90a5c9
    value->file = apr_pstrdup(p, file);
Packit 90a5c9
    value->line = line;
Packit 90a5c9
    rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
Packit 90a5c9
                                p);
Packit 90a5c9
    if (rv != APR_SUCCESS) {
Packit 90a5c9
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, p, APLOGNO(02186)
Packit 90a5c9
                      "Failed to create thread mutex for dynamic lock");
Packit 90a5c9
        apr_pool_destroy(p);
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
    return value;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 * Dynamic locking and unlocking function
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
Packit 90a5c9
                           const char *file, int line)
Packit 90a5c9
{
Packit 90a5c9
    apr_status_t rv;
Packit 90a5c9
Packit 90a5c9
    if (mode & CRYPTO_LOCK) {
Packit 90a5c9
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
Packit 90a5c9
                      "Acquiring mutex %s:%d", l->file, l->line);
Packit 90a5c9
        rv = apr_thread_mutex_lock(l->mutex);
Packit 90a5c9
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
Packit 90a5c9
                      "Mutex %s:%d acquired!", l->file, l->line);
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
Packit 90a5c9
                      "Releasing mutex %s:%d", l->file, l->line);
Packit 90a5c9
        rv = apr_thread_mutex_unlock(l->mutex);
Packit 90a5c9
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
Packit 90a5c9
                      "Mutex %s:%d released!", l->file, l->line);
Packit 90a5c9
    }
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 * Dynamic lock destruction callback
Packit 90a5c9
 */
Packit 90a5c9
static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
Packit 90a5c9
                          const char *file, int line)
Packit 90a5c9
{
Packit 90a5c9
    apr_status_t rv;
Packit 90a5c9
Packit 90a5c9
    ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, l->pool,
Packit 90a5c9
                  "Destroying dynamic lock %s:%d", l->file, l->line);
Packit 90a5c9
    rv = apr_thread_mutex_destroy(l->mutex);
Packit 90a5c9
    if (rv != APR_SUCCESS) {
Packit 90a5c9
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, l->pool,
Packit 90a5c9
                      APLOGNO(02192) "Failed to destroy mutex for dynamic "
Packit 90a5c9
                      "lock %s:%d", l->file, l->line);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    /* Trust that whomever owned the CRYPTO_dynlock_value we were
Packit 90a5c9
     * passed has no future use for it...
Packit 90a5c9
     */
Packit 90a5c9
    apr_pool_destroy(l->pool);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
Packit 90a5c9
Packit 90a5c9
static void ssl_util_thr_id(CRYPTO_THREADID *id)
Packit 90a5c9
{
Packit 90a5c9
    /* OpenSSL needs this to return an unsigned long.  On OS/390, the pthread
Packit 90a5c9
     * id is a structure twice that big.  Use the TCB pointer instead as a
Packit 90a5c9
     * unique unsigned long.
Packit 90a5c9
     */
Packit 90a5c9
#ifdef __MVS__
Packit 90a5c9
    struct PSA {
Packit 90a5c9
        char unmapped[540]; /* PSATOLD is at offset 540 in the PSA */
Packit 90a5c9
        unsigned long PSATOLD;
Packit 90a5c9
    } *psaptr = 0; /* PSA is at address 0 */
Packit 90a5c9
Packit 90a5c9
    CRYPTO_THREADID_set_numeric(id, psaptr->PSATOLD);
Packit 90a5c9
#else
Packit 90a5c9
    CRYPTO_THREADID_set_numeric(id, (unsigned long) apr_os_thread_current());
Packit 90a5c9
#endif
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static apr_status_t ssl_util_thr_id_cleanup(void *old)
Packit 90a5c9
{
Packit 90a5c9
    CRYPTO_THREADID_set_callback(old);
Packit 90a5c9
    return APR_SUCCESS;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#else
Packit 90a5c9
Packit 90a5c9
static unsigned long ssl_util_thr_id(void)
Packit 90a5c9
{
Packit 90a5c9
    /* OpenSSL needs this to return an unsigned long.  On OS/390, the pthread
Packit 90a5c9
     * id is a structure twice that big.  Use the TCB pointer instead as a
Packit 90a5c9
     * unique unsigned long.
Packit 90a5c9
     */
Packit 90a5c9
#ifdef __MVS__
Packit 90a5c9
    struct PSA {
Packit 90a5c9
        char unmapped[540];
Packit 90a5c9
        unsigned long PSATOLD;
Packit 90a5c9
    } *psaptr = 0;
Packit 90a5c9
Packit 90a5c9
    return psaptr->PSATOLD;
Packit 90a5c9
#else
Packit 90a5c9
    return (unsigned long) apr_os_thread_current();
Packit 90a5c9
#endif
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static apr_status_t ssl_util_thr_id_cleanup(void *old)
Packit 90a5c9
{
Packit 90a5c9
    CRYPTO_set_id_callback(old);
Packit 90a5c9
    return APR_SUCCESS;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
static apr_status_t ssl_util_thread_cleanup(void *data)
Packit 90a5c9
{
Packit 90a5c9
    CRYPTO_set_locking_callback(NULL);
Packit 90a5c9
Packit 90a5c9
    CRYPTO_set_dynlock_create_callback(NULL);
Packit 90a5c9
    CRYPTO_set_dynlock_lock_callback(NULL);
Packit 90a5c9
    CRYPTO_set_dynlock_destroy_callback(NULL);
Packit 90a5c9
Packit 90a5c9
    dynlockpool = NULL;
Packit 90a5c9
Packit 90a5c9
    /* Let the registered mutex cleanups do their own thing
Packit 90a5c9
     */
Packit 90a5c9
    return APR_SUCCESS;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
void ssl_util_thread_setup(apr_pool_t *p)
Packit 90a5c9
{
Packit 90a5c9
    int i;
Packit 90a5c9
Packit 90a5c9
    lock_num_locks = CRYPTO_num_locks();
Packit 90a5c9
    lock_cs = apr_palloc(p, lock_num_locks * sizeof(*lock_cs));
Packit 90a5c9
Packit 90a5c9
    for (i = 0; i < lock_num_locks; i++) {
Packit 90a5c9
        apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    CRYPTO_set_locking_callback(ssl_util_thr_lock);
Packit 90a5c9
Packit 90a5c9
    /* Set up dynamic locking scaffolding for OpenSSL to use at its
Packit 90a5c9
     * convenience.
Packit 90a5c9
     */
Packit 90a5c9
    dynlockpool = p;
Packit 90a5c9
    CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
Packit 90a5c9
    CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
Packit 90a5c9
    CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);
Packit 90a5c9
Packit 90a5c9
    apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup,
Packit 90a5c9
                                       apr_pool_cleanup_null);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
void ssl_util_thread_id_setup(apr_pool_t *p)
Packit 90a5c9
{
Packit 90a5c9
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
Packit 90a5c9
    CRYPTO_THREADID_set_callback(ssl_util_thr_id);
Packit 90a5c9
#else
Packit 90a5c9
    CRYPTO_set_id_callback(ssl_util_thr_id);
Packit 90a5c9
#endif
Packit 90a5c9
    apr_pool_cleanup_register(p, NULL, ssl_util_thr_id_cleanup,
Packit 90a5c9
                                       apr_pool_cleanup_null);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */
Packit 70c855
Packit 70c855
int modssl_is_engine_id(const char *name)
Packit 70c855
{
Packit 70c855
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
Packit 70c855
    /* ### Can handle any other special ENGINE key names here? */
Packit 70c855
    return strncmp(name, "pkcs11:", 7) == 0;
Packit 70c855
#else
Packit 70c855
    return 0;
Packit 70c855
#endif
Packit 70c855
}