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