]> granicus.if.org Git - apache/blob - modules/ssl/ssl_engine_init.c
enable support for ECC keys and ECDH ciphers. Tested against
[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, *ecc_id;
940     const char *vhost_id = mctx->sc->vhost_id;
941     int i;
942     int have_rsa, have_dsa, have_ecc;
943
944     rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
945     dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);
946 #ifndef OPENSSL_NO_EC
947     ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC);
948 #endif
949
950     have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
951     have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);
952 #ifndef OPENSSL_NO_EC
953     have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC);
954 #endif
955
956     if (!(have_rsa || have_dsa
957 #ifndef OPENSSL_NO_EC
958         || have_ecc
959 #endif
960 )) {
961         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
962 #ifndef OPENSSL_NO_EC
963                 "Oops, no RSA, DSA or ECC server certificate found "
964 #else
965                 "Oops, no RSA or DSA server certificate found "
966 #endif
967                 "for '%s:%d'?!", s->server_hostname, s->port);
968         ssl_die();
969     }
970
971     for (i = 0; i < SSL_AIDX_MAX; i++) {
972         ssl_check_public_cert(s, ptemp, mctx->pks->certs[i], i);
973     }
974
975     have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA);
976     have_dsa = ssl_server_import_key(s, mctx, dsa_id, SSL_AIDX_DSA);
977 #if SSL_LIBRARY_VERSION >= 0x00908000
978     have_ecc = ssl_server_import_key(s, mctx, ecc_id, SSL_AIDX_ECC);
979 #endif
980
981     if (!(have_rsa || have_dsa
982 #if SSL_LIBRARY_VERSION >= 0x00908000
983         || have_ecc
984 #endif
985           )) {
986         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
987 #if SSL_LIBRARY_VERSION >= 0x00908000
988                 "Oops, no RSA, DSA or ECC server private key found?!");
989 #else
990                 "Oops, no RSA or DSA server private key found?!");
991 #endif
992         ssl_die();
993     }
994 }
995
996 static void ssl_init_proxy_certs(server_rec *s,
997                                  apr_pool_t *p,
998                                  apr_pool_t *ptemp,
999                                  modssl_ctx_t *mctx)
1000 {
1001     int n, ncerts = 0;
1002     STACK_OF(X509_INFO) *sk;
1003     modssl_pk_proxy_t *pkp = mctx->pkp;
1004
1005     SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
1006                                ssl_callback_proxy_cert);
1007
1008     if (!(pkp->cert_file || pkp->cert_path)) {
1009         return;
1010     }
1011
1012     sk = sk_X509_INFO_new_null();
1013
1014     if (pkp->cert_file) {
1015         SSL_X509_INFO_load_file(ptemp, sk, pkp->cert_file);
1016     }
1017
1018     if (pkp->cert_path) {
1019         SSL_X509_INFO_load_path(ptemp, sk, pkp->cert_path);
1020     }
1021
1022     if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
1023         sk_X509_INFO_free(sk);
1024         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
1025                      "no client certs found for SSL proxy");
1026         return;
1027     }
1028
1029     /* Check that all client certs have got certificates and private
1030      * keys. */
1031     for (n = 0; n < ncerts; n++) {
1032         X509_INFO *inf = sk_X509_INFO_value(sk, n);
1033
1034         if (!inf->x509 || !inf->x_pkey) {
1035             sk_X509_INFO_free(sk);
1036             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
1037                          "incomplete client cert configured for SSL proxy "
1038                          "(missing or encrypted private key?)");
1039             ssl_die();
1040             return;
1041         }
1042     }
1043
1044     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
1045                  "loaded %d client certs for SSL proxy",
1046                  ncerts);
1047     pkp->certs = sk;
1048 }
1049
1050 static void ssl_init_proxy_ctx(server_rec *s,
1051                                apr_pool_t *p,
1052                                apr_pool_t *ptemp,
1053                                SSLSrvConfigRec *sc)
1054 {
1055     ssl_init_ctx(s, p, ptemp, sc->proxy);
1056
1057     ssl_init_proxy_certs(s, p, ptemp, sc->proxy);
1058 }
1059
1060 static void ssl_init_server_ctx(server_rec *s,
1061                                 apr_pool_t *p,
1062                                 apr_pool_t *ptemp,
1063                                 SSLSrvConfigRec *sc)
1064 {
1065     ssl_init_server_check(s, p, ptemp, sc->server);
1066
1067     ssl_init_ctx(s, p, ptemp, sc->server);
1068
1069     ssl_init_server_certs(s, p, ptemp, sc->server);
1070 }
1071
1072 /*
1073  * Configure a particular server
1074  */
1075 void ssl_init_ConfigureServer(server_rec *s,
1076                               apr_pool_t *p,
1077                               apr_pool_t *ptemp,
1078                               SSLSrvConfigRec *sc)
1079 {
1080     /* Initialize the server if SSL is enabled or optional.
1081      */
1082     if ((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) {
1083         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
1084                      "Configuring server for SSL protocol");
1085         ssl_init_server_ctx(s, p, ptemp, sc);
1086     }
1087
1088     if (sc->proxy_enabled) {
1089         ssl_init_proxy_ctx(s, p, ptemp, sc);
1090     }
1091 }
1092
1093 void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
1094 {
1095     server_rec *s, *ps;
1096     SSLSrvConfigRec *sc;
1097     apr_hash_t *table;
1098     const char *key;
1099     apr_ssize_t klen;
1100
1101     BOOL conflict = FALSE;
1102
1103     /*
1104      * Give out warnings when a server has HTTPS configured
1105      * for the HTTP port or vice versa
1106      */
1107     for (s = base_server; s; s = s->next) {
1108         sc = mySrvConfig(s);
1109
1110         if ((sc->enabled == SSL_ENABLED_TRUE) && (s->port == DEFAULT_HTTP_PORT)) {
1111             ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1112                          base_server,
1113                          "Init: (%s) You configured HTTPS(%d) "
1114                          "on the standard HTTP(%d) port!",
1115                          ssl_util_vhostid(p, s),
1116                          DEFAULT_HTTPS_PORT, DEFAULT_HTTP_PORT);
1117         }
1118
1119         if ((sc->enabled == SSL_ENABLED_FALSE) && (s->port == DEFAULT_HTTPS_PORT)) {
1120             ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1121                          base_server,
1122                          "Init: (%s) You configured HTTP(%d) "
1123                          "on the standard HTTPS(%d) port!",
1124                          ssl_util_vhostid(p, s),
1125                          DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT);
1126         }
1127     }
1128
1129     /*
1130      * Give out warnings when more than one SSL-aware virtual server uses the
1131      * same IP:port. This doesn't work because mod_ssl then will always use
1132      * just the certificate/keys of one virtual host (which one cannot be said
1133      * easily - but that doesn't matter here).
1134      */
1135     table = apr_hash_make(p);
1136
1137     for (s = base_server; s; s = s->next) {
1138         char *addr;
1139
1140         sc = mySrvConfig(s);
1141
1142         if (!((sc->enabled == SSL_ENABLED_TRUE) && s->addrs)) {
1143             continue;
1144         }
1145
1146         apr_sockaddr_ip_get(&addr, s->addrs->host_addr);
1147         key = apr_psprintf(p, "%s:%u", addr, s->addrs->host_port);
1148         klen = strlen(key);
1149
1150         if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
1151             ap_log_error(APLOG_MARK, 
1152 #ifdef OPENSSL_NO_TLSEXT
1153                          APLOG_WARNING, 
1154 #else
1155                          APLOG_DEBUG, 
1156 #endif
1157                          0,
1158                          base_server,
1159 #ifdef OPENSSL_NO_TLSEXT
1160                          "Init: SSL server IP/port conflict: "
1161 #else
1162                          "Init: SSL server IP/port overlap: "
1163 #endif
1164                          "%s (%s:%d) vs. %s (%s:%d)",
1165                          ssl_util_vhostid(p, s),
1166                          (s->defn_name ? s->defn_name : "unknown"),
1167                          s->defn_line_number,
1168                          ssl_util_vhostid(p, ps),
1169                          (ps->defn_name ? ps->defn_name : "unknown"),
1170                          ps->defn_line_number);
1171             conflict = TRUE;
1172             continue;
1173         }
1174
1175         apr_hash_set(table, key, klen, s);
1176     }
1177
1178     if (conflict) {
1179         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
1180 #ifdef OPENSSL_NO_TLSEXT
1181                      "Init: You should not use name-based "
1182                      "virtual hosts in conjunction with SSL!!");
1183 #else
1184                      "Init: Name-based SSL virtual hosts only "
1185                      "work for clients with TLS server name indication "
1186                      "support (RFC 4366)");
1187 #endif
1188     }
1189 }
1190
1191 #ifdef SSLC_VERSION_NUMBER
1192 static int ssl_init_FindCAList_X509NameCmp(char **a, char **b)
1193 {
1194     return(X509_NAME_cmp((void*)*a, (void*)*b));
1195 }
1196 #else
1197 static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a, 
1198                                            const X509_NAME * const *b)
1199 {
1200     return(X509_NAME_cmp(*a, *b));
1201 }
1202 #endif
1203
1204 static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
1205                                 server_rec *s, const char *file)
1206 {
1207     int n;
1208     STACK_OF(X509_NAME) *sk;
1209
1210     sk = (STACK_OF(X509_NAME) *)
1211              SSL_load_client_CA_file(MODSSL_PCHAR_CAST file);
1212
1213     if (!sk) {
1214         return;
1215     }
1216
1217     for (n = 0; n < sk_X509_NAME_num(sk); n++) {
1218         char name_buf[256];
1219         X509_NAME *name = sk_X509_NAME_value(sk, n);
1220
1221         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
1222                      "CA certificate: %s",
1223                      X509_NAME_oneline(name, name_buf, sizeof(name_buf)));
1224
1225         /*
1226          * note that SSL_load_client_CA_file() checks for duplicates,
1227          * but since we call it multiple times when reading a directory
1228          * we must also check for duplicates ourselves.
1229          */
1230
1231         if (sk_X509_NAME_find(ca_list, name) < 0) {
1232             /* this will be freed when ca_list is */
1233             sk_X509_NAME_push(ca_list, name);
1234         }
1235         else {
1236             /* need to free this ourselves, else it will leak */
1237             X509_NAME_free(name);
1238         }
1239     }
1240
1241     sk_X509_NAME_free(sk);
1242 }
1243
1244 STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
1245                                          apr_pool_t *ptemp,
1246                                          const char *ca_file,
1247                                          const char *ca_path)
1248 {
1249     STACK_OF(X509_NAME) *ca_list;
1250
1251     /*
1252      * Start with a empty stack/list where new
1253      * entries get added in sorted order.
1254      */
1255     ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp);
1256
1257     /*
1258      * Process CA certificate bundle file
1259      */
1260     if (ca_file) {
1261         ssl_init_PushCAList(ca_list, s, ca_file);
1262     }
1263
1264     /*
1265      * Process CA certificate path files
1266      */
1267     if (ca_path) {
1268         apr_dir_t *dir;
1269         apr_finfo_t direntry;
1270         apr_int32_t finfo_flags = APR_FINFO_TYPE|APR_FINFO_NAME;
1271         apr_status_t rv;
1272
1273         if ((rv = apr_dir_open(&dir, ca_path, ptemp)) != APR_SUCCESS) {
1274             ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
1275                     "Failed to open Certificate Path `%s'",
1276                     ca_path);
1277             ssl_die();
1278         }
1279
1280         while ((apr_dir_read(&direntry, finfo_flags, dir)) == APR_SUCCESS) {
1281             const char *file;
1282             if (direntry.filetype == APR_DIR) {
1283                 continue; /* don't try to load directories */
1284             }
1285             file = apr_pstrcat(ptemp, ca_path, "/", direntry.name, NULL);
1286             ssl_init_PushCAList(ca_list, s, file);
1287         }
1288
1289         apr_dir_close(dir);
1290     }
1291
1292     /*
1293      * Cleanup
1294      */
1295     (void) sk_X509_NAME_set_cmp_func(ca_list, NULL);
1296
1297     return ca_list;
1298 }
1299
1300 void ssl_init_Child(apr_pool_t *p, server_rec *s)
1301 {
1302     SSLModConfigRec *mc = myModConfig(s);
1303     mc->pid = getpid(); /* only call getpid() once per-process */
1304
1305     /* XXX: there should be an ap_srand() function */
1306     srand((unsigned int)time(NULL));
1307
1308     /* open the mutex lockfile */
1309     ssl_mutex_reinit(s, p);
1310 #ifdef HAVE_OCSP_STAPLING
1311     ssl_stapling_mutex_reinit(s, p);
1312 #endif
1313 }
1314
1315 #define MODSSL_CFG_ITEM_FREE(func, item) \
1316     if (item) { \
1317         func(item); \
1318         item = NULL; \
1319     }
1320
1321 static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
1322 {
1323     MODSSL_CFG_ITEM_FREE(X509_STORE_free, mctx->crl);
1324
1325     MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
1326 }
1327
1328 static void ssl_init_ctx_cleanup_proxy(modssl_ctx_t *mctx)
1329 {
1330     ssl_init_ctx_cleanup(mctx);
1331
1332     if (mctx->pkp->certs) {
1333         sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free);
1334         mctx->pkp->certs = NULL;
1335     }
1336 }
1337
1338 static void ssl_init_ctx_cleanup_server(modssl_ctx_t *mctx)
1339 {
1340     int i;
1341
1342     ssl_init_ctx_cleanup(mctx);
1343
1344     for (i=0; i < SSL_AIDX_MAX; i++) {
1345         MODSSL_CFG_ITEM_FREE(X509_free,
1346                              mctx->pks->certs[i]);
1347
1348         MODSSL_CFG_ITEM_FREE(EVP_PKEY_free,
1349                              mctx->pks->keys[i]);
1350     }
1351 }
1352
1353 apr_status_t ssl_init_ModuleKill(void *data)
1354 {
1355     SSLSrvConfigRec *sc;
1356     server_rec *base_server = (server_rec *)data;
1357     server_rec *s;
1358
1359     /*
1360      * Drop the session cache and mutex
1361      */
1362     ssl_scache_kill(base_server);
1363
1364     /*
1365      * Destroy the temporary keys and params
1366      */
1367     ssl_tmp_keys_free(base_server);
1368
1369     /*
1370      * Free the non-pool allocated structures
1371      * in the per-server configurations
1372      */
1373     for (s = base_server; s; s = s->next) {
1374         sc = mySrvConfig(s);
1375
1376         ssl_init_ctx_cleanup_proxy(sc->proxy);
1377
1378         ssl_init_ctx_cleanup_server(sc->server);
1379     }
1380
1381     return APR_SUCCESS;
1382 }
1383