ssl_util.c revision a943533fd4d91d114af622731a405407990c4fb1
e1e8390280254f7f0580d701e583f670643d4f3fnilgun/* _ _
e1e8390280254f7f0580d701e583f670643d4f3fnilgun** _ __ ___ ___ __| | ___ ___| | mod_ssl
e1e8390280254f7f0580d701e583f670643d4f3fnilgun** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
e1e8390280254f7f0580d701e583f670643d4f3fnilgun** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org
e1e8390280254f7f0580d701e583f670643d4f3fnilgun** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org
e1e8390280254f7f0580d701e583f670643d4f3fnilgun** |_____|
e1e8390280254f7f0580d701e583f670643d4f3fnilgun** ssl_util.c
e1e8390280254f7f0580d701e583f670643d4f3fnilgun** Utility Functions
e1e8390280254f7f0580d701e583f670643d4f3fnilgun*/
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen/* ====================================================================
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * The Apache Software License, Version 1.1
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen *
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * reserved.
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * Redistribution and use in source and binary forms, with or without
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * modification, are permitted provided that the following conditions
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * are met:
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * 1. Redistributions of source code must retain the above copyright
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * notice, this list of conditions and the following disclaimer.
3f08db06526d6901aa08c110b5bc7dde6bc39905nd *
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * 2. Redistributions in binary form must reproduce the above copyright
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * notice, this list of conditions and the following disclaimer in
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * the documentation and/or other materials provided with the
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * distribution.
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * 3. The end-user documentation included with the redistribution,
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung * if any, must include the following acknowledgment:
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * "This product includes software developed by the
f0fa55ff14fa0bf8fd72d989f6625de6dc3260c8igalic * Apache Software Foundation (http://www.apache.org/)."
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * Alternately, this acknowledgment may appear in the software itself,
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * if and wherever such third-party acknowledgments normally appear.
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * 4. The names "Apache" and "Apache Software Foundation" must
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * not be used to endorse or promote products derived from this
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * software without prior written permission. For written
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * permission, please contact apache@apache.org.
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * 5. Products derived from this software may not be called "Apache",
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * nor may "Apache" appear in their name, without prior written
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * permission of the Apache Software Foundation.
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2704de98885368683621b01c8f8f4e4b01557611takashi * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * SUCH DAMAGE.
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * ====================================================================
b9f522ae1c0ed2bf3fc4444245bf28b2e2449a65nd */
e1e8390280254f7f0580d701e583f670643d4f3fnilgun /* ``Every day of my life
c38e2a97e43fc69b22f6b03c6d2f60e3bd705f89sf I am forced to add another
e1e8390280254f7f0580d701e583f670643d4f3fnilgun name to the list of people
e1e8390280254f7f0580d701e583f670643d4f3fnilgun who piss me off!''
e1e8390280254f7f0580d701e583f670643d4f3fnilgun -- Calvin */
e1e8390280254f7f0580d701e583f670643d4f3fnilgun#include "mod_ssl.h"
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
e1e8390280254f7f0580d701e583f670643d4f3fnilgun/* _________________________________________________________________
e1e8390280254f7f0580d701e583f670643d4f3fnilgun**
e1e8390280254f7f0580d701e583f670643d4f3fnilgun** Utility Functions
e1e8390280254f7f0580d701e583f670643d4f3fnilgun** _________________________________________________________________
e1e8390280254f7f0580d701e583f670643d4f3fnilgun*/
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
2704de98885368683621b01c8f8f4e4b01557611takashichar *ssl_util_vhostid(apr_pool_t *p, server_rec *s)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun{
e1e8390280254f7f0580d701e583f670643d4f3fnilgun char *id;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun SSLSrvConfigRec *sc;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun char *host;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun apr_port_t port;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun host = s->server_hostname;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun if (s->port != 0)
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh port = s->port;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun else {
e1e8390280254f7f0580d701e583f670643d4f3fnilgun sc = mySrvConfig(s);
e1e8390280254f7f0580d701e583f670643d4f3fnilgun if (sc->bEnabled)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun port = DEFAULT_HTTPS_PORT;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun else
e1e8390280254f7f0580d701e583f670643d4f3fnilgun port = DEFAULT_HTTP_PORT;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun }
e1e8390280254f7f0580d701e583f670643d4f3fnilgun id = apr_psprintf(p, "%s:%lu", host, (unsigned long)port);
e1e8390280254f7f0580d701e583f670643d4f3fnilgun return id;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun}
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun
e1e8390280254f7f0580d701e583f670643d4f3fnilgunvoid ssl_util_strupper(char *s)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun{
e1e8390280254f7f0580d701e583f670643d4f3fnilgun for (; *s; ++s)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *s = apr_toupper(*s);
e1e8390280254f7f0580d701e583f670643d4f3fnilgun return;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun}
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
e1e8390280254f7f0580d701e583f670643d4f3fnilgunstatic const char ssl_util_uuencode_six2pr[64+1] =
e1e8390280254f7f0580d701e583f670643d4f3fnilgun "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
e1e8390280254f7f0580d701e583f670643d4f3fnilgunvoid ssl_util_uuencode(char *szTo, const char *szFrom, BOOL bPad)
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun{
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun ssl_util_uuencode_binary((unsigned char *)szTo,
e1e8390280254f7f0580d701e583f670643d4f3fnilgun (const unsigned char *)szFrom,
e1e8390280254f7f0580d701e583f670643d4f3fnilgun strlen(szFrom), bPad);
e1e8390280254f7f0580d701e583f670643d4f3fnilgun}
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
e1e8390280254f7f0580d701e583f670643d4f3fnilgunvoid ssl_util_uuencode_binary(
e1e8390280254f7f0580d701e583f670643d4f3fnilgun unsigned char *szTo, const unsigned char *szFrom, int nLength, BOOL bPad)
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun{
e1e8390280254f7f0580d701e583f670643d4f3fnilgun const unsigned char *s;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun int nPad = 0;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
e1e8390280254f7f0580d701e583f670643d4f3fnilgun for (s = szFrom; nLength > 0; s += 3) {
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *szTo++ = ssl_util_uuencode_six2pr[s[0] >> 2];
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *szTo++ = ssl_util_uuencode_six2pr[(s[0] << 4 | s[1] >> 4) & 0x3f];
e1e8390280254f7f0580d701e583f670643d4f3fnilgun if (--nLength == 0) {
e1e8390280254f7f0580d701e583f670643d4f3fnilgun nPad = 2;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun break;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun }
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *szTo++ = ssl_util_uuencode_six2pr[(s[1] << 2 | s[2] >> 6) & 0x3f];
e1e8390280254f7f0580d701e583f670643d4f3fnilgun if (--nLength == 0) {
e1e8390280254f7f0580d701e583f670643d4f3fnilgun nPad = 1;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun break;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun }
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *szTo++ = ssl_util_uuencode_six2pr[s[2] & 0x3f];
e1e8390280254f7f0580d701e583f670643d4f3fnilgun --nLength;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun }
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun while(bPad && nPad--)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *szTo++ = NUL;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun *szTo = NUL;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun return;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun}
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
e1e8390280254f7f0580d701e583f670643d4f3fnilgunapr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, char *cmd)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun{
e1e8390280254f7f0580d701e583f670643d4f3fnilgun apr_procattr_t *procattr;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun apr_proc_t *proc;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
e1e8390280254f7f0580d701e583f670643d4f3fnilgun if (apr_procattr_create(&procattr, p) != APR_SUCCESS)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun return NULL;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK,
e1e8390280254f7f0580d701e583f670643d4f3fnilgun APR_FULL_BLOCK) != APR_SUCCESS)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun return NULL;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun if (apr_procattr_dir_set(procattr,
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS)
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun return NULL;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun return NULL;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL)
2704de98885368683621b01c8f8f4e4b01557611takashi return NULL;
2704de98885368683621b01c8f8f4e4b01557611takashi if (apr_proc_create(proc, cmd, NULL, NULL, procattr, p) != APR_SUCCESS)
2704de98885368683621b01c8f8f4e4b01557611takashi return NULL;
2704de98885368683621b01c8f8f4e4b01557611takashi return proc->out;
2704de98885368683621b01c8f8f4e4b01557611takashi}
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgunvoid ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun{
e1e8390280254f7f0580d701e583f670643d4f3fnilgun apr_file_close(fp);
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun return;
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun}
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun/*
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun * Run a filter program and read the first line of its stdout output
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun */
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgunchar *ssl_util_readfilter(server_rec *s, apr_pool_t *p, char *cmd)
e0cfea1f5d38eeaa8fdf7c197c3c1eb31148e191nilgun{
e1e8390280254f7f0580d701e583f670643d4f3fnilgun static char buf[MAX_STRING_LEN];
e1e8390280254f7f0580d701e583f670643d4f3fnilgun apr_file_t *fp;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun apr_size_t nbytes;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun char c;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun int k;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung if ((fp = ssl_util_ppopen(s, p, cmd)) == NULL)
727872d18412fc021f03969b8641810d8896820bhumbedooh return NULL;
0d0ba3a410038e179b695446bb149cce6264e0abnd for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
727872d18412fc021f03969b8641810d8896820bhumbedooh && nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) {
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh if (c == '\n' || c == '\r')
0d0ba3a410038e179b695446bb149cce6264e0abnd break;
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh buf[k++] = c;
727872d18412fc021f03969b8641810d8896820bhumbedooh }
0d0ba3a410038e179b695446bb149cce6264e0abnd buf[k] = NUL;
0d0ba3a410038e179b695446bb149cce6264e0abnd ssl_util_ppclose(s, p, fp);
0d0ba3a410038e179b695446bb149cce6264e0abnd
ac082aefa89416cbdc9a1836eaf3bed9698201c8humbedooh return buf;
0d0ba3a410038e179b695446bb149cce6264e0abnd}
0d0ba3a410038e179b695446bb149cce6264e0abnd
0d0ba3a410038e179b695446bb149cce6264e0abndBOOL ssl_util_path_check(ssl_pathcheck_t pcm, char *path, apr_pool_t *p)
727872d18412fc021f03969b8641810d8896820bhumbedooh{
0d0ba3a410038e179b695446bb149cce6264e0abnd apr_finfo_t finfo;
0d0ba3a410038e179b695446bb149cce6264e0abnd
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh if (path == NULL)
1a1356f375e36db7bee379ea0684ab389579f798rbowen return FALSE;
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path,
0d0ba3a410038e179b695446bb149cce6264e0abnd APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd return FALSE;
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd return FALSE;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
return FALSE;
if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0)
return FALSE;
return TRUE;
}
ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
{
ssl_algo_t t;
t = SSL_ALGO_UNKNOWN;
if (pCert != NULL)
pKey = X509_get_pubkey(pCert);
if (pKey != NULL) {
switch (EVP_PKEY_type(pKey->type)) {
case EVP_PKEY_RSA:
t = SSL_ALGO_RSA;
break;
case EVP_PKEY_DSA:
t = SSL_ALGO_DSA;
break;
default:
break;
}
}
return t;
}
char *ssl_util_algotypestr(ssl_algo_t t)
{
char *cp;
cp = "UNKNOWN";
switch (t) {
case SSL_ALGO_RSA:
cp = "RSA";
break;
case SSL_ALGO_DSA:
cp = "DSA";
break;
default:
break;
}
return cp;
}
char *ssl_util_ptxtsub(
apr_pool_t *p, const char *cpLine, const char *cpMatch, char *cpSubst)
{
#define MAX_PTXTSUB 100
char *cppMatch[MAX_PTXTSUB];
char *cpResult;
int nResult;
int nLine;
int nSubst;
int nMatch;
char *cpI;
char *cpO;
char *cp;
int i;
/*
* Pass 1: find substitution locations and calculate sizes
*/
nLine = strlen(cpLine);
nMatch = strlen(cpMatch);
nSubst = strlen(cpSubst);
for (cpI = (char *)cpLine, i = 0, nResult = 0;
cpI < cpLine+nLine && i < MAX_PTXTSUB; ) {
if ((cp = strstr(cpI, cpMatch)) != NULL) {
cppMatch[i++] = cp;
nResult += ((cp-cpI)+nSubst);
cpI = (cp+nMatch);
}
else {
nResult += strlen(cpI);
break;
}
}
cppMatch[i] = NULL;
if (i == 0)
return NULL;
/*
* Pass 2: allocate memory and assemble result
*/
cpResult = apr_pcalloc(p, nResult+1);
for (cpI = (char *)cpLine, cpO = cpResult, i = 0; cppMatch[i] != NULL; i++) {
apr_cpystrn(cpO, cpI, cppMatch[i]-cpI+1);
cpO += (cppMatch[i]-cpI);
apr_cpystrn(cpO, cpSubst, nSubst+1);
cpO += nSubst;
cpI = (cppMatch[i]+nMatch);
}
apr_cpystrn(cpO, cpI, cpResult+nResult-cpO+1);
return cpResult;
}
apr_status_t
ssl_util_setmodconfig(
server_rec *s, const char *key, SSLModConfigRec *mc)
{
return apr_pool_userdata_set((void *)mc, key, apr_pool_cleanup_null, s->process->pool);
}
SSLModConfigRec *
ssl_util_getmodconfig(
server_rec *s, const char *key)
{
SSLModConfigRec *mc = NULL;
if (apr_pool_userdata_get((void **)&mc, key, s->process->pool) != APR_SUCCESS)
ssl_log(s, SSL_LOG_TRACE, "Unable to retrieve SSLModConfig from global pool");
return mc;
}
SSLModConfigRec *
ssl_util_getmodconfig_ssl(
SSL *ssl, const char *key)
{
conn_rec *c;
SSLModConfigRec *mc = NULL;
c = SSL_get_app_data(ssl);
if (c != NULL)
mc = ssl_util_getmodconfig(c->base_server, key);
return mc;
}