ssl_util.c revision baa6746bc66ff1daa1852a3a085906d2dfa96bb6
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Licensed to the Apache Software Foundation (ASF) under one or more
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * contributor license agreements. See the NOTICE file distributed with
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * this work for additional information regarding copyright ownership.
b99dbaab171d91e1b664397cc40e039d0c087c65fielding * The ASF licenses this file to You under the Apache License, Version 2.0
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * (the "License"); you may not use this file except in compliance with
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the License. You may obtain a copy of the License at
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * http://www.apache.org/licenses/LICENSE-2.0
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Unless required by applicable law or agreed to in writing, software
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * distributed under the License is distributed on an "AS IS" BASIS,
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * See the License for the specific language governing permissions and
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * limitations under the License.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* _ _
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * _ __ ___ ___ __| | ___ ___| | mod_ssl
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * | | | | | | (_) | (_| | \__ \__ \ |
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * |_| |_| |_|\___/ \__,_|___|___/___/_|
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * |_____|
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * ssl_util.c
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Utility Functions
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding /* ``Every day of my life
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding I am forced to add another
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding name to the list of people
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding who piss me off!''
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding -- Calvin */
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "ssl_private.h"
64185f9824e42f21ca7b9ae6c004484215c031a7rbb#include "ap_mpm.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "apr_thread_mutex.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding/* _________________________________________________________________
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding**
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding** Utility Functions
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding** _________________________________________________________________
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding*/
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fieldingchar *ssl_util_vhostid(apr_pool_t *p, server_rec *s)
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding{
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding char *id;
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding SSLSrvConfigRec *sc;
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding char *host;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_port_t port;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding host = s->server_hostname;
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding if (s->port != 0)
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding port = s->port;
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding else {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding sc = mySrvConfig(s);
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding if (sc->enabled == TRUE)
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding port = DEFAULT_HTTPS_PORT;
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding else
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding port = DEFAULT_HTTP_PORT;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
3568de757bac0b47256647504c186d17ca272f85rbb id = apr_psprintf(p, "%s:%lu", host, (unsigned long)port);
3568de757bac0b47256647504c186d17ca272f85rbb return id;
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbapr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd,
3568de757bac0b47256647504c186d17ca272f85rbb const char * const *argv)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb apr_procattr_t *procattr;
3568de757bac0b47256647504c186d17ca272f85rbb apr_proc_t *proc;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb if (apr_procattr_create(&procattr, p) != APR_SUCCESS)
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK,
3568de757bac0b47256647504c186d17ca272f85rbb APR_FULL_BLOCK) != APR_SUCCESS)
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb if (apr_procattr_dir_set(procattr,
3568de757bac0b47256647504c186d17ca272f85rbb ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS)
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL)
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb return proc->out;
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbvoid ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb apr_file_close(fp);
3568de757bac0b47256647504c186d17ca272f85rbb return;
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/*
3568de757bac0b47256647504c186d17ca272f85rbb * Run a filter program and read the first line of its stdout output
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbbchar *ssl_util_readfilter(server_rec *s, apr_pool_t *p, const char *cmd,
3568de757bac0b47256647504c186d17ca272f85rbb const char * const *argv)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb static char buf[MAX_STRING_LEN];
3568de757bac0b47256647504c186d17ca272f85rbb apr_file_t *fp;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_size_t nbytes = 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding char c;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int k;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
3568de757bac0b47256647504c186d17ca272f85rbb if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL)
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb /* XXX: we are reading 1 byte at a time here */
3568de757bac0b47256647504c186d17ca272f85rbb for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
3568de757bac0b47256647504c186d17ca272f85rbb && nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) {
db12cd62083041bf90945eeb90cc40fbd2340797trawick if (c == '\n' || c == '\r')
db12cd62083041bf90945eeb90cc40fbd2340797trawick break;
db12cd62083041bf90945eeb90cc40fbd2340797trawick buf[k++] = c;
333eac96e4fb7d6901cb75e6ca7bb22b2ccb84cetrawick }
333eac96e4fb7d6901cb75e6ca7bb22b2ccb84cetrawick buf[k] = NUL;
3568de757bac0b47256647504c186d17ca272f85rbb ssl_util_ppclose(s, p, fp);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb return buf;
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbBOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb apr_finfo_t finfo;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb if (path == NULL)
3568de757bac0b47256647504c186d17ca272f85rbb return FALSE;
3568de757bac0b47256647504c186d17ca272f85rbb if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path,
3568de757bac0b47256647504c186d17ca272f85rbb APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
3568de757bac0b47256647504c186d17ca272f85rbb return FALSE;
3568de757bac0b47256647504c186d17ca272f85rbb if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
3568de757bac0b47256647504c186d17ca272f85rbb return FALSE;
3568de757bac0b47256647504c186d17ca272f85rbb if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
3568de757bac0b47256647504c186d17ca272f85rbb return FALSE;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return FALSE;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return TRUE;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
8f3ec4772d2aeb347cf40e87c77627bb784dd018rbbssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
8f3ec4772d2aeb347cf40e87c77627bb784dd018rbb{
3d96ee83babeec32482c9082c9426340cee8c44dwrowe ssl_algo_t t;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding EVP_PKEY *pFreeKey = NULL;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb t = SSL_ALGO_UNKNOWN;
3568de757bac0b47256647504c186d17ca272f85rbb if (pCert != NULL)
3568de757bac0b47256647504c186d17ca272f85rbb pFreeKey = pKey = X509_get_pubkey(pCert);
3568de757bac0b47256647504c186d17ca272f85rbb if (pKey != NULL) {
3568de757bac0b47256647504c186d17ca272f85rbb switch (EVP_PKEY_key_type(pKey)) {
3568de757bac0b47256647504c186d17ca272f85rbb case EVP_PKEY_RSA:
3568de757bac0b47256647504c186d17ca272f85rbb t = SSL_ALGO_RSA;
3568de757bac0b47256647504c186d17ca272f85rbb break;
3568de757bac0b47256647504c186d17ca272f85rbb case EVP_PKEY_DSA:
3568de757bac0b47256647504c186d17ca272f85rbb t = SSL_ALGO_DSA;
3568de757bac0b47256647504c186d17ca272f85rbb break;
3568de757bac0b47256647504c186d17ca272f85rbb#ifndef OPENSSL_NO_EC
3568de757bac0b47256647504c186d17ca272f85rbb case EVP_PKEY_EC:
3568de757bac0b47256647504c186d17ca272f85rbb t = SSL_ALGO_ECC;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb default:
3568de757bac0b47256647504c186d17ca272f85rbb break;
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb#ifdef OPENSSL_VERSION_NUMBER
3568de757bac0b47256647504c186d17ca272f85rbb /* Only refcounted in OpenSSL */
3568de757bac0b47256647504c186d17ca272f85rbb if (pFreeKey != NULL)
3568de757bac0b47256647504c186d17ca272f85rbb EVP_PKEY_free(pFreeKey);
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb return t;
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbchar *ssl_util_algotypestr(ssl_algo_t t)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb char *cp;
3568de757bac0b47256647504c186d17ca272f85rbb
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding cp = "UNKNOWN";
3568de757bac0b47256647504c186d17ca272f85rbb switch (t) {
3568de757bac0b47256647504c186d17ca272f85rbb case SSL_ALGO_RSA:
3568de757bac0b47256647504c186d17ca272f85rbb cp = "RSA";
3568de757bac0b47256647504c186d17ca272f85rbb break;
3568de757bac0b47256647504c186d17ca272f85rbb case SSL_ALGO_DSA:
3568de757bac0b47256647504c186d17ca272f85rbb cp = "DSA";
3568de757bac0b47256647504c186d17ca272f85rbb break;
3568de757bac0b47256647504c186d17ca272f85rbb#ifndef OPENSSL_NO_EC
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case SSL_ALGO_ECC:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding cp = "ECC";
78ae889ffe0fdfab72f56c6993b0f302cb48da55rbb break;
3568de757bac0b47256647504c186d17ca272f85rbb#endif
fc1efab92032301e317f07e1b3a00082d9d71f3frbb default:
0375f54d32af9c27de0006956d9f85d01b020351stoddard break;
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb return cp;
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/*
3568de757bac0b47256647504c186d17ca272f85rbb * certain key and cert data needs to survive restarts,
3568de757bac0b47256647504c186d17ca272f85rbb * which are stored in the user data table of s->process->pool.
fc1efab92032301e317f07e1b3a00082d9d71f3frbb * to prevent "leaking" of this data, we use malloc/free
3568de757bac0b47256647504c186d17ca272f85rbb * rather than apr_palloc and these wrappers to help make sure
fc1efab92032301e317f07e1b3a00082d9d71f3frbb * we do not leak the malloc-ed data.
3568de757bac0b47256647504c186d17ca272f85rbb */
fc1efab92032301e317f07e1b3a00082d9d71f3frbbunsigned char *ssl_asn1_table_set(apr_hash_t *table,
3568de757bac0b47256647504c186d17ca272f85rbb const char *key,
fc1efab92032301e317f07e1b3a00082d9d71f3frbb long int length)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb apr_ssize_t klen = strlen(key);
3568de757bac0b47256647504c186d17ca272f85rbb ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb /*
3568de757bac0b47256647504c186d17ca272f85rbb * if a value for this key already exists,
3568de757bac0b47256647504c186d17ca272f85rbb * reuse as much of the already malloc-ed data
3568de757bac0b47256647504c186d17ca272f85rbb * as possible.
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb if (asn1) {
3568de757bac0b47256647504c186d17ca272f85rbb if (asn1->nData != length) {
3568de757bac0b47256647504c186d17ca272f85rbb free(asn1->cpData); /* XXX: realloc? */
3568de757bac0b47256647504c186d17ca272f85rbb asn1->cpData = NULL;
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb else {
3568de757bac0b47256647504c186d17ca272f85rbb asn1 = malloc(sizeof(*asn1));
3568de757bac0b47256647504c186d17ca272f85rbb asn1->source_mtime = 0; /* used as a note for encrypted private keys */
3568de757bac0b47256647504c186d17ca272f85rbb asn1->cpData = NULL;
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb asn1->nData = length;
3568de757bac0b47256647504c186d17ca272f85rbb if (!asn1->cpData) {
3568de757bac0b47256647504c186d17ca272f85rbb asn1->cpData = malloc(length);
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb apr_hash_set(table, key, klen, asn1);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return asn1->cpData; /* caller will assign a value to this */
3568de757bac0b47256647504c186d17ca272f85rbb}
239f998fbee5ac5b114b965bb76e217cce0003edstoddard
78ae889ffe0fdfab72f56c6993b0f302cb48da55rbbssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
3568de757bac0b47256647504c186d17ca272f85rbb const char *key)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbvoid ssl_asn1_table_unset(apr_hash_t *table,
3568de757bac0b47256647504c186d17ca272f85rbb const char *key)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb apr_ssize_t klen = strlen(key);
3568de757bac0b47256647504c186d17ca272f85rbb ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard
3568de757bac0b47256647504c186d17ca272f85rbb if (!asn1) {
3568de757bac0b47256647504c186d17ca272f85rbb return;
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb if (asn1->cpData) {
3568de757bac0b47256647504c186d17ca272f85rbb free(asn1->cpData);
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb free(asn1);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb apr_hash_set(table, key, klen, NULL);
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb#ifndef OPENSSL_NO_EC
3568de757bac0b47256647504c186d17ca272f85rbbstatic const char *ssl_asn1_key_types[] = {"RSA", "DSA", "ECC"};
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#else
ca53a74f4012a45cbad48e940eddf27d866981f9dougmstatic const char *ssl_asn1_key_types[] = {"RSA", "DSA"};
ca53a74f4012a45cbad48e940eddf27d866981f9dougm#endif
ca53a74f4012a45cbad48e940eddf27d866981f9dougm
ca53a74f4012a45cbad48e940eddf27d866981f9dougmconst char *ssl_asn1_keystr(int keytype)
239f998fbee5ac5b114b965bb76e217cce0003edstoddard{
3568de757bac0b47256647504c186d17ca272f85rbb if (keytype >= SSL_AIDX_MAX) {
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb return ssl_asn1_key_types[keytype];
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingconst char *ssl_asn1_table_keyfmt(apr_pool_t *p,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *id,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int keytype)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *keystr = ssl_asn1_keystr(keytype);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
3568de757bac0b47256647504c186d17ca272f85rbb return apr_pstrcat(p, id, ":", keystr, NULL);
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbSTACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb PKCS7 *p7;
3568de757bac0b47256647504c186d17ca272f85rbb STACK_OF(X509) *certs = NULL;
3568de757bac0b47256647504c186d17ca272f85rbb FILE *f;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb f = fopen(pkcs7, "r");
3568de757bac0b47256647504c186d17ca272f85rbb if (!f) {
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Can't open %s", pkcs7);
3568de757bac0b47256647504c186d17ca272f85rbb ssl_die();
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb p7 = PEM_read_PKCS7(f, NULL, NULL, NULL);
3568de757bac0b47256647504c186d17ca272f85rbb if (!p7) {
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s,
3568de757bac0b47256647504c186d17ca272f85rbb "Can't read PKCS7 object %s", pkcs7);
3568de757bac0b47256647504c186d17ca272f85rbb ssl_log_ssl_error(SSLLOG_MARK, APLOG_CRIT, s);
3568de757bac0b47256647504c186d17ca272f85rbb exit(1);
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb switch (OBJ_obj2nid(p7->type)) {
3568de757bac0b47256647504c186d17ca272f85rbb case NID_pkcs7_signed:
3568de757bac0b47256647504c186d17ca272f85rbb certs = p7->d.sign->cert;
3568de757bac0b47256647504c186d17ca272f85rbb p7->d.sign->cert = NULL;
3568de757bac0b47256647504c186d17ca272f85rbb PKCS7_free(p7);
3568de757bac0b47256647504c186d17ca272f85rbb break;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb case NID_pkcs7_signedAndEnveloped:
3568de757bac0b47256647504c186d17ca272f85rbb certs = p7->d.signed_and_enveloped->cert;
3568de757bac0b47256647504c186d17ca272f85rbb p7->d.signed_and_enveloped->cert = NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding PKCS7_free(p7);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
5a58a10705b7b154b53294e0c0283d64eabdcb7fstoddard default:
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, 0, s,
3568de757bac0b47256647504c186d17ca272f85rbb "Don't understand PKCS7 file %s", pkcs7);
3568de757bac0b47256647504c186d17ca272f85rbb ssl_die();
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb if (!certs) {
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, 0, s,
3568de757bac0b47256647504c186d17ca272f85rbb "No certificates in %s", pkcs7);
3568de757bac0b47256647504c186d17ca272f85rbb ssl_die();
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb fclose(f);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb return certs;
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard#if APR_HAS_THREADS
3568de757bac0b47256647504c186d17ca272f85rbb/*
3568de757bac0b47256647504c186d17ca272f85rbb * To ensure thread-safetyness in OpenSSL - work in progress
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddardstatic apr_thread_mutex_t **lock_cs;
3568de757bac0b47256647504c186d17ca272f85rbbstatic int lock_num_locks;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb#ifdef HAVE_SSLC
3568de757bac0b47256647504c186d17ca272f85rbb#if SSLC_VERSION_NUMBER >= 0x2000
3568de757bac0b47256647504c186d17ca272f85rbbstatic int ssl_util_thr_lock(int mode, int type,
3568de757bac0b47256647504c186d17ca272f85rbb char *file, int line)
3568de757bac0b47256647504c186d17ca272f85rbb#else
3568de757bac0b47256647504c186d17ca272f85rbbstatic void ssl_util_thr_lock(int mode, int type,
3568de757bac0b47256647504c186d17ca272f85rbb char *file, int line)
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb#else
74fd6d9aeadb9022086259c5c1ae00bc0dda9c9astoddardstatic void ssl_util_thr_lock(int mode, int type,
74fd6d9aeadb9022086259c5c1ae00bc0dda9c9astoddard const char *file, int line)
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb if (type < lock_num_locks) {
3568de757bac0b47256647504c186d17ca272f85rbb if (mode & CRYPTO_LOCK) {
3568de757bac0b47256647504c186d17ca272f85rbb apr_thread_mutex_lock(lock_cs[type]);
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb else {
3568de757bac0b47256647504c186d17ca272f85rbb apr_thread_mutex_unlock(lock_cs[type]);
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb#ifdef HAVE_SSLC
3568de757bac0b47256647504c186d17ca272f85rbb#if SSLC_VERSION_NUMBER >= 0x2000
3568de757bac0b47256647504c186d17ca272f85rbb return 1;
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb else {
3568de757bac0b47256647504c186d17ca272f85rbb return -1;
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/* Dynamic lock structure */
3568de757bac0b47256647504c186d17ca272f85rbbstruct CRYPTO_dynlock_value {
3568de757bac0b47256647504c186d17ca272f85rbb apr_pool_t *pool;
3568de757bac0b47256647504c186d17ca272f85rbb const char* file;
3568de757bac0b47256647504c186d17ca272f85rbb int line;
3568de757bac0b47256647504c186d17ca272f85rbb apr_thread_mutex_t *mutex;
3568de757bac0b47256647504c186d17ca272f85rbb};
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard
3568de757bac0b47256647504c186d17ca272f85rbb/* Global reference to the pool passed into ssl_util_thread_setup() */
3568de757bac0b47256647504c186d17ca272f85rbbapr_pool_t *dynlockpool = NULL;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/*
3568de757bac0b47256647504c186d17ca272f85rbb * Dynamic lock creation callback
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbbstatic struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
3568de757bac0b47256647504c186d17ca272f85rbb int line)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb struct CRYPTO_dynlock_value *value;
3568de757bac0b47256647504c186d17ca272f85rbb apr_pool_t *p;
3568de757bac0b47256647504c186d17ca272f85rbb apr_status_t rv;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb /*
3568de757bac0b47256647504c186d17ca272f85rbb * We need a pool to allocate our mutex. Since we can't clear
3568de757bac0b47256647504c186d17ca272f85rbb * allocated memory from a pool, create a subpool that we can blow
3568de757bac0b47256647504c186d17ca272f85rbb * away in the destruction callback.
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb rv = apr_pool_create(&p, dynlockpool);
3568de757bac0b47256647504c186d17ca272f85rbb if (rv != APR_SUCCESS) {
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_perror(file, line, APLOG_ERR, rv, dynlockpool,
3568de757bac0b47256647504c186d17ca272f85rbb "Failed to create subpool for dynamic lock");
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_perror(file, line, APLOG_DEBUG, 0, p,
3568de757bac0b47256647504c186d17ca272f85rbb "Creating dynamic lock");
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb value = (struct CRYPTO_dynlock_value *)apr_palloc(p,
3568de757bac0b47256647504c186d17ca272f85rbb sizeof(struct CRYPTO_dynlock_value));
3568de757bac0b47256647504c186d17ca272f85rbb if (!value) {
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_perror(file, line, APLOG_ERR, 0, p,
3568de757bac0b47256647504c186d17ca272f85rbb "Failed to allocate dynamic lock structure");
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb value->pool = p;
3568de757bac0b47256647504c186d17ca272f85rbb /* Keep our own copy of the place from which we were created,
3568de757bac0b47256647504c186d17ca272f85rbb using our own pool. */
3568de757bac0b47256647504c186d17ca272f85rbb value->file = apr_pstrdup(p, file);
3568de757bac0b47256647504c186d17ca272f85rbb value->line = line;
3568de757bac0b47256647504c186d17ca272f85rbb rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
3568de757bac0b47256647504c186d17ca272f85rbb p);
3568de757bac0b47256647504c186d17ca272f85rbb if (rv != APR_SUCCESS) {
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_perror(file, line, APLOG_ERR, rv, p,
3568de757bac0b47256647504c186d17ca272f85rbb "Failed to create thread mutex for dynamic lock");
3568de757bac0b47256647504c186d17ca272f85rbb apr_pool_destroy(p);
3568de757bac0b47256647504c186d17ca272f85rbb return NULL;
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb return value;
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/*
3568de757bac0b47256647504c186d17ca272f85rbb * Dynamic locking and unlocking function
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbstatic void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
3568de757bac0b47256647504c186d17ca272f85rbb const char *file, int line)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb apr_status_t rv;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb if (mode & CRYPTO_LOCK) {
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool,
3568de757bac0b47256647504c186d17ca272f85rbb "Acquiring mutex %s:%d", l->file, l->line);
3568de757bac0b47256647504c186d17ca272f85rbb rv = apr_thread_mutex_lock(l->mutex);
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_perror(file, line, APLOG_DEBUG, rv, l->pool,
3568de757bac0b47256647504c186d17ca272f85rbb "Mutex %s:%d acquired!", l->file, l->line);
3568de757bac0b47256647504c186d17ca272f85rbb }
3568de757bac0b47256647504c186d17ca272f85rbb else {
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool,
3568de757bac0b47256647504c186d17ca272f85rbb "Releasing mutex %s:%d", l->file, l->line);
3568de757bac0b47256647504c186d17ca272f85rbb rv = apr_thread_mutex_unlock(l->mutex);
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_perror(file, line, APLOG_DEBUG, rv, l->pool,
beb70d51e435dc36c56a72b6cd83556c04db9283wrowe "Mutex %s:%d released!", l->file, l->line);
fe6baec9bbcd36f932b71a355120cd7b5a685d6cfielding }
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/*
3568de757bac0b47256647504c186d17ca272f85rbb * Dynamic lock destruction callback
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbbstatic void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
3568de757bac0b47256647504c186d17ca272f85rbb const char *file, int line)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb apr_status_t rv;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool,
3568de757bac0b47256647504c186d17ca272f85rbb "Destroying dynamic lock %s:%d", l->file, l->line);
3568de757bac0b47256647504c186d17ca272f85rbb rv = apr_thread_mutex_destroy(l->mutex);
3568de757bac0b47256647504c186d17ca272f85rbb if (rv != APR_SUCCESS) {
ce03576b2434cec77f2921db9d5b6a0510581c23rederpj ap_log_perror(file, line, APLOG_ERR, rv, l->pool,
3568de757bac0b47256647504c186d17ca272f85rbb "Failed to destroy mutex for dynamic lock %s:%d",
3568de757bac0b47256647504c186d17ca272f85rbb l->file, l->line);
3568de757bac0b47256647504c186d17ca272f85rbb }
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick /* Trust that whomever owned the CRYPTO_dynlock_value we were
3568de757bac0b47256647504c186d17ca272f85rbb * passed has no future use for it...
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb apr_pool_destroy(l->pool);
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbstatic unsigned long ssl_util_thr_id(void)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb /* OpenSSL needs this to return an unsigned long. On OS/390, the pthread
3568de757bac0b47256647504c186d17ca272f85rbb * id is a structure twice that big. Use the TCB pointer instead as a
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick * unique unsigned long.
3568de757bac0b47256647504c186d17ca272f85rbb */
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick#ifdef __MVS__
3568de757bac0b47256647504c186d17ca272f85rbb struct PSA {
3568de757bac0b47256647504c186d17ca272f85rbb char unmapped[540];
3568de757bac0b47256647504c186d17ca272f85rbb unsigned long PSATOLD;
3568de757bac0b47256647504c186d17ca272f85rbb } *psaptr = 0;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb return psaptr->PSATOLD;
3568de757bac0b47256647504c186d17ca272f85rbb#else
3568de757bac0b47256647504c186d17ca272f85rbb return (unsigned long) apr_os_thread_current();
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbstatic apr_status_t ssl_util_thread_cleanup(void *data)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb CRYPTO_set_locking_callback(NULL);
3568de757bac0b47256647504c186d17ca272f85rbb CRYPTO_set_id_callback(NULL);
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard
3568de757bac0b47256647504c186d17ca272f85rbb CRYPTO_set_dynlock_create_callback(NULL);
3568de757bac0b47256647504c186d17ca272f85rbb CRYPTO_set_dynlock_lock_callback(NULL);
3568de757bac0b47256647504c186d17ca272f85rbb CRYPTO_set_dynlock_destroy_callback(NULL);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb dynlockpool = NULL;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb /* Let the registered mutex cleanups do their own thing
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb return APR_SUCCESS;
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbvoid ssl_util_thread_setup(apr_pool_t *p)
3568de757bac0b47256647504c186d17ca272f85rbb{
3568de757bac0b47256647504c186d17ca272f85rbb int i;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb lock_num_locks = CRYPTO_num_locks();
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard lock_cs = apr_palloc(p, lock_num_locks * sizeof(*lock_cs));
3568de757bac0b47256647504c186d17ca272f85rbb
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard for (i = 0; i < lock_num_locks; i++) {
3568de757bac0b47256647504c186d17ca272f85rbb apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p);
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard }
3568de757bac0b47256647504c186d17ca272f85rbb
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard CRYPTO_set_id_callback(ssl_util_thr_id);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb CRYPTO_set_locking_callback(ssl_util_thr_lock);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb /* Set up dynamic locking scaffolding for OpenSSL to use at its
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard * convenience.
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb dynlockpool = p;
3568de757bac0b47256647504c186d17ca272f85rbb CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
3568de757bac0b47256647504c186d17ca272f85rbb CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
3568de757bac0b47256647504c186d17ca272f85rbb CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup,
3568de757bac0b47256647504c186d17ca272f85rbb apr_pool_cleanup_null);
3568de757bac0b47256647504c186d17ca272f85rbb}
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb