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