2 ** _ __ ___ ___ __| | ___ ___| | mod_ssl
3 ** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
4 ** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org
5 ** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org
11 /* ====================================================================
12 * The Apache Software License, Version 1.1
14 * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
29 * 3. The end-user documentation included with the redistribution,
30 * if any, must include the following acknowledgment:
31 * "This product includes software developed by the
32 * Apache Software Foundation (http://www.apache.org/)."
33 * Alternately, this acknowledgment may appear in the software itself,
34 * if and wherever such third-party acknowledgments normally appear.
36 * 4. The names "Apache" and "Apache Software Foundation" must
37 * not be used to endorse or promote products derived from this
38 * software without prior written permission. For written
39 * permission, please contact apache@apache.org.
41 * 5. Products derived from this software may not be called "Apache",
42 * nor may "Apache" appear in their name, without prior written
43 * permission of the Apache Software Foundation.
45 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * ====================================================================
59 /* ``Every day of my life
60 I am forced to add another
61 name to the list of people
67 #include "apr_thread_mutex.h"
69 /* _________________________________________________________________
72 ** _________________________________________________________________
75 char *ssl_util_vhostid(apr_pool_t *p, server_rec *s)
82 host = s->server_hostname;
88 port = DEFAULT_HTTPS_PORT;
90 port = DEFAULT_HTTP_PORT;
92 id = apr_psprintf(p, "%s:%lu", host, (unsigned long)port);
96 void ssl_util_strupper(char *s)
103 static const char ssl_util_uuencode_six2pr[64+1] =
104 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
106 void ssl_util_uuencode(char *szTo, const char *szFrom, BOOL bPad)
108 ssl_util_uuencode_binary((unsigned char *)szTo,
109 (const unsigned char *)szFrom,
110 strlen(szFrom), bPad);
113 void ssl_util_uuencode_binary(unsigned char *szTo,
114 const unsigned char *szFrom,
115 int nLength, BOOL bPad)
117 const unsigned char *s;
120 for (s = szFrom; nLength > 0; s += 3) {
121 *szTo++ = ssl_util_uuencode_six2pr[s[0] >> 2];
122 *szTo++ = ssl_util_uuencode_six2pr[(s[0] << 4 | s[1] >> 4) & 0x3f];
123 if (--nLength == 0) {
127 *szTo++ = ssl_util_uuencode_six2pr[(s[1] << 2 | s[2] >> 6) & 0x3f];
128 if (--nLength == 0) {
132 *szTo++ = ssl_util_uuencode_six2pr[s[2] & 0x3f];
135 while(bPad && nPad--) {
142 apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd,
143 const char * const *argv)
145 apr_procattr_t *procattr;
148 if (apr_procattr_create(&procattr, p) != APR_SUCCESS)
150 if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK,
151 APR_FULL_BLOCK) != APR_SUCCESS)
153 if (apr_procattr_dir_set(procattr,
154 ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS)
156 if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
158 if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL)
160 if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
165 void ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp)
172 * Run a filter program and read the first line of its stdout output
174 char *ssl_util_readfilter(server_rec *s, apr_pool_t *p, const char *cmd,
175 const char * const *argv)
177 static char buf[MAX_STRING_LEN];
179 apr_size_t nbytes = 1;
183 if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL)
185 /* XXX: we are reading 1 byte at a time here */
186 for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
187 && nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) {
188 if (c == '\n' || c == '\r')
193 ssl_util_ppclose(s, p, fp);
198 BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
204 if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path,
205 APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
207 if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
209 if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
211 if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0)
216 ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
220 t = SSL_ALGO_UNKNOWN;
222 pKey = X509_get_pubkey(pCert);
224 switch (EVP_PKEY_key_type(pKey)) {
238 char *ssl_util_algotypestr(ssl_algo_t t)
256 char *ssl_util_ptxtsub(apr_pool_t *p, const char *cpLine,
257 const char *cpMatch, char *cpSubst)
259 #define MAX_PTXTSUB 100
260 char *cppMatch[MAX_PTXTSUB];
272 * Pass 1: find substitution locations and calculate sizes
274 nLine = strlen(cpLine);
275 nMatch = strlen(cpMatch);
276 nSubst = strlen(cpSubst);
277 for (cpI = (char *)cpLine, i = 0, nResult = 0;
278 cpI < cpLine+nLine && i < MAX_PTXTSUB; ) {
279 if ((cp = strstr(cpI, cpMatch)) != NULL) {
281 nResult += ((cp-cpI)+nSubst);
285 nResult += strlen(cpI);
294 * Pass 2: allocate memory and assemble result
296 cpResult = apr_pcalloc(p, nResult+1);
297 for (cpI = (char *)cpLine, cpO = cpResult, i = 0;
300 apr_cpystrn(cpO, cpI, cppMatch[i]-cpI+1);
301 cpO += (cppMatch[i]-cpI);
302 apr_cpystrn(cpO, cpSubst, nSubst+1);
304 cpI = (cppMatch[i]+nMatch);
306 apr_cpystrn(cpO, cpI, cpResult+nResult-cpO+1);
312 * certain key and cert data needs to survive restarts,
313 * which are stored in the user data table of s->process->pool.
314 * to prevent "leaking" of this data, we use malloc/free
315 * rather than apr_palloc and these wrappers to help make sure
316 * we do not leak the malloc-ed data.
318 unsigned char *ssl_asn1_table_set(apr_hash_t *table,
322 apr_ssize_t klen = strlen(key);
323 ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
326 * if a value for this key already exists,
327 * reuse as much of the already malloc-ed data
331 if (asn1->nData != length) {
332 free(asn1->cpData); /* XXX: realloc? */
337 asn1 = malloc(sizeof(*asn1));
338 asn1->source_mtime = 0; /* used as a note for encrypted private keys */
342 asn1->nData = length;
344 asn1->cpData = malloc(length);
347 apr_hash_set(table, key, klen, asn1);
349 return asn1->cpData; /* caller will assign a value to this */
352 ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
355 return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);
358 void ssl_asn1_table_unset(apr_hash_t *table,
361 apr_ssize_t klen = strlen(key);
362 ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
373 apr_hash_set(table, key, klen, NULL);
378 * To ensure thread-safetyness in OpenSSL - work in progress
381 static apr_thread_mutex_t **lock_cs;
382 /* FIXME: CRYPTO_NUM_LOCKS may vary between releases - replace with
383 CRYPT_num_locks() [Ben, Jan 2002] */
384 static long lock_count[CRYPTO_NUM_LOCKS];
386 static void ssl_util_thr_lock(int mode, int type, const char *file, int line)
388 if (mode & CRYPTO_LOCK) {
389 apr_thread_mutex_lock(lock_cs[type]);
393 apr_thread_mutex_unlock(lock_cs[type]);
397 static unsigned long ssl_util_thr_id(void)
399 return (unsigned long) apr_os_thread_current();
402 static apr_status_t ssl_util_thread_cleanup(void *data)
406 CRYPTO_set_locking_callback(NULL);
408 for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
409 apr_thread_mutex_destroy(lock_cs[i]);
415 void ssl_util_thread_setup(server_rec *s, apr_pool_t *p)
418 /* This variable is not used? -aaron
419 SSLModConfigRec *mc = myModConfig(s);
422 ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded_mpm);
428 lock_cs = apr_palloc(p, CRYPTO_NUM_LOCKS * sizeof(apr_thread_mutex_t *));
431 * XXX: CRYPTO_NUM_LOCKS == 28
432 * should determine if there are lock types we do not need
433 * for example: debug_malloc, debug_malloc2 (see crypto/cryptlib.c)
435 for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
437 /* XXX: Can we remove the lock_count now that apr_thread_mutex_t
438 * can support nested (aka recursive) locks? -aaron */
439 apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p);
442 CRYPTO_set_id_callback(ssl_util_thr_id);
444 CRYPTO_set_locking_callback(ssl_util_thr_lock);
446 apr_pool_cleanup_register(p, NULL,
447 ssl_util_thread_cleanup,
448 apr_pool_cleanup_null);