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