~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to modules/ssl/ssl_engine_init.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

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