]> granicus.if.org Git - apache/blob - modules/ssl/ssl_engine_init.c
fixed code style, missing prototype warnings, disabled init for proxy, removed obsole...
[apache] / modules / ssl / ssl_engine_init.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*                      _             _
18  *  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
19  * | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
20  * | | | | | | (_) | (_| |   \__ \__ \ |
21  * |_| |_| |_|\___/ \__,_|___|___/___/_|
22  *                      |_____|
23  *  ssl_engine_init.c
24  *  Initialization of Servers
25  */
26                              /* ``Recursive, adj.;
27                                   see Recursive.''
28                                         -- Unknown   */
29 #include "ssl_private.h"
30
31 /*  _________________________________________________________________
32 **
33 **  Module Initialization
34 **  _________________________________________________________________
35 */
36
37
38 static void ssl_add_version_components(apr_pool_t *p,
39                                        server_rec *s)
40 {
41     char *modver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_INTERFACE");
42     char *libver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_LIBRARY");
43     char *incver = ssl_var_lookup(p, s, NULL, NULL, 
44                                   "SSL_VERSION_LIBRARY_INTERFACE");
45
46     ap_add_version_component(p, modver);
47     ap_add_version_component(p, libver);
48
49     ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
50                  "%s compiled against Server: %s, Library: %s",
51                  modver, AP_SERVER_BASEVERSION, incver);
52 }
53
54
55 /*
56  * Handle the Temporary RSA Keys and DH Params
57  */
58
59 #define MODSSL_TMP_KEY_FREE(mc, type, idx) \
60     if (mc->pTmpKeys[idx]) { \
61         type##_free((type *)mc->pTmpKeys[idx]); \
62         mc->pTmpKeys[idx] = NULL; \
63     }
64
65 #define MODSSL_TMP_KEYS_FREE(mc, type) \
66     MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_512); \
67     MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_1024)
68
69 static void ssl_tmp_keys_free(server_rec *s)
70 {
71     SSLModConfigRec *mc = myModConfig(s);
72
73     MODSSL_TMP_KEYS_FREE(mc, RSA);
74     MODSSL_TMP_KEYS_FREE(mc, DH);
75 }
76
77 static int ssl_tmp_key_init_rsa(server_rec *s,
78                                 int bits, int idx)
79 {
80     SSLModConfigRec *mc = myModConfig(s);
81
82     if (!(mc->pTmpKeys[idx] =
83           RSA_generate_key(bits, RSA_F4, NULL, NULL)))
84     {
85         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
86                      "Init: Failed to generate temporary "
87                      "%d bit RSA private key", bits);
88         return !OK;
89     }
90
91     return OK;
92 }
93
94 static int ssl_tmp_key_init_dh(server_rec *s,
95                                int bits, int idx)
96 {
97     SSLModConfigRec *mc = myModConfig(s);
98
99     if (!(mc->pTmpKeys[idx] =
100           ssl_dh_GetTmpParam(bits)))
101     {
102         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
103                      "Init: Failed to generate temporary "
104                      "%d bit DH parameters", bits);
105         return !OK;
106     }
107
108     return OK;
109 }
110
111 #define MODSSL_TMP_KEY_INIT_RSA(s, bits) \
112     ssl_tmp_key_init_rsa(s, bits, SSL_TMP_KEY_RSA_##bits)
113
114 #define MODSSL_TMP_KEY_INIT_DH(s, bits) \
115     ssl_tmp_key_init_dh(s, bits, SSL_TMP_KEY_DH_##bits)
116
117 static int ssl_tmp_keys_init(server_rec *s)
118 {
119     ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
120                  "Init: Generating temporary RSA private keys (512/1024 bits)");
121
122     if (MODSSL_TMP_KEY_INIT_RSA(s, 512) ||
123         MODSSL_TMP_KEY_INIT_RSA(s, 1024)) {
124         return !OK;
125     }
126
127     ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
128                  "Init: Generating temporary DH parameters (512/1024 bits)");
129
130     if (MODSSL_TMP_KEY_INIT_DH(s, 512) ||
131         MODSSL_TMP_KEY_INIT_DH(s, 1024)) {
132         return !OK;
133     }
134
135     return OK;
136 }
137
138 #ifndef OPENSSL_NO_TLSEXT
139 static int set_ssl_vhost(void *servername, conn_rec *c, server_rec *s) 
140 {
141     SSLSrvConfigRec *sc;
142     SSL *ssl;
143     BOOL found = FALSE;
144     apr_array_header_t *names;
145     int i;
146
147     /* check ServerName */
148     if (!strcasecmp(servername, s->server_hostname))
149         found = TRUE;
150
151     /* if not matched yet, check ServerAlias entries */
152     if (!found) {
153         names = s->names;
154         if (names) {
155             char **name = (char **)names->elts;
156             for (i = 0; i < names->nelts; ++i) {
157                 if (!name[i])
158                     continue;
159                 if (!strcasecmp(servername, name[i])) {
160                     found = TRUE;
161                     break;
162                 }
163             }
164         }
165     }
166
167     /* if still no match, check ServerAlias entries with wildcards */
168     if (!found) {
169         names = s->wild_names;
170         if (names) {
171             char **name = (char **)names->elts;
172             for (i = 0; i < names->nelts; ++i) {
173                 if (!name[i])
174                     continue;
175                 if (!ap_strcasecmp_match(servername, name[i])) {
176                     found = TRUE;
177                     break;
178                 }
179             }
180         }
181     }
182
183     /* set SSL_CTX (if matched) */
184     if (found) {
185         if ((ssl = ((SSLConnRec *)myConnConfig(c))->ssl) == NULL)
186             return 0;
187         if (!(sc = mySrvConfig(s)))
188             return 0;
189         SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx);
190         return 1;
191     }
192     return 0;
193 }
194
195 int ssl_set_vhost_ctx(SSL *ssl, const char *servername) 
196 {
197     conn_rec *c;
198
199     if (servername == NULL)   /* should not occur. */
200         return 0;
201     SSL_set_SSL_CTX(ssl, NULL);
202     if (!(c = (conn_rec *)SSL_get_app_data(ssl)))
203         return 0;
204     return ap_vhost_iterate_given_conn(c, set_ssl_vhost, (void *)servername);
205 }
206
207 int ssl_servername_cb(SSL *ssl, int *al, modssl_ctx_t *mctx)
208 {
209     const char *servername =
210                 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
211     if (servername)
212         return ssl_set_vhost_ctx(ssl, servername) ? 
213                 SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_ALERT_FATAL;
214     return SSL_TLSEXT_ERR_NOACK;
215 }
216 #endif
217
218 /*
219  *  Per-module initialization
220  */
221 int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
222                     apr_pool_t *ptemp,
223                     server_rec *base_server)
224 {
225     SSLModConfigRec *mc = myModConfig(base_server);
226     SSLSrvConfigRec *sc;
227     server_rec *s;
228
229     /* We initialize mc->pid per-process in the child init,
230      * but it should be initialized for startup before we
231      * call ssl_rand_seed() below.
232      */
233     mc->pid = getpid();
234
235     /*
236      * Let us cleanup on restarts and exists
237      */
238     apr_pool_cleanup_register(p, base_server,
239                               ssl_init_ModuleKill,
240                               apr_pool_cleanup_null);
241
242     /*
243      * Any init round fixes the global config
244      */
245     ssl_config_global_create(base_server); /* just to avoid problems */
246     ssl_config_global_fix(mc);
247
248     /*
249      *  try to fix the configuration and open the dedicated SSL
250      *  logfile as early as possible
251      */
252     for (s = base_server; s; s = s->next) {
253         sc = mySrvConfig(s);
254
255         if (sc->server) {
256             sc->server->sc = sc;
257         }
258
259         if (sc->proxy) {
260             sc->proxy->sc = sc;
261         }
262
263         /*
264          * Create the server host:port string because we need it a lot
265          */
266         sc->vhost_id = ssl_util_vhostid(p, s);
267         sc->vhost_id_len = strlen(sc->vhost_id);
268
269         if (ap_get_server_protocol(s) &&
270             strcmp("https", ap_get_server_protocol(s)) == 0) {
271             sc->enabled = SSL_ENABLED_TRUE;
272         }
273
274        /* If sc->enabled is UNSET, then SSL is optional on this vhost  */
275         /* Fix up stuff that may not have been set */
276         if (sc->enabled == SSL_ENABLED_UNSET) {
277             sc->enabled = SSL_ENABLED_FALSE;
278         }
279         if (sc->proxy_enabled == UNSET) {
280             sc->proxy_enabled = FALSE;
281         }
282
283         if (sc->session_cache_timeout == UNSET) {
284             sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT;
285         }
286
287         if (sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) {
288             sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
289         }
290
291     }
292
293 #if APR_HAS_THREADS
294     ssl_util_thread_setup(p);
295 #endif
296
297     /*
298      * SSL external crypto device ("engine") support
299      */
300 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
301     ssl_init_Engine(base_server, p);
302 #endif
303
304     ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
305                  "Init: Initialized %s library", SSL_LIBRARY_NAME);
306
307     /*
308      * Seed the Pseudo Random Number Generator (PRNG)
309      * only need ptemp here; nothing inside allocated from the pool
310      * needs to live once we return from ssl_rand_seed().
311      */
312     ssl_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init: ");
313
314     /*
315      * read server private keys/public certs into memory.
316      * decrypting any encrypted keys via configured SSLPassPhraseDialogs
317      * anything that needs to live longer than ptemp needs to also survive
318      * restarts, in which case they'll live inside s->process->pool.
319      */
320     ssl_pphrase_Handle(base_server, ptemp);
321
322     if (ssl_tmp_keys_init(base_server)) {
323         return !OK;
324     }
325
326     /*
327      * initialize the mutex handling
328      */
329     if (!ssl_mutex_init(base_server, p)) {
330         return HTTP_INTERNAL_SERVER_ERROR;
331     }
332
333     /*
334      * initialize session caching
335      */
336     ssl_scache_init(base_server, p);
337
338     /*
339      *  initialize servers
340      */
341     ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server,
342                  "Init: Initializing (virtual) servers for SSL");
343
344     for (s = base_server; s; s = s->next) {
345         sc = mySrvConfig(s);
346         /*
347          * Either now skip this server when SSL is disabled for
348          * it or give out some information about what we're
349          * configuring.
350          */
351
352         /*
353          * Read the server certificate and key
354          */
355         ssl_init_ConfigureServer(s, p, ptemp, sc);
356     }
357
358     /*
359      * Configuration consistency checks
360      */
361     ssl_init_CheckServers(base_server, ptemp);
362
363     /*
364      *  Announce mod_ssl and SSL library in HTTP Server field
365      *  as ``mod_ssl/X.X.X OpenSSL/X.X.X''
366      */
367     ssl_add_version_components(p, base_server);
368
369     SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */
370
371     return OK;
372 }
373
374 /*
375  * Support for external a Crypto Device ("engine"), usually
376  * a hardware accellerator card for crypto operations.
377  */
378 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
379 void ssl_init_Engine(server_rec *s, apr_pool_t *p)
380 {
381     SSLModConfigRec *mc = myModConfig(s);
382     ENGINE *e;
383
384     if (mc->szCryptoDevice) {
385         if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
386             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
387                          "Init: Failed to load Crypto Device API `%s'",
388                          mc->szCryptoDevice);
389             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
390             ssl_die();
391         }
392
393         if (strEQ(mc->szCryptoDevice, "chil")) {
394             ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
395         }
396
397         if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
398             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
399                          "Init: Failed to enable Crypto Device API `%s'",
400                          mc->szCryptoDevice);
401             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
402             ssl_die();
403         }
404
405         ENGINE_free(e);
406     }
407 }
408 #endif
409
410 static void ssl_init_server_check(server_rec *s,
411                                   apr_pool_t *p,
412                                   apr_pool_t *ptemp,
413                                   modssl_ctx_t *mctx)
414 {
415     /*
416      * check for important parameters and the
417      * possibility that the user forgot to set them.
418      */
419     if (!mctx->pks->cert_files[0] && !mctx->pkcs7) {
420         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
421                 "No SSL Certificate set [hint: SSLCertificateFile]");
422         ssl_die();
423     }
424
425     /*
426      *  Check for problematic re-initializations
427      */
428     if (mctx->pks->certs[SSL_AIDX_RSA] ||
429         mctx->pks->certs[SSL_AIDX_DSA])
430     {
431         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
432                 "Illegal attempt to re-initialise SSL for server "
433                 "(theoretically shouldn't happen!)");
434         ssl_die();
435     }
436 }
437
438 static void ssl_init_server_extensions(server_rec *s,
439                                        apr_pool_t *p,
440                                        apr_pool_t *ptemp,
441                                        modssl_ctx_t *mctx)
442 {
443     /*
444      * Configure TLS extensions support
445      */
446 #ifndef OPENSSL_NO_TLSEXT
447     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
448                  "Configuring TLS extensions facility");
449
450     if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
451                                                 ssl_servername_cb) ||
452         !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) {
453         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
454                      "Unable to initialize servername callback - "
455                      "bad OpenSSL version.");
456         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
457         ssl_die();
458     }
459 #endif
460 }
461
462 static void ssl_init_ctx_protocol(server_rec *s,
463                                   apr_pool_t *p,
464                                   apr_pool_t *ptemp,
465                                   modssl_ctx_t *mctx)
466 {
467     SSL_CTX *ctx = NULL;
468     MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL;
469     char *cp;
470     int protocol = mctx->protocol;
471
472     /*
473      *  Create the new per-server SSL context
474      */
475     if (protocol == SSL_PROTOCOL_NONE) {
476         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
477                 "No SSL protocols available [hint: SSLProtocol]");
478         ssl_die();
479     }
480
481     cp = apr_pstrcat(p,
482                      (protocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
483                      (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
484                      (protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
485                      NULL);
486     cp[strlen(cp)-2] = NUL;
487
488     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
489                  "Creating new SSL context (protocols: %s)", cp);
490
491     if (protocol == SSL_PROTOCOL_SSLV2) {
492         method = mctx->pkp ?
493             SSLv2_client_method() : /* proxy */
494             SSLv2_server_method();  /* server */
495     }
496     else if (protocol == SSL_PROTOCOL_SSLV3) {
497         method = mctx->pkp ?
498             SSLv3_client_method() : /* proxy */
499             SSLv3_server_method();  /* server */
500     }
501     else if (protocol == SSL_PROTOCOL_TLSV1) {
502         method = mctx->pkp ?
503             TLSv1_client_method() : /* proxy */
504             TLSv1_server_method();  /* server */
505     }
506     else { /* For multiple protocols, we need a flexible method */
507         method = mctx->pkp ?
508             SSLv23_client_method() : /* proxy */
509             SSLv23_server_method();  /* server */
510     }
511     ctx = SSL_CTX_new(method);
512
513     mctx->ssl_ctx = ctx;
514
515     SSL_CTX_set_options(ctx, SSL_OP_ALL);
516
517     if (!(protocol & SSL_PROTOCOL_SSLV2)) {
518         SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
519     }
520
521     if (!(protocol & SSL_PROTOCOL_SSLV3)) {
522         SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
523     }
524
525     if (!(protocol & SSL_PROTOCOL_TLSV1)) {
526         SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
527     }
528
529 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
530     {
531         SSLSrvConfigRec *sc = mySrvConfig(s);
532         if (sc->cipher_server_pref == TRUE) {
533             SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
534         }
535     }
536 #endif
537
538     SSL_CTX_set_app_data(ctx, s);
539
540     /*
541      * Configure additional context ingredients
542      */
543     SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
544
545 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
546     /*
547      * Disallow a session from being resumed during a renegotiation,
548      * so that an acceptable cipher suite can be negotiated.
549      */
550     SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
551 #endif
552 }
553
554 static void ssl_init_ctx_session_cache(server_rec *s,
555                                        apr_pool_t *p,
556                                        apr_pool_t *ptemp,
557                                        modssl_ctx_t *mctx)
558 {
559     SSL_CTX *ctx = mctx->ssl_ctx;
560     SSLModConfigRec *mc = myModConfig(s);
561     long cache_mode = SSL_SESS_CACHE_OFF;
562     if (mc->nSessionCacheMode != SSL_SCMODE_NONE) {
563         /* SSL_SESS_CACHE_NO_INTERNAL will force OpenSSL
564          * to ignore process local-caching and
565          * to always get/set/delete sessions using mod_ssl's callbacks.
566          */
567         cache_mode = SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL;
568     }
569
570     SSL_CTX_set_session_cache_mode(ctx, cache_mode);
571
572     SSL_CTX_sess_set_new_cb(ctx,    ssl_callback_NewSessionCacheEntry);
573     SSL_CTX_sess_set_get_cb(ctx,    ssl_callback_GetSessionCacheEntry);
574     SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
575 }
576
577 static void ssl_init_ctx_callbacks(server_rec *s,
578                                    apr_pool_t *p,
579                                    apr_pool_t *ptemp,
580                                    modssl_ctx_t *mctx)
581 {
582     SSL_CTX *ctx = mctx->ssl_ctx;
583
584     SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
585     SSL_CTX_set_tmp_dh_callback(ctx,  ssl_callback_TmpDH);
586
587     if (s->loglevel >= APLOG_DEBUG) {
588         /* this callback only logs if LogLevel >= info */
589         SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState);
590     }
591 }
592
593 static void ssl_init_ctx_verify(server_rec *s,
594                                 apr_pool_t *p,
595                                 apr_pool_t *ptemp,
596                                 modssl_ctx_t *mctx)
597 {
598     SSL_CTX *ctx = mctx->ssl_ctx;
599
600     int verify = SSL_VERIFY_NONE;
601     STACK_OF(X509_NAME) *ca_list;
602
603     if (mctx->auth.verify_mode == SSL_CVERIFY_UNSET) {
604         mctx->auth.verify_mode = SSL_CVERIFY_NONE;
605     }
606
607     if (mctx->auth.verify_depth == UNSET) {
608         mctx->auth.verify_depth = 1;
609     }
610
611     /*
612      *  Configure callbacks for SSL context
613      */
614     if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
615         verify |= SSL_VERIFY_PEER_STRICT;
616     }
617
618     if ((mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
619         (mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
620     {
621         verify |= SSL_VERIFY_PEER;
622     }
623
624     SSL_CTX_set_verify(ctx, verify, ssl_callback_SSLVerify);
625
626     /*
627      * Configure Client Authentication details
628      */
629     if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) {
630         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
631                      "Configuring client authentication");
632
633         if (!SSL_CTX_load_verify_locations(ctx,
634                          MODSSL_PCHAR_CAST mctx->auth.ca_cert_file,
635                          MODSSL_PCHAR_CAST mctx->auth.ca_cert_path))
636         {
637             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
638                     "Unable to configure verify locations "
639                     "for client authentication");
640             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
641             ssl_die();
642         }
643
644         if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) {
645             ca_list = ssl_init_FindCAList(s, ptemp,
646                                           mctx->pks->ca_name_file,
647                                           mctx->pks->ca_name_path);
648         } else
649             ca_list = ssl_init_FindCAList(s, ptemp,
650                                           mctx->auth.ca_cert_file,
651                                           mctx->auth.ca_cert_path);
652         if (!ca_list) {
653             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
654                     "Unable to determine list of acceptable "
655                     "CA certificates for client authentication");
656             ssl_die();
657         }
658
659         SSL_CTX_set_client_CA_list(ctx, (STACK *)ca_list);
660     }
661
662     /*
663      * Give a warning when no CAs were configured but client authentication
664      * should take place. This cannot work.
665      */
666     if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
667         ca_list = (STACK_OF(X509_NAME) *)SSL_CTX_get_client_CA_list(ctx);
668
669         if (sk_X509_NAME_num(ca_list) == 0) {
670             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
671                          "Init: Oops, you want to request client "
672                          "authentication, but no CAs are known for "
673                          "verification!?  [Hint: SSLCACertificate*]");
674         }
675     }
676 }
677
678 static void ssl_init_ctx_cipher_suite(server_rec *s,
679                                       apr_pool_t *p,
680                                       apr_pool_t *ptemp,
681                                       modssl_ctx_t *mctx)
682 {
683     SSL_CTX *ctx = mctx->ssl_ctx;
684     const char *suite = mctx->auth.cipher_suite;
685
686     /*
687      *  Configure SSL Cipher Suite
688      */
689     if (!suite) {
690         return;
691     }
692
693     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
694                  "Configuring permitted SSL ciphers [%s]",
695                  suite);
696
697     if (!SSL_CTX_set_cipher_list(ctx, MODSSL_PCHAR_CAST suite)) {
698         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
699                 "Unable to configure permitted SSL ciphers");
700         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
701         ssl_die();
702     }
703 }
704
705 static void ssl_init_ctx_crl(server_rec *s,
706                              apr_pool_t *p,
707                              apr_pool_t *ptemp,
708                              modssl_ctx_t *mctx)
709 {
710     /*
711      * Configure Certificate Revocation List (CRL) Details
712      */
713
714     if (!(mctx->crl_file || mctx->crl_path)) {
715         return;
716     }
717
718     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
719                  "Configuring certificate revocation facility");
720
721     mctx->crl =
722         SSL_X509_STORE_create((char *)mctx->crl_file,
723                               (char *)mctx->crl_path);
724
725     if (!mctx->crl) {
726         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
727                 "Unable to configure X.509 CRL storage "
728                 "for certificate revocation");
729         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
730         ssl_die();
731     }
732 }
733
734 static void ssl_init_ctx_pkcs7_cert_chain(server_rec *s, modssl_ctx_t *mctx)
735 {
736     STACK_OF(X509) *certs = ssl_read_pkcs7(s, mctx->pkcs7);
737     int n;
738
739     if (!mctx->ssl_ctx->extra_certs)
740         for (n = 1; n < sk_X509_num(certs); ++n)
741              SSL_CTX_add_extra_chain_cert(mctx->ssl_ctx, sk_X509_value(certs, n));
742 }
743
744 static void ssl_init_ctx_cert_chain(server_rec *s,
745                                     apr_pool_t *p,
746                                     apr_pool_t *ptemp,
747                                     modssl_ctx_t *mctx)
748 {
749     BOOL skip_first = FALSE;
750     int i, n;
751     const char *chain = mctx->cert_chain;
752
753     if (mctx->pkcs7) {
754         ssl_init_ctx_pkcs7_cert_chain(s, mctx);
755         return;
756     }
757
758     /*
759      * Optionally configure extra server certificate chain certificates.
760      * This is usually done by OpenSSL automatically when one of the
761      * server cert issuers are found under SSLCACertificatePath or in
762      * SSLCACertificateFile. But because these are intended for client
763      * authentication it can conflict. For instance when you use a
764      * Global ID server certificate you've to send out the intermediate
765      * CA certificate, too. When you would just configure this with
766      * SSLCACertificateFile and also use client authentication mod_ssl
767      * would accept all clients also issued by this CA. Obviously this
768      * isn't what we want in this situation. So this feature here exists
769      * to allow one to explicity configure CA certificates which are
770      * used only for the server certificate chain.
771      */
772     if (!chain) {
773         return;
774     }
775
776     for (i = 0; (i < SSL_AIDX_MAX) && mctx->pks->cert_files[i]; i++) {
777         if (strEQ(mctx->pks->cert_files[i], chain)) {
778             skip_first = TRUE;
779             break;
780         }
781     }
782
783     n = SSL_CTX_use_certificate_chain(mctx->ssl_ctx,
784                                       (char *)chain,
785                                       skip_first, NULL);
786     if (n < 0) {
787         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
788                 "Failed to configure CA certificate chain!");
789         ssl_die();
790     }
791
792     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
793                  "Configuring server certificate chain "
794                  "(%d CA certificate%s)",
795                  n, n == 1 ? "" : "s");
796 }
797
798 static void ssl_init_ctx(server_rec *s,
799                          apr_pool_t *p,
800                          apr_pool_t *ptemp,
801                          modssl_ctx_t *mctx)
802 {
803     ssl_init_ctx_protocol(s, p, ptemp, mctx);
804
805     ssl_init_ctx_session_cache(s, p, ptemp, mctx);
806
807     ssl_init_ctx_callbacks(s, p, ptemp, mctx);
808
809     ssl_init_ctx_verify(s, p, ptemp, mctx);
810
811     ssl_init_ctx_cipher_suite(s, p, ptemp, mctx);
812
813     ssl_init_ctx_crl(s, p, ptemp, mctx);
814
815     if (mctx->pks) {
816         /* XXX: proxy support? */
817         ssl_init_ctx_cert_chain(s, p, ptemp, mctx);
818         ssl_init_server_extensions(s, p, ptemp, mctx);
819     }
820 }
821
822 static int ssl_server_import_cert(server_rec *s,
823                                   modssl_ctx_t *mctx,
824                                   const char *id,
825                                   int idx)
826 {
827     SSLModConfigRec *mc = myModConfig(s);
828     ssl_asn1_t *asn1;
829     MODSSL_D2I_X509_CONST unsigned char *ptr;
830     const char *type = ssl_asn1_keystr(idx);
831     X509 *cert;
832
833     if (!(asn1 = ssl_asn1_table_get(mc->tPublicCert, id))) {
834         return FALSE;
835     }
836
837     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
838                  "Configuring %s server certificate", type);
839
840     ptr = asn1->cpData;
841     if (!(cert = d2i_X509(NULL, &ptr, asn1->nData))) {
842         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
843                 "Unable to import %s server certificate", type);
844         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
845         ssl_die();
846     }
847
848     if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) {
849         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
850                 "Unable to configure %s server certificate", type);
851         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
852         ssl_die();
853     }
854
855     mctx->pks->certs[idx] = cert;
856
857     return TRUE;
858 }
859
860 static int ssl_server_import_key(server_rec *s,
861                                  modssl_ctx_t *mctx,
862                                  const char *id,
863                                  int idx)
864 {
865     SSLModConfigRec *mc = myModConfig(s);
866     ssl_asn1_t *asn1;
867     MODSSL_D2I_PrivateKey_CONST unsigned char *ptr;
868     const char *type = ssl_asn1_keystr(idx);
869     int pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
870     EVP_PKEY *pkey;
871
872     if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) {
873         return FALSE;
874     }
875
876     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
877                  "Configuring %s server private key", type);
878
879     ptr = asn1->cpData;
880     if (!(pkey = d2i_PrivateKey(pkey_type, NULL, &ptr, asn1->nData)))
881     {
882         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
883                 "Unable to import %s server private key", type);
884         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
885         ssl_die();
886     }
887
888     if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) {
889         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
890                 "Unable to configure %s server private key", type);
891         ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
892         ssl_die();
893     }
894
895     /*
896      * XXX: wonder if this is still needed, this is old todo doc.
897      * (see http://www.psy.uq.edu.au/~ftp/Crypto/ssleay/TODO.html)
898      */
899     if ((pkey_type == EVP_PKEY_DSA) && mctx->pks->certs[idx]) {
900         EVP_PKEY *pubkey = X509_get_pubkey(mctx->pks->certs[idx]);
901
902         if (pubkey && EVP_PKEY_missing_parameters(pubkey)) {
903             EVP_PKEY_copy_parameters(pubkey, pkey);
904             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
905                     "Copying DSA parameters from private key to certificate");
906             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
907             EVP_PKEY_free(pubkey);
908         }
909     }
910
911     mctx->pks->keys[idx] = pkey;
912
913     return TRUE;
914 }
915
916 static void ssl_check_public_cert(server_rec *s,
917                                   apr_pool_t *ptemp,
918                                   X509 *cert,
919                                   int type)
920 {
921     int is_ca, pathlen;
922     char *cn;
923
924     if (!cert) {
925         return;
926     }
927
928     /*
929      * Some information about the certificate(s)
930      */
931
932     if (SSL_X509_isSGC(cert)) {
933         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
934                      "%s server certificate enables "
935                      "Server Gated Cryptography (SGC)",
936                      ssl_asn1_keystr(type));
937     }
938
939     if (SSL_X509_getBC(cert, &is_ca, &pathlen)) {
940         if (is_ca) {
941             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
942                          "%s server certificate is a CA certificate "
943                          "(BasicConstraints: CA == TRUE !?)",
944                          ssl_asn1_keystr(type));
945         }
946
947         if (pathlen > 0) {
948             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
949                          "%s server certificate is not a leaf certificate "
950                          "(BasicConstraints: pathlen == %d > 0 !?)",
951                          ssl_asn1_keystr(type), pathlen);
952         }
953     }
954
955     if (SSL_X509_getCN(ptemp, cert, &cn)) {
956         int fnm_flags = APR_FNM_PERIOD|APR_FNM_CASE_BLIND;
957
958         if (apr_fnmatch_test(cn)) {
959             if (apr_fnmatch(cn, s->server_hostname,
960                             fnm_flags) == APR_FNM_NOMATCH) {
961                 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
962                              "%s server certificate wildcard CommonName "
963                              "(CN) `%s' does NOT match server name!?",
964                              ssl_asn1_keystr(type), cn);
965             }
966         }
967         else if (strNE(s->server_hostname, cn)) {
968             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
969                          "%s server certificate CommonName (CN) `%s' "
970                          "does NOT match server name!?",
971                          ssl_asn1_keystr(type), cn);
972         }
973     }
974 }
975
976 static void ssl_init_server_certs(server_rec *s,
977                                   apr_pool_t *p,
978                                   apr_pool_t *ptemp,
979                                   modssl_ctx_t *mctx)
980 {
981     const char *rsa_id, *dsa_id;
982     const char *vhost_id = mctx->sc->vhost_id;
983     int i;
984     int have_rsa, have_dsa;
985
986     rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
987     dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);
988
989     have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
990     have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);
991
992     if (!(have_rsa || have_dsa)) {
993         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
994                 "Oops, no RSA or DSA server certificate found "
995                 "for '%s:%d'?!", s->server_hostname, s->port);
996         ssl_die();
997     }
998
999     for (i = 0; i < SSL_AIDX_MAX; i++) {
1000         ssl_check_public_cert(s, ptemp, mctx->pks->certs[i], i);
1001     }
1002
1003     have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA);
1004     have_dsa = ssl_server_import_key(s, mctx, dsa_id, SSL_AIDX_DSA);
1005
1006     if (!(have_rsa || have_dsa)) {
1007         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
1008                 "Oops, no RSA or DSA server private key found?!");
1009         ssl_die();
1010     }
1011 }
1012
1013 static void ssl_init_proxy_certs(server_rec *s,
1014                                  apr_pool_t *p,
1015                                  apr_pool_t *ptemp,
1016                                  modssl_ctx_t *mctx)
1017 {
1018     int n, ncerts = 0;
1019     STACK_OF(X509_INFO) *sk;
1020     modssl_pk_proxy_t *pkp = mctx->pkp;
1021
1022     SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
1023                                ssl_callback_proxy_cert);
1024
1025     if (!(pkp->cert_file || pkp->cert_path)) {
1026         return;
1027     }
1028
1029     sk = sk_X509_INFO_new_null();
1030
1031     if (pkp->cert_file) {
1032         SSL_X509_INFO_load_file(ptemp, sk, pkp->cert_file);
1033     }
1034
1035     if (pkp->cert_path) {
1036         SSL_X509_INFO_load_path(ptemp, sk, pkp->cert_path);
1037     }
1038
1039     if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
1040         sk_X509_INFO_free(sk);
1041         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
1042                      "no client certs found for SSL proxy");
1043         return;
1044     }
1045
1046     /* Check that all client certs have got certificates and private
1047      * keys. */
1048     for (n = 0; n < ncerts; n++) {
1049         X509_INFO *inf = sk_X509_INFO_value(sk, n);
1050
1051         if (!inf->x509 || !inf->x_pkey) {
1052             sk_X509_INFO_free(sk);
1053             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
1054                          "incomplete client cert configured for SSL proxy "
1055                          "(missing or encrypted private key?)");
1056             ssl_die();
1057             return;
1058         }
1059     }
1060
1061     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
1062                  "loaded %d client certs for SSL proxy",
1063                  ncerts);
1064     pkp->certs = sk;
1065 }
1066
1067 static void ssl_init_proxy_ctx(server_rec *s,
1068                                apr_pool_t *p,
1069                                apr_pool_t *ptemp,
1070                                SSLSrvConfigRec *sc)
1071 {
1072     ssl_init_ctx(s, p, ptemp, sc->proxy);
1073
1074     ssl_init_proxy_certs(s, p, ptemp, sc->proxy);
1075 }
1076
1077 static void ssl_init_server_ctx(server_rec *s,
1078                                 apr_pool_t *p,
1079                                 apr_pool_t *ptemp,
1080                                 SSLSrvConfigRec *sc)
1081 {
1082     ssl_init_server_check(s, p, ptemp, sc->server);
1083
1084     ssl_init_ctx(s, p, ptemp, sc->server);
1085
1086     ssl_init_server_certs(s, p, ptemp, sc->server);
1087 }
1088
1089 /*
1090  * Configure a particular server
1091  */
1092 void ssl_init_ConfigureServer(server_rec *s,
1093                               apr_pool_t *p,
1094                               apr_pool_t *ptemp,
1095                               SSLSrvConfigRec *sc)
1096 {
1097     /* Initialize the server if SSL is enabled or optional.
1098      */
1099     if ((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) {
1100         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
1101                      "Configuring server for SSL protocol");
1102         ssl_init_server_ctx(s, p, ptemp, sc);
1103     }
1104
1105     if (sc->proxy_enabled) {
1106         ssl_init_proxy_ctx(s, p, ptemp, sc);
1107     }
1108 }
1109
1110 void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
1111 {
1112     SSLSrvConfigRec *sc;
1113     server_rec *s;
1114 #ifdef OPENSSL_NO_TLSEXT
1115     server_rec *ps;
1116     apr_hash_t *table;
1117     const char *key;
1118     apr_ssize_t klen;
1119
1120     BOOL conflict = FALSE;
1121 #endif
1122
1123     /*
1124      * Give out warnings when a server has HTTPS configured
1125      * for the HTTP port or vice versa
1126      */
1127     for (s = base_server; s; s = s->next) {
1128         sc = mySrvConfig(s);
1129
1130         if ((sc->enabled == SSL_ENABLED_TRUE) && (s->port == DEFAULT_HTTP_PORT)) {
1131             ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1132                          base_server,
1133                          "Init: (%s) You configured HTTPS(%d) "
1134                          "on the standard HTTP(%d) port!",
1135                          ssl_util_vhostid(p, s),
1136                          DEFAULT_HTTPS_PORT, DEFAULT_HTTP_PORT);
1137         }
1138
1139         if ((sc->enabled == SSL_ENABLED_FALSE) && (s->port == DEFAULT_HTTPS_PORT)) {
1140             ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1141                          base_server,
1142                          "Init: (%s) You configured HTTP(%d) "
1143                          "on the standard HTTPS(%d) port!",
1144                          ssl_util_vhostid(p, s),
1145                          DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT);
1146         }
1147     }
1148
1149 #ifdef OPENSSL_NO_TLSEXT
1150     /*
1151      * Give out warnings when more than one SSL-aware virtual server uses the
1152      * same IP:port. This doesn't work because mod_ssl then will always use
1153      * just the certificate/keys of one virtual host (which one cannot be said
1154      * easily - but that doesn't matter here).
1155      */
1156     table = apr_hash_make(p);
1157
1158     for (s = base_server; s; s = s->next) {
1159         char *addr;
1160
1161         sc = mySrvConfig(s);
1162
1163         if (!((sc->enabled == SSL_ENABLED_TRUE) && s->addrs)) {
1164             continue;
1165         }
1166
1167         apr_sockaddr_ip_get(&addr, s->addrs->host_addr);
1168         key = apr_psprintf(p, "%s:%u", addr, s->addrs->host_port);
1169         klen = strlen(key);
1170
1171         if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
1172             ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1173                          base_server,
1174                          "Init: SSL server IP/port conflict: "
1175                          "%s (%s:%d) vs. %s (%s:%d)",
1176                          ssl_util_vhostid(p, s),
1177                          (s->defn_name ? s->defn_name : "unknown"),
1178                          s->defn_line_number,
1179                          ssl_util_vhostid(p, ps),
1180                          (ps->defn_name ? ps->defn_name : "unknown"),
1181                          ps->defn_line_number);
1182             conflict = TRUE;
1183             continue;
1184         }
1185
1186         apr_hash_set(table, key, klen, s);
1187     }
1188
1189     if (conflict) {
1190         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
1191                      "Init: You should not use name-based "
1192                      "virtual hosts in conjunction with SSL!!");
1193     }
1194 #endif
1195 }
1196
1197 #ifdef SSLC_VERSION_NUMBER
1198 static int ssl_init_FindCAList_X509NameCmp(char **a, char **b)
1199 {
1200     return(X509_NAME_cmp((void*)*a, (void*)*b));
1201 }
1202 #else
1203 static int ssl_init_FindCAList_X509NameCmp(X509_NAME **a, X509_NAME **b)
1204 {
1205     return(X509_NAME_cmp(*a, *b));
1206 }
1207 #endif
1208
1209 static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
1210                                 server_rec *s, const char *file)
1211 {
1212     int n;
1213     STACK_OF(X509_NAME) *sk;
1214
1215     sk = (STACK_OF(X509_NAME) *)
1216              SSL_load_client_CA_file(MODSSL_PCHAR_CAST file);
1217
1218     if (!sk) {
1219         return;
1220     }
1221
1222     for (n = 0; n < sk_X509_NAME_num(sk); n++) {
1223         char name_buf[256];
1224         X509_NAME *name = sk_X509_NAME_value(sk, n);
1225
1226         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
1227                      "CA certificate: %s",
1228                      X509_NAME_oneline(name, name_buf, sizeof(name_buf)));
1229
1230         /*
1231          * note that SSL_load_client_CA_file() checks for duplicates,
1232          * but since we call it multiple times when reading a directory
1233          * we must also check for duplicates ourselves.
1234          */
1235
1236         if (sk_X509_NAME_find(ca_list, name) < 0) {
1237             /* this will be freed when ca_list is */
1238             sk_X509_NAME_push(ca_list, name);
1239         }
1240         else {
1241             /* need to free this ourselves, else it will leak */
1242             X509_NAME_free(name);
1243         }
1244     }
1245
1246     sk_X509_NAME_free(sk);
1247 }
1248
1249 STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
1250                                          apr_pool_t *ptemp,
1251                                          const char *ca_file,
1252                                          const char *ca_path)
1253 {
1254     STACK_OF(X509_NAME) *ca_list;
1255
1256     /*
1257      * Start with a empty stack/list where new
1258      * entries get added in sorted order.
1259      */
1260     ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp);
1261
1262     /*
1263      * Process CA certificate bundle file
1264      */
1265     if (ca_file) {
1266         ssl_init_PushCAList(ca_list, s, ca_file);
1267     }
1268
1269     /*
1270      * Process CA certificate path files
1271      */
1272     if (ca_path) {
1273         apr_dir_t *dir;
1274         apr_finfo_t direntry;
1275         apr_int32_t finfo_flags = APR_FINFO_TYPE|APR_FINFO_NAME;
1276         apr_status_t rv;
1277
1278         if ((rv = apr_dir_open(&dir, ca_path, ptemp)) != APR_SUCCESS) {
1279             ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
1280                     "Failed to open Certificate Path `%s'",
1281                     ca_path);
1282             ssl_die();
1283         }
1284
1285         while ((apr_dir_read(&direntry, finfo_flags, dir)) == APR_SUCCESS) {
1286             const char *file;
1287             if (direntry.filetype == APR_DIR) {
1288                 continue; /* don't try to load directories */
1289             }
1290             file = apr_pstrcat(ptemp, ca_path, "/", direntry.name, NULL);
1291             ssl_init_PushCAList(ca_list, s, file);
1292         }
1293
1294         apr_dir_close(dir);
1295     }
1296
1297     /*
1298      * Cleanup
1299      */
1300     sk_X509_NAME_set_cmp_func(ca_list, NULL);
1301
1302     return ca_list;
1303 }
1304
1305 void ssl_init_Child(apr_pool_t *p, server_rec *s)
1306 {
1307     SSLModConfigRec *mc = myModConfig(s);
1308     mc->pid = getpid(); /* only call getpid() once per-process */
1309
1310     /* XXX: there should be an ap_srand() function */
1311     srand((unsigned int)time(NULL));
1312
1313     /* open the mutex lockfile */
1314     ssl_mutex_reinit(s, p);
1315 }
1316
1317 #define MODSSL_CFG_ITEM_FREE(func, item) \
1318     if (item) { \
1319         func(item); \
1320         item = NULL; \
1321     }
1322
1323 static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
1324 {
1325     MODSSL_CFG_ITEM_FREE(X509_STORE_free, mctx->crl);
1326
1327     MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
1328 }
1329
1330 static void ssl_init_ctx_cleanup_proxy(modssl_ctx_t *mctx)
1331 {
1332     ssl_init_ctx_cleanup(mctx);
1333
1334     if (mctx->pkp->certs) {
1335         sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free);
1336         mctx->pkp->certs = NULL;
1337     }
1338 }
1339
1340 static void ssl_init_ctx_cleanup_server(modssl_ctx_t *mctx)
1341 {
1342     int i;
1343
1344     ssl_init_ctx_cleanup(mctx);
1345
1346     for (i=0; i < SSL_AIDX_MAX; i++) {
1347         MODSSL_CFG_ITEM_FREE(X509_free,
1348                              mctx->pks->certs[i]);
1349
1350         MODSSL_CFG_ITEM_FREE(EVP_PKEY_free,
1351                              mctx->pks->keys[i]);
1352     }
1353 }
1354
1355 apr_status_t ssl_init_ModuleKill(void *data)
1356 {
1357     SSLSrvConfigRec *sc;
1358     server_rec *base_server = (server_rec *)data;
1359     server_rec *s;
1360
1361     /*
1362      * Drop the session cache and mutex
1363      */
1364     ssl_scache_kill(base_server);
1365
1366     /*
1367      * Destroy the temporary keys and params
1368      */
1369     ssl_tmp_keys_free(base_server);
1370
1371     /*
1372      * Free the non-pool allocated structures
1373      * in the per-server configurations
1374      */
1375     for (s = base_server; s; s = s->next) {
1376         sc = mySrvConfig(s);
1377
1378         ssl_init_ctx_cleanup_proxy(sc->proxy);
1379
1380         ssl_init_ctx_cleanup_server(sc->server);
1381     }
1382
1383     return APR_SUCCESS;
1384 }
1385