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