/[Apache-SVN]/httpd/httpd/trunk/modules/ssl/ssl_engine_init.c
ViewVC logotype

Contents of /httpd/httpd/trunk/modules/ssl/ssl_engine_init.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1598107 - (show annotations) (download)
Wed May 28 19:14:28 2014 UTC (5 years, 4 months ago) by jorton
File MIME type: text/plain
File size: 59376 byte(s)
Create DH parameters from OpenSSL at module init, avoiding (very
minor) race and leaks:

* modules/ssl/ssl_engine_init.c (make_dh_params): Moved/rejigged
  variant of make_get_dh() macro.
  (init_dh_params, free_dh_params): New functions.
  (modssl_get_dh_params): Split out from ssl_callback_TmpDH.
  (ssl_init_Module, ssl_init_ModuleKill): Use new init_/free_.

* modules/ssl/ssl_engine_kernel.c: Moved out DH parameter handling.
  (ssl_callback_TmpDH): Use modssl_get_dh_params.

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 #include "mod_ssl.h"
31 #include "mod_ssl_openssl.h"
32 #include "mpm_common.h"
33
34 APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_server,
35 (server_rec *s,apr_pool_t *p,int is_proxy,SSL_CTX *ctx),
36 (s,p,is_proxy,ctx), OK, DECLINED)
37
38 /* _________________________________________________________________
39 **
40 ** Module Initialization
41 ** _________________________________________________________________
42 */
43
44 #ifdef HAVE_ECC
45 #define KEYTYPES "RSA, DSA or ECC"
46 #else
47 #define KEYTYPES "RSA or DSA"
48 #endif
49
50 /*
51 * Grab well-defined DH parameters from OpenSSL, see the get_rfc*
52 * functions in <openssl/bn.h> for all available primes.
53 */
54 static DH *make_dh_params(BIGNUM *(*prime)(BIGNUM *), const char *gen)
55 {
56 DH *dh = NULL;
57 DH *dh_tmp;
58
59 if (dh) {
60 return dh;
61 }
62 if (!(dh_tmp = DH_new())) {
63 return NULL;
64 }
65 dh_tmp->p = prime(NULL);
66 BN_dec2bn(&dh_tmp->g, gen);
67 if (!dh_tmp->p || !dh_tmp->g) {
68 DH_free(dh_tmp);
69 return NULL;
70 }
71 dh = dh_tmp;
72 return dh;
73 }
74
75 static DH *dhparam1024, *dhparam2048, *dhparam3072, *dhparam4096;
76
77 static void init_dh_params(void)
78 {
79 /*
80 * Prepare DH parameters from 1024 to 4096 bits, in 1024-bit increments
81 */
82 dhparam1024 = make_dh_params(get_rfc2409_prime_1024, "2");
83 dhparam2048 = make_dh_params(get_rfc3526_prime_2048, "2");
84 dhparam3072 = make_dh_params(get_rfc3526_prime_3072, "2");
85 dhparam4096 = make_dh_params(get_rfc3526_prime_4096, "2");
86 }
87
88 static void free_dh_params(void)
89 {
90 DH_free(dhparam1024);
91 DH_free(dhparam2048);
92 DH_free(dhparam3072);
93 DH_free(dhparam4096);
94 dhparam1024 = dhparam2048 = dhparam3072 = dhparam4096 = NULL;
95 }
96
97 /* Hand out the same DH structure though once generated as we leak
98 * memory otherwise and freeing the structure up after use would be
99 * hard to track and in fact is not needed at all as it is safe to
100 * use the same parameters over and over again security wise (in
101 * contrast to the keys itself) and code safe as the returned structure
102 * is duplicated by OpenSSL anyway. Hence no modification happens
103 * to our copy. */
104 DH *modssl_get_dh_params(unsigned keylen)
105 {
106 if (keylen >= 4096)
107 return dhparam4096;
108 else if (keylen >= 3072)
109 return dhparam3072;
110 else if (keylen >= 2048)
111 return dhparam2048;
112 else
113 return dhparam1024;
114 }
115
116 static void ssl_add_version_components(apr_pool_t *p,
117 server_rec *s)
118 {
119 char *modver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_INTERFACE");
120 char *libver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_LIBRARY");
121 char *incver = ssl_var_lookup(p, s, NULL, NULL,
122 "SSL_VERSION_LIBRARY_INTERFACE");
123
124 ap_add_version_component(p, libver);
125
126 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01876)
127 "%s compiled against Server: %s, Library: %s",
128 modver, AP_SERVER_BASEVERSION, incver);
129 }
130
131 /*
132 * Per-module initialization
133 */
134 apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
135 apr_pool_t *ptemp,
136 server_rec *base_server)
137 {
138 SSLModConfigRec *mc = myModConfig(base_server);
139 SSLSrvConfigRec *sc;
140 server_rec *s;
141 apr_status_t rv;
142 apr_array_header_t *pphrases;
143
144 if (SSLeay() < SSL_LIBRARY_VERSION) {
145 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01882)
146 "Init: this version of mod_ssl was compiled against "
147 "a newer library (%s, version currently loaded is %s)"
148 " - may result in undefined or erroneous behavior",
149 SSL_LIBRARY_TEXT, SSLeay_version(SSLEAY_VERSION));
150 }
151
152 /* We initialize mc->pid per-process in the child init,
153 * but it should be initialized for startup before we
154 * call ssl_rand_seed() below.
155 */
156 mc->pid = getpid();
157
158 /*
159 * Let us cleanup on restarts and exits
160 */
161 apr_pool_cleanup_register(p, base_server,
162 ssl_init_ModuleKill,
163 apr_pool_cleanup_null);
164
165 /*
166 * Any init round fixes the global config
167 */
168 ssl_config_global_create(base_server); /* just to avoid problems */
169 ssl_config_global_fix(mc);
170
171 /*
172 * try to fix the configuration and open the dedicated SSL
173 * logfile as early as possible
174 */
175 for (s = base_server; s; s = s->next) {
176 sc = mySrvConfig(s);
177
178 if (sc->server) {
179 sc->server->sc = sc;
180 }
181
182 if (sc->proxy) {
183 sc->proxy->sc = sc;
184 }
185
186 /*
187 * Create the server host:port string because we need it a lot
188 */
189 sc->vhost_id = ssl_util_vhostid(p, s);
190 sc->vhost_id_len = strlen(sc->vhost_id);
191
192 /* Default to enabled if SSLEngine is not set explicitly, and
193 * the protocol is https. */
194 if (ap_get_server_protocol(s)
195 && strcmp("https", ap_get_server_protocol(s)) == 0
196 && sc->enabled == SSL_ENABLED_UNSET) {
197 sc->enabled = SSL_ENABLED_TRUE;
198 }
199
200 /* Fix up stuff that may not have been set. If sc->enabled is
201 * UNSET, then SSL is disabled on this vhost. */
202 if (sc->enabled == SSL_ENABLED_UNSET) {
203 sc->enabled = SSL_ENABLED_FALSE;
204 }
205 if (sc->proxy_enabled == UNSET) {
206 sc->proxy_enabled = FALSE;
207 }
208
209 if (sc->session_cache_timeout == UNSET) {
210 sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT;
211 }
212
213 if (sc->server && sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) {
214 sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
215 }
216
217 #ifdef HAVE_FIPS
218 if (sc->fips == UNSET) {
219 sc->fips = FALSE;
220 }
221 #endif
222 }
223
224 #if APR_HAS_THREADS
225 ssl_util_thread_setup(p);
226 #endif
227
228 /*
229 * SSL external crypto device ("engine") support
230 */
231 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
232 if ((rv = ssl_init_Engine(base_server, p)) != APR_SUCCESS) {
233 return rv;
234 }
235 #endif
236
237 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01883)
238 "Init: Initialized %s library", SSL_LIBRARY_NAME);
239
240 /*
241 * Seed the Pseudo Random Number Generator (PRNG)
242 * only need ptemp here; nothing inside allocated from the pool
243 * needs to live once we return from ssl_rand_seed().
244 */
245 ssl_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init: ");
246
247 #ifdef HAVE_FIPS
248 if(sc->fips) {
249 if (!FIPS_mode()) {
250 if (FIPS_mode_set(1)) {
251 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(01884)
252 "Operating in SSL FIPS mode");
253 }
254 else {
255 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01885) "FIPS mode failed");
256 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
257 return ssl_die(s);
258 }
259 }
260 }
261 else {
262 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01886)
263 "SSL FIPS mode disabled");
264 }
265 #endif
266
267 /*
268 * initialize the mutex handling
269 */
270 if (!ssl_mutex_init(base_server, p)) {
271 return HTTP_INTERNAL_SERVER_ERROR;
272 }
273 #ifdef HAVE_OCSP_STAPLING
274 ssl_stapling_ex_init();
275 #endif
276
277 /*
278 * initialize session caching
279 */
280 if ((rv = ssl_scache_init(base_server, p)) != APR_SUCCESS) {
281 return rv;
282 }
283
284 pphrases = apr_array_make(ptemp, 2, sizeof(char *));
285
286 /*
287 * initialize servers
288 */
289 ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, APLOGNO(01887)
290 "Init: Initializing (virtual) servers for SSL");
291
292 for (s = base_server; s; s = s->next) {
293 sc = mySrvConfig(s);
294 /*
295 * Either now skip this server when SSL is disabled for
296 * it or give out some information about what we're
297 * configuring.
298 */
299
300 /*
301 * Read the server certificate and key
302 */
303 if ((rv = ssl_init_ConfigureServer(s, p, ptemp, sc, pphrases))
304 != APR_SUCCESS) {
305 return rv;
306 }
307 }
308
309 if (pphrases->nelts > 0) {
310 memset(pphrases->elts, 0, pphrases->elt_size * pphrases->nelts);
311 pphrases->nelts = 0;
312 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02560)
313 "Init: Wiped out the queried pass phrases from memory");
314 }
315
316 /*
317 * Configuration consistency checks
318 */
319 if ((rv = ssl_init_CheckServers(base_server, ptemp)) != APR_SUCCESS) {
320 return rv;
321 }
322
323 for (s = base_server; s; s = s->next) {
324 sc = mySrvConfig(s);
325
326 if (sc->enabled == SSL_ENABLED_TRUE || sc->enabled == SSL_ENABLED_OPTIONAL) {
327 if ((rv = ssl_run_init_server(s, p, 0, sc->server->ssl_ctx)) != APR_SUCCESS) {
328 return rv;
329 }
330 }
331 else if (sc->proxy_enabled == SSL_ENABLED_TRUE) {
332 if ((rv = ssl_run_init_server(s, p, 1, sc->proxy->ssl_ctx)) != APR_SUCCESS) {
333 return rv;
334 }
335 }
336 }
337
338 /*
339 * Announce mod_ssl and SSL library in HTTP Server field
340 * as ``mod_ssl/X.X.X OpenSSL/X.X.X''
341 */
342 ssl_add_version_components(p, base_server);
343
344 SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */
345
346 init_dh_params();
347
348 return OK;
349 }
350
351 /*
352 * Support for external a Crypto Device ("engine"), usually
353 * a hardware accellerator card for crypto operations.
354 */
355 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
356 apr_status_t ssl_init_Engine(server_rec *s, apr_pool_t *p)
357 {
358 SSLModConfigRec *mc = myModConfig(s);
359 ENGINE *e;
360
361 if (mc->szCryptoDevice) {
362 if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
363 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01888)
364 "Init: Failed to load Crypto Device API `%s'",
365 mc->szCryptoDevice);
366 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
367 return ssl_die(s);
368 }
369
370 if (strEQ(mc->szCryptoDevice, "chil")) {
371 ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
372 }
373
374 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
375 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01889)
376 "Init: Failed to enable Crypto Device API `%s'",
377 mc->szCryptoDevice);
378 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
379 return ssl_die(s);
380 }
381 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01890)
382 "Init: loaded Crypto Device API `%s'",
383 mc->szCryptoDevice);
384
385 ENGINE_free(e);
386 }
387
388 return APR_SUCCESS;
389 }
390 #endif
391
392 #ifdef HAVE_TLSEXT
393 static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
394 apr_pool_t *p,
395 apr_pool_t *ptemp,
396 modssl_ctx_t *mctx)
397 {
398 apr_status_t rv;
399
400 /*
401 * Configure TLS extensions support
402 */
403 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01893)
404 "Configuring TLS extension handling");
405
406 /*
407 * Server name indication (SNI)
408 */
409 if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
410 ssl_callback_ServerNameIndication) ||
411 !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) {
412 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01894)
413 "Unable to initialize TLS servername extension "
414 "callback (incompatible OpenSSL version?)");
415 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
416 return ssl_die(s);
417 }
418
419 #ifdef HAVE_OCSP_STAPLING
420 /*
421 * OCSP Stapling support, status_request extension
422 */
423 if ((mctx->pkp == FALSE) && (mctx->stapling_enabled == TRUE)) {
424 if ((rv = modssl_init_stapling(s, p, ptemp, mctx)) != APR_SUCCESS) {
425 return rv;
426 }
427 }
428 #endif
429
430 #ifdef HAVE_SRP
431 /*
432 * TLS-SRP support
433 */
434 if (mctx->srp_vfile != NULL) {
435 int err;
436 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02308)
437 "Using SRP verifier file [%s]", mctx->srp_vfile);
438
439 if (!(mctx->srp_vbase = SRP_VBASE_new(mctx->srp_unknown_user_seed))) {
440 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02309)
441 "Unable to initialize SRP verifier structure "
442 "[%s seed]",
443 mctx->srp_unknown_user_seed ? "with" : "without");
444 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
445 return ssl_die(s);
446 }
447
448 err = SRP_VBASE_init(mctx->srp_vbase, mctx->srp_vfile);
449 if (err != SRP_NO_ERROR) {
450 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02310)
451 "Unable to load SRP verifier file [error %d]", err);
452 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
453 return ssl_die(s);
454 }
455
456 SSL_CTX_set_srp_username_callback(mctx->ssl_ctx,
457 ssl_callback_SRPServerParams);
458 SSL_CTX_set_srp_cb_arg(mctx->ssl_ctx, mctx);
459 }
460 #endif
461 return APR_SUCCESS;
462 }
463 #endif
464
465 static apr_status_t ssl_init_ctx_protocol(server_rec *s,
466 apr_pool_t *p,
467 apr_pool_t *ptemp,
468 modssl_ctx_t *mctx)
469 {
470 SSL_CTX *ctx = NULL;
471 MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL;
472 char *cp;
473 int protocol = mctx->protocol;
474 SSLSrvConfigRec *sc = mySrvConfig(s);
475
476 /*
477 * Create the new per-server SSL context
478 */
479 if (protocol == SSL_PROTOCOL_NONE) {
480 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
481 "No SSL protocols available [hint: SSLProtocol]");
482 return ssl_die(s);
483 }
484
485 cp = apr_pstrcat(p,
486 (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
487 (protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
488 #ifdef HAVE_TLSV1_X
489 (protocol & SSL_PROTOCOL_TLSV1_1 ? "TLSv1.1, " : ""),
490 (protocol & SSL_PROTOCOL_TLSV1_2 ? "TLSv1.2, " : ""),
491 #endif
492 NULL);
493 cp[strlen(cp)-2] = NUL;
494
495 ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
496 "Creating new SSL context (protocols: %s)", cp);
497
498 if (protocol == SSL_PROTOCOL_SSLV3) {
499 method = mctx->pkp ?
500 SSLv3_client_method() : /* proxy */
501 SSLv3_server_method(); /* server */
502 }
503 else if (protocol == SSL_PROTOCOL_TLSV1) {
504 method = mctx->pkp ?
505 TLSv1_client_method() : /* proxy */
506 TLSv1_server_method(); /* server */
507 }
508 #ifdef HAVE_TLSV1_X
509 else if (protocol == SSL_PROTOCOL_TLSV1_1) {
510 method = mctx->pkp ?
511 TLSv1_1_client_method() : /* proxy */
512 TLSv1_1_server_method(); /* server */
513 }
514 else if (protocol == SSL_PROTOCOL_TLSV1_2) {
515 method = mctx->pkp ?
516 TLSv1_2_client_method() : /* proxy */
517 TLSv1_2_server_method(); /* server */
518 }
519 #endif
520 else { /* For multiple protocols, we need a flexible method */
521 method = mctx->pkp ?
522 SSLv23_client_method() : /* proxy */
523 SSLv23_server_method(); /* server */
524 }
525 ctx = SSL_CTX_new(method);
526
527 mctx->ssl_ctx = ctx;
528
529 SSL_CTX_set_options(ctx, SSL_OP_ALL);
530
531 /* always disable SSLv2, as per RFC 6176 */
532 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
533
534 if (!(protocol & SSL_PROTOCOL_SSLV3)) {
535 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
536 }
537
538 if (!(protocol & SSL_PROTOCOL_TLSV1)) {
539 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
540 }
541
542 #ifdef HAVE_TLSV1_X
543 if (!(protocol & SSL_PROTOCOL_TLSV1_1)) {
544 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
545 }
546
547 if (!(protocol & SSL_PROTOCOL_TLSV1_2)) {
548 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
549 }
550 #endif
551
552 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
553 if (sc->cipher_server_pref == TRUE) {
554 SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
555 }
556 #endif
557
558
559 #ifndef OPENSSL_NO_COMP
560 if (sc->compression != TRUE) {
561 #ifdef SSL_OP_NO_COMPRESSION
562 /* OpenSSL >= 1.0 only */
563 SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
564 #else
565 sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
566 #endif
567 }
568 #endif
569
570 #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
571 if (sc->insecure_reneg == TRUE) {
572 SSL_CTX_set_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
573 }
574 #endif
575
576 SSL_CTX_set_app_data(ctx, s);
577
578 /*
579 * Configure additional context ingredients
580 */
581 SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
582 #ifdef HAVE_ECC
583 SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
584 #endif
585
586 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
587 /*
588 * Disallow a session from being resumed during a renegotiation,
589 * so that an acceptable cipher suite can be negotiated.
590 */
591 SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
592 #endif
593
594 #ifdef SSL_MODE_RELEASE_BUFFERS
595 /* If httpd is configured to reduce mem usage, ask openssl to do so, too */
596 if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED)
597 SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
598 #endif
599
600 return APR_SUCCESS;
601 }
602
603 static void ssl_init_ctx_session_cache(server_rec *s,
604 apr_pool_t *p,
605 apr_pool_t *ptemp,
606 modssl_ctx_t *mctx)
607 {
608 SSL_CTX *ctx = mctx->ssl_ctx;
609 SSLModConfigRec *mc = myModConfig(s);
610
611 SSL_CTX_set_session_cache_mode(ctx, mc->sesscache_mode);
612
613 if (mc->sesscache) {
614 SSL_CTX_sess_set_new_cb(ctx, ssl_callback_NewSessionCacheEntry);
615 SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry);
616 SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
617 }
618 }
619
620 static void ssl_init_ctx_callbacks(server_rec *s,
621 apr_pool_t *p,
622 apr_pool_t *ptemp,
623 modssl_ctx_t *mctx)
624 {
625 SSL_CTX *ctx = mctx->ssl_ctx;
626
627 SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
628
629 SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
630
631 #ifdef HAVE_TLS_NPN
632 SSL_CTX_set_next_protos_advertised_cb(
633 ctx, ssl_callback_AdvertiseNextProtos, NULL);
634 #endif
635 }
636
637 static apr_status_t ssl_init_ctx_verify(server_rec *s,
638 apr_pool_t *p,
639 apr_pool_t *ptemp,
640 modssl_ctx_t *mctx)
641 {
642 SSL_CTX *ctx = mctx->ssl_ctx;
643
644 int verify = SSL_VERIFY_NONE;
645 STACK_OF(X509_NAME) *ca_list;
646
647 if (mctx->auth.verify_mode == SSL_CVERIFY_UNSET) {
648 mctx->auth.verify_mode = SSL_CVERIFY_NONE;
649 }
650
651 if (mctx->auth.verify_depth == UNSET) {
652 mctx->auth.verify_depth = 1;
653 }
654
655 /*
656 * Configure callbacks for SSL context
657 */
658 if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
659 verify |= SSL_VERIFY_PEER_STRICT;
660 }
661
662 if ((mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
663 (mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
664 {
665 verify |= SSL_VERIFY_PEER;
666 }
667
668 SSL_CTX_set_verify(ctx, verify, ssl_callback_SSLVerify);
669
670 /*
671 * Configure Client Authentication details
672 */
673 if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) {
674 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
675 "Configuring client authentication");
676
677 if (!SSL_CTX_load_verify_locations(ctx,
678 mctx->auth.ca_cert_file,
679 mctx->auth.ca_cert_path))
680 {
681 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01895)
682 "Unable to configure verify locations "
683 "for client authentication");
684 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
685 return ssl_die(s);
686 }
687
688 if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) {
689 ca_list = ssl_init_FindCAList(s, ptemp,
690 mctx->pks->ca_name_file,
691 mctx->pks->ca_name_path);
692 } else
693 ca_list = ssl_init_FindCAList(s, ptemp,
694 mctx->auth.ca_cert_file,
695 mctx->auth.ca_cert_path);
696 if (sk_X509_NAME_num(ca_list) <= 0) {
697 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896)
698 "Unable to determine list of acceptable "
699 "CA certificates for client authentication");
700 return ssl_die(s);
701 }
702
703 SSL_CTX_set_client_CA_list(ctx, ca_list);
704 }
705
706 /*
707 * Give a warning when no CAs were configured but client authentication
708 * should take place. This cannot work.
709 */
710 if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
711 ca_list = SSL_CTX_get_client_CA_list(ctx);
712
713 if (sk_X509_NAME_num(ca_list) == 0) {
714 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01897)
715 "Init: Oops, you want to request client "
716 "authentication, but no CAs are known for "
717 "verification!? [Hint: SSLCACertificate*]");
718 }
719 }
720
721 return APR_SUCCESS;
722 }
723
724 static apr_status_t ssl_init_ctx_cipher_suite(server_rec *s,
725 apr_pool_t *p,
726 apr_pool_t *ptemp,
727 modssl_ctx_t *mctx)
728 {
729 SSL_CTX *ctx = mctx->ssl_ctx;
730 const char *suite;
731
732 /*
733 * Configure SSL Cipher Suite. Always disable NULL and export ciphers,
734 * see also ssl_engine_config.c:ssl_cmd_SSLCipherSuite().
735 * OpenSSL's SSL_DEFAULT_CIPHER_LIST already includes !aNULL:!eNULL,
736 * so only prepend !EXP in this case.
737 */
738 suite = mctx->auth.cipher_suite ? mctx->auth.cipher_suite :
739 apr_pstrcat(ptemp, "!EXP:", SSL_DEFAULT_CIPHER_LIST, NULL);
740
741 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
742 "Configuring permitted SSL ciphers [%s]",
743 suite);
744
745 if (!SSL_CTX_set_cipher_list(ctx, suite)) {
746 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01898)
747 "Unable to configure permitted SSL ciphers");
748 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
749 return ssl_die(s);
750 }
751
752 return APR_SUCCESS;
753 }
754
755 static apr_status_t ssl_init_ctx_crl(server_rec *s,
756 apr_pool_t *p,
757 apr_pool_t *ptemp,
758 modssl_ctx_t *mctx)
759 {
760 X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
761 unsigned long crlflags = 0;
762 char *cfgp = mctx->pkp ? "SSLProxy" : "SSL";
763
764 /*
765 * Configure Certificate Revocation List (CRL) Details
766 */
767
768 if (!(mctx->crl_file || mctx->crl_path)) {
769 if (mctx->crl_check_mode == SSL_CRLCHECK_LEAF ||
770 mctx->crl_check_mode == SSL_CRLCHECK_CHAIN) {
771 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01899)
772 "Host %s: CRL checking has been enabled, but "
773 "neither %sCARevocationFile nor %sCARevocationPath "
774 "is configured", mctx->sc->vhost_id, cfgp, cfgp);
775 return ssl_die(s);
776 }
777 return APR_SUCCESS;
778 }
779
780 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01900)
781 "Configuring certificate revocation facility");
782
783 if (!store || !X509_STORE_load_locations(store, mctx->crl_file,
784 mctx->crl_path)) {
785 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01901)
786 "Host %s: unable to configure X.509 CRL storage "
787 "for certificate revocation", mctx->sc->vhost_id);
788 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
789 return ssl_die(s);
790 }
791
792 switch (mctx->crl_check_mode) {
793 case SSL_CRLCHECK_LEAF:
794 crlflags = X509_V_FLAG_CRL_CHECK;
795 break;
796 case SSL_CRLCHECK_CHAIN:
797 crlflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
798 break;
799 default:
800 crlflags = 0;
801 }
802
803 if (crlflags) {
804 X509_STORE_set_flags(store, crlflags);
805 } else {
806 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01902)
807 "Host %s: X.509 CRL storage locations configured, "
808 "but CRL checking (%sCARevocationCheck) is not "
809 "enabled", mctx->sc->vhost_id, cfgp);
810 }
811
812 return APR_SUCCESS;
813 }
814
815 static apr_status_t ssl_init_ctx_cert_chain(server_rec *s,
816 apr_pool_t *p,
817 apr_pool_t *ptemp,
818 modssl_ctx_t *mctx)
819 {
820 BOOL skip_first = FALSE;
821 int i, n;
822 const char *chain = mctx->cert_chain;
823
824 /*
825 * Optionally configure extra server certificate chain certificates.
826 * This is usually done by OpenSSL automatically when one of the
827 * server cert issuers are found under SSLCACertificatePath or in
828 * SSLCACertificateFile. But because these are intended for client
829 * authentication it can conflict. For instance when you use a
830 * Global ID server certificate you've to send out the intermediate
831 * CA certificate, too. When you would just configure this with
832 * SSLCACertificateFile and also use client authentication mod_ssl
833 * would accept all clients also issued by this CA. Obviously this
834 * isn't what we want in this situation. So this feature here exists
835 * to allow one to explicity configure CA certificates which are
836 * used only for the server certificate chain.
837 */
838 if (!chain) {
839 return APR_SUCCESS;
840 }
841
842 for (i = 0; (i < mctx->pks->cert_files->nelts) &&
843 APR_ARRAY_IDX(mctx->pks->cert_files, i, const char *); i++) {
844 if (strEQ(APR_ARRAY_IDX(mctx->pks->cert_files, i, const char *), chain)) {
845 skip_first = TRUE;
846 break;
847 }
848 }
849
850 n = SSL_CTX_use_certificate_chain(mctx->ssl_ctx,
851 (char *)chain,
852 skip_first, NULL);
853 if (n < 0) {
854 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903)
855 "Failed to configure CA certificate chain!");
856 return ssl_die(s);
857 }
858
859 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01904)
860 "Configuring server certificate chain "
861 "(%d CA certificate%s)",
862 n, n == 1 ? "" : "s");
863
864 return APR_SUCCESS;
865 }
866
867 static apr_status_t ssl_init_ctx(server_rec *s,
868 apr_pool_t *p,
869 apr_pool_t *ptemp,
870 modssl_ctx_t *mctx)
871 {
872 apr_status_t rv;
873
874 if ((rv = ssl_init_ctx_protocol(s, p, ptemp, mctx)) != APR_SUCCESS) {
875 return rv;
876 }
877
878 ssl_init_ctx_session_cache(s, p, ptemp, mctx);
879
880 ssl_init_ctx_callbacks(s, p, ptemp, mctx);
881
882 if ((rv = ssl_init_ctx_verify(s, p, ptemp, mctx)) != APR_SUCCESS) {
883 return rv;
884 }
885
886 if ((rv = ssl_init_ctx_cipher_suite(s, p, ptemp, mctx)) != APR_SUCCESS) {
887 return rv;
888 }
889
890 if ((rv = ssl_init_ctx_crl(s, p, ptemp, mctx)) != APR_SUCCESS) {
891 return rv;
892 }
893
894 if (mctx->pks) {
895 /* XXX: proxy support? */
896 if ((rv = ssl_init_ctx_cert_chain(s, p, ptemp, mctx)) != APR_SUCCESS) {
897 return rv;
898 }
899 #ifdef HAVE_TLSEXT
900 if ((rv = ssl_init_ctx_tls_extensions(s, p, ptemp, mctx)) !=
901 APR_SUCCESS) {
902 return rv;
903 }
904 #endif
905 }
906
907 return APR_SUCCESS;
908 }
909
910 static void ssl_check_public_cert(server_rec *s,
911 apr_pool_t *ptemp,
912 X509 *cert,
913 const char *key_id)
914 {
915 int is_ca, pathlen;
916
917 if (!cert) {
918 return;
919 }
920
921 /*
922 * Some information about the certificate(s)
923 */
924
925 if (SSL_X509_getBC(cert, &is_ca, &pathlen)) {
926 if (is_ca) {
927 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01906)
928 "%s server certificate is a CA certificate "
929 "(BasicConstraints: CA == TRUE !?)", key_id);
930 }
931
932 if (pathlen > 0) {
933 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01907)
934 "%s server certificate is not a leaf certificate "
935 "(BasicConstraints: pathlen == %d > 0 !?)",
936 key_id, pathlen);
937 }
938 }
939
940 if (SSL_X509_match_name(ptemp, cert, (const char *)s->server_hostname,
941 TRUE, s) == FALSE) {
942 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01909)
943 "%s server certificate does NOT include an ID "
944 "which matches the server name", key_id);
945 }
946 }
947
948 /* prevent OpenSSL from showing its "Enter PEM pass phrase:" prompt */
949 static int ssl_no_passwd_prompt_cb(char *buf, int size, int rwflag,
950 void *userdata) {
951 return 0;
952 }
953
954 static apr_status_t ssl_init_server_certs(server_rec *s,
955 apr_pool_t *p,
956 apr_pool_t *ptemp,
957 modssl_ctx_t *mctx,
958 apr_array_header_t *pphrases)
959 {
960 SSLModConfigRec *mc = myModConfig(s);
961 const char *vhost_id = mctx->sc->vhost_id, *key_id, *certfile, *keyfile;
962 int i;
963 X509 *cert;
964 DH *dhparams;
965 #ifdef HAVE_ECC
966 EC_GROUP *ecparams;
967 int nid;
968 EC_KEY *eckey;
969 #endif
970 #ifndef HAVE_SSL_CONF_CMD
971 SSL *ssl;
972 #endif
973
974 /* no OpenSSL default prompts for any of the SSL_CTX_use_* calls, please */
975 SSL_CTX_set_default_passwd_cb(mctx->ssl_ctx, ssl_no_passwd_prompt_cb);
976
977 /* Iterate over the SSLCertificateFile array */
978 for (i = 0; (i < mctx->pks->cert_files->nelts) &&
979 (certfile = APR_ARRAY_IDX(mctx->pks->cert_files, i,
980 const char *));
981 i++) {
982 key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i);
983
984 ERR_clear_error();
985
986 /* first the certificate (public key) */
987 if (mctx->cert_chain) {
988 if ((SSL_CTX_use_certificate_file(mctx->ssl_ctx, certfile,
989 SSL_FILETYPE_PEM) < 1)) {
990 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02561)
991 "Failed to configure certificate %s, check %s",
992 key_id, certfile);
993 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
994 return APR_EGENERAL;
995 }
996 } else {
997 if ((SSL_CTX_use_certificate_chain_file(mctx->ssl_ctx,
998 certfile) < 1)) {
999 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02562)
1000 "Failed to configure certificate %s (with chain),"
1001 " check %s", key_id, certfile);
1002 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
1003 return APR_EGENERAL;
1004 }
1005 }
1006
1007 /* and second, the private key */
1008 if (i < mctx->pks->key_files->nelts) {
1009 keyfile = APR_ARRAY_IDX(mctx->pks->key_files, i, const char *);
1010 } else {
1011 keyfile = certfile;
1012 }
1013
1014 ERR_clear_error();
1015
1016 if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile,
1017 SSL_FILETYPE_PEM) < 1) &&
1018 (ERR_GET_FUNC(ERR_peek_last_error())
1019 != X509_F_X509_CHECK_PRIVATE_KEY)) {
1020 ssl_asn1_t *asn1;
1021 EVP_PKEY *pkey;
1022 const unsigned char *ptr;
1023
1024 ERR_clear_error();
1025
1026 /* perhaps it's an encrypted private key, so try again */
1027 ssl_load_encrypted_pkey(s, ptemp, i, keyfile, &pphrases);
1028
1029 if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id)) ||
1030 !(ptr = asn1->cpData) ||
1031 !(pkey = d2i_AutoPrivateKey(NULL, &ptr, asn1->nData)) ||
1032 (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1)) {
1033 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02564)
1034 "Failed to configure encrypted (?) private key %s,"
1035 " check %s", key_id, keyfile);
1036 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
1037 return APR_EGENERAL;
1038 }
1039 }
1040
1041 if (SSL_CTX_check_private_key(mctx->ssl_ctx) < 1) {
1042 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02565)
1043 "Certificate and private key %s from %s and %s "
1044 "do not match", key_id, certfile, keyfile);
1045 return APR_EGENERAL;
1046 }
1047
1048 #ifdef HAVE_SSL_CONF_CMD
1049 /*
1050 * workaround for those OpenSSL versions where SSL_CTX_get0_certificate
1051 * is not yet available: create an SSL struct which we dispose of
1052 * as soon as we no longer need access to the cert. (Strictly speaking,
1053 * SSL_CTX_get0_certificate does not depend on the SSL_CONF stuff,
1054 * but there's no reliable way to check for its existence, so we
1055 * assume that if SSL_CONF is available, it's OpenSSL 1.0.2 or later,
1056 * and SSL_CTX_get0_certificate is implemented.)
1057 */
1058 if (!(cert = SSL_CTX_get0_certificate(mctx->ssl_ctx))) {
1059 #else
1060 ssl = SSL_new(mctx->ssl_ctx);
1061 if (ssl) {
1062 /* Workaround bug in SSL_get_certificate in OpenSSL 0.9.8y */
1063 SSL_set_connect_state(ssl);
1064 cert = SSL_get_certificate(ssl);
1065 }
1066 if (!ssl || !cert) {
1067 #endif
1068 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02566)
1069 "Unable to retrieve certificate %s", key_id);
1070 #ifndef HAVE_SSL_CONF_CMD
1071 if (ssl)
1072 SSL_free(ssl);
1073 #endif
1074 return APR_EGENERAL;
1075 }
1076
1077 /* warn about potential cert issues */
1078 ssl_check_public_cert(s, ptemp, cert, key_id);
1079
1080 #if defined(HAVE_OCSP_STAPLING) && !defined(SSL_CTRL_SET_CURRENT_CERT)
1081 /*
1082 * OpenSSL up to 1.0.1: configure stapling as we go. In 1.0.2
1083 * and later, there's SSL_CTX_set_current_cert, which allows
1084 * iterating over all certs in an SSL_CTX (including those possibly
1085 * loaded via SSLOpenSSLConfCmd Certificate), so for 1.0.2 and
1086 * later, we defer to the code in ssl_init_server_ctx.
1087 */
1088 if ((mctx->stapling_enabled == TRUE) &&
1089 !ssl_stapling_init_cert(s, mctx, cert)) {
1090 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02567)
1091 "Unable to configure certificate %s for stapling",
1092 key_id);
1093 }
1094 #endif
1095
1096 #ifndef HAVE_SSL_CONF_CMD
1097 SSL_free(ssl);
1098 #endif
1099
1100 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02568)
1101 "Certificate and private key %s configured from %s and %s",
1102 key_id, certfile, keyfile);
1103 }
1104
1105 /*
1106 * Try to read DH parameters from the (first) SSLCertificateFile
1107 */
1108 if ((certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *)) &&
1109 (dhparams = ssl_dh_GetParamFromFile(certfile))) {
1110 SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dhparams);
1111 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02540)
1112 "Custom DH parameters (%d bits) for %s loaded from %s",
1113 BN_num_bits(dhparams->p), vhost_id, certfile);
1114 }
1115
1116 #ifdef HAVE_ECC
1117 /*
1118 * Similarly, try to read the ECDH curve name from SSLCertificateFile...
1119 */
1120 if ((certfile != NULL) &&
1121 (ecparams = ssl_ec_GetParamFromFile(certfile)) &&
1122 (nid = EC_GROUP_get_curve_name(ecparams)) &&
1123 (eckey = EC_KEY_new_by_curve_name(nid))) {
1124 SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey);
1125 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02541)
1126 "ECDH curve %s for %s specified in %s",
1127 OBJ_nid2sn(nid), vhost_id, certfile);
1128 }
1129 /*
1130 * ...otherwise, enable auto curve selection (OpenSSL 1.0.2 and later)
1131 * or configure NIST P-256 (required to enable ECDHE for earlier versions)
1132 */
1133 else {
1134 #if defined(SSL_CTX_set_ecdh_auto)
1135 SSL_CTX_set_ecdh_auto(mctx->ssl_ctx, 1);
1136 #else
1137 SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx,
1138 EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1139 #endif
1140 }
1141 #endif
1142
1143 return APR_SUCCESS;
1144 }
1145
1146 #ifdef HAVE_TLS_SESSION_TICKETS
1147 static apr_status_t ssl_init_ticket_key(server_rec *s,
1148 apr_pool_t *p,
1149 apr_pool_t *ptemp,
1150 modssl_ctx_t *mctx)
1151 {
1152 apr_status_t rv;
1153 apr_file_t *fp;
1154 apr_size_t len;
1155 char buf[TLSEXT_TICKET_KEY_LEN];
1156 char *path;
1157 modssl_ticket_key_t *ticket_key = mctx->ticket_key;
1158
1159 if (!ticket_key->file_path) {
1160 return APR_SUCCESS;
1161 }
1162
1163 path = ap_server_root_relative(p, ticket_key->file_path);
1164
1165 rv = apr_file_open(&fp, path, APR_READ|APR_BINARY,
1166 APR_OS_DEFAULT, ptemp);
1167
1168 if (rv != APR_SUCCESS) {
1169 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02286)
1170 "Failed to open ticket key file %s: (%d) %pm",
1171 path, rv, &rv);
1172 return ssl_die(s);
1173 }
1174
1175 rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEY_LEN, &len);
1176
1177 if (rv != APR_SUCCESS) {
1178 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02287)
1179 "Failed to read %d bytes from %s: (%d) %pm",
1180 TLSEXT_TICKET_KEY_LEN, path, rv, &rv);
1181 return ssl_die(s);
1182 }
1183
1184 memcpy(ticket_key->key_name, buf, 16);
1185 memcpy(ticket_key->hmac_secret, buf + 16, 16);
1186 memcpy(ticket_key->aes_key, buf + 32, 16);
1187
1188 if (!SSL_CTX_set_tlsext_ticket_key_cb(mctx->ssl_ctx,
1189 ssl_callback_SessionTicket)) {
1190 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01913)
1191 "Unable to initialize TLS session ticket key callback "
1192 "(incompatible OpenSSL version?)");
1193 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
1194 return ssl_die(s);
1195 }
1196
1197 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02288)
1198 "TLS session ticket key for %s successfully loaded from %s",
1199 (mySrvConfig(s))->vhost_id, path);
1200
1201 return APR_SUCCESS;
1202 }
1203 #endif
1204
1205 static apr_status_t ssl_init_proxy_certs(server_rec *s,
1206 apr_pool_t *p,
1207 apr_pool_t *ptemp,
1208 modssl_ctx_t *mctx)
1209 {
1210 int n, ncerts = 0;
1211 STACK_OF(X509_INFO) *sk;
1212 modssl_pk_proxy_t *pkp = mctx->pkp;
1213 STACK_OF(X509) *chain;
1214 X509_STORE_CTX *sctx;
1215 X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
1216
1217 SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
1218 ssl_callback_proxy_cert);
1219
1220 if (!(pkp->cert_file || pkp->cert_path)) {
1221 return APR_SUCCESS;
1222 }
1223
1224 sk = sk_X509_INFO_new_null();
1225
1226 if (pkp->cert_file) {
1227 SSL_X509_INFO_load_file(ptemp, sk, pkp->cert_file);
1228 }
1229
1230 if (pkp->cert_path) {
1231 SSL_X509_INFO_load_path(ptemp, sk, pkp->cert_path);
1232 }
1233
1234 if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
1235 sk_X509_INFO_free(sk);
1236 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
1237 "no client certs found for SSL proxy");
1238 return APR_SUCCESS;
1239 }
1240
1241 /* Check that all client certs have got certificates and private
1242 * keys. */
1243 for (n = 0; n < ncerts; n++) {
1244 X509_INFO *inf = sk_X509_INFO_value(sk, n);
1245
1246 if (!inf->x509 || !inf->x_pkey || !inf->x_pkey->dec_pkey ||
1247 inf->enc_data) {
1248 sk_X509_INFO_free(sk);
1249 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
1250 "incomplete client cert configured for SSL proxy "
1251 "(missing or encrypted private key?)");
1252 return ssl_die(s);
1253 }
1254
1255 if (X509_check_private_key(inf->x509, inf->x_pkey->dec_pkey) != 1) {
1256 ssl_log_xerror(SSLLOG_MARK, APLOG_STARTUP, 0, ptemp, s, inf->x509,
1257 APLOGNO(02326) "proxy client certificate and "
1258 "private key do not match");
1259 ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
1260 return ssl_die(s);
1261 }
1262 }
1263
1264 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02207)
1265 "loaded %d client certs for SSL proxy",
1266 ncerts);
1267 pkp->certs = sk;
1268
1269
1270 if (!pkp->ca_cert_file || !store) {
1271 return APR_SUCCESS;
1272 }
1273
1274 /* If SSLProxyMachineCertificateChainFile is configured, load all
1275 * the CA certs and have OpenSSL attempt to construct a full chain
1276 * from each configured end-entity cert up to a root. This will
1277 * allow selection of the correct cert given a list of root CA
1278 * names in the certificate request from the server. */
1279 pkp->ca_certs = (STACK_OF(X509) **) apr_pcalloc(p, ncerts * sizeof(sk));
1280 sctx = X509_STORE_CTX_new();
1281
1282 if (!sctx) {
1283 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02208)
1284 "SSL proxy client cert initialization failed");
1285 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
1286 return ssl_die(s);
1287 }
1288
1289 X509_STORE_load_locations(store, pkp->ca_cert_file, NULL);
1290
1291 for (n = 0; n < ncerts; n++) {
1292 int i;
1293
1294 X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n);
1295 X509_STORE_CTX_init(sctx, store, inf->x509, NULL);
1296
1297 /* Attempt to verify the client cert */
1298 if (X509_verify_cert(sctx) != 1) {
1299 int err = X509_STORE_CTX_get_error(sctx);
1300 ssl_log_xerror(SSLLOG_MARK, APLOG_WARNING, 0, ptemp, s, inf->x509,
1301 APLOGNO(02270) "SSL proxy client cert chain "
1302 "verification failed: %s :",
1303 X509_verify_cert_error_string(err));
1304 }
1305
1306 /* Clear X509_verify_cert errors */
1307 ERR_clear_error();
1308
1309 /* Obtain a copy of the verified chain */
1310 chain = X509_STORE_CTX_get1_chain(sctx);
1311
1312 if (chain != NULL) {
1313 /* Discard end entity cert from the chain */
1314 X509_free(sk_X509_shift(chain));
1315
1316 if ((i = sk_X509_num(chain)) > 0) {
1317 /* Store the chain for later use */
1318 pkp->ca_certs[n] = chain;
1319 }
1320 else {
1321 /* Discard empty chain */
1322 sk_X509_pop_free(chain, X509_free);
1323 pkp->ca_certs[n] = NULL;
1324 }
1325
1326 ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509,
1327 APLOGNO(02271)
1328 "loaded %i intermediate CA%s for cert %i: ",
1329 i, i == 1 ? "" : "s", n);
1330 if (i > 0) {
1331 int j;
1332 for (j = 0; j < i; j++) {
1333 ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s,
1334 sk_X509_value(chain, j), "%i:", j);
1335 }
1336 }
1337 }
1338
1339 /* get ready for next X509_STORE_CTX_init */
1340 X509_STORE_CTX_cleanup(sctx);
1341 }
1342
1343 X509_STORE_CTX_free(sctx);
1344
1345 return APR_SUCCESS;
1346 }
1347
1348 static apr_status_t ssl_init_proxy_ctx(server_rec *s,
1349 apr_pool_t *p,
1350 apr_pool_t *ptemp,
1351 SSLSrvConfigRec *sc)
1352 {
1353 apr_status_t rv;
1354
1355 if ((rv = ssl_init_ctx(s, p, ptemp, sc->proxy)) != APR_SUCCESS) {
1356 return rv;
1357 }
1358
1359 if ((rv = ssl_init_proxy_certs(s, p, ptemp, sc->proxy)) != APR_SUCCESS) {
1360 return rv;
1361 }
1362
1363 return APR_SUCCESS;
1364 }
1365
1366 static apr_status_t ssl_init_server_ctx(server_rec *s,
1367 apr_pool_t *p,
1368 apr_pool_t *ptemp,
1369 SSLSrvConfigRec *sc,
1370 apr_array_header_t *pphrases)
1371 {
1372 apr_status_t rv;
1373 #ifdef HAVE_SSL_CONF_CMD
1374 ssl_ctx_param_t *param = (ssl_ctx_param_t *)sc->server->ssl_ctx_param->elts;
1375 SSL_CONF_CTX *cctx = sc->server->ssl_ctx_config;
1376 int i;
1377 #endif
1378
1379 /*
1380 * Check for problematic re-initializations
1381 */
1382 if (sc->server->ssl_ctx) {
1383 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02569)
1384 "Illegal attempt to re-initialise SSL for server "
1385 "(SSLEngine On should go in the VirtualHost, not in global scope.)");
1386 return APR_EGENERAL;
1387 }
1388
1389 if ((rv = ssl_init_ctx(s, p, ptemp, sc->server)) != APR_SUCCESS) {
1390 return rv;
1391 }
1392
1393 if ((rv = ssl_init_server_certs(s, p, ptemp, sc->server, pphrases))
1394 != APR_SUCCESS) {
1395 return rv;
1396 }
1397
1398 #ifdef HAVE_SSL_CONF_CMD
1399 SSL_CONF_CTX_set_ssl_ctx(cctx, sc->server->ssl_ctx);
1400 for (i = 0; i < sc->server->ssl_ctx_param->nelts; i++, param++) {
1401 ERR_clear_error();
1402 if (SSL_CONF_cmd(cctx, param->name, param->value) <= 0) {
1403 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02407)
1404 "\"SSLOpenSSLConfCmd %s %s\" failed for %s",
1405 param->name, param->value, sc->vhost_id);
1406 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
1407 return ssl_die(s);
1408 } else {
1409 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02556)
1410 "\"SSLOpenSSLConfCmd %s %s\" applied to %s",
1411 param->name, param->value, sc->vhost_id);
1412 }
1413 }
1414 if (SSL_CONF_CTX_finish(cctx) == 0) {
1415 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02547)
1416 "SSL_CONF_CTX_finish() failed");
1417 SSL_CONF_CTX_free(cctx);
1418 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
1419 return ssl_die(s);
1420 }
1421 SSL_CONF_CTX_free(cctx);
1422 #endif
1423
1424 if (SSL_CTX_check_private_key(sc->server->ssl_ctx) != 1) {
1425 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02572)
1426 "Failed to configure at least one certificate and key "
1427 "for %s", sc->vhost_id);
1428 ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
1429 return ssl_die(s);
1430 }
1431
1432 #if defined(HAVE_OCSP_STAPLING) && defined(SSL_CTRL_SET_CURRENT_CERT)
1433 /*
1434 * OpenSSL 1.0.2 and later allows iterating over all SSL_CTX certs
1435 * by means of SSL_CTX_set_current_cert. Enabling stapling at this
1436 * (late) point makes sure that we catch both certificates loaded
1437 * via SSLCertificateFile and SSLOpenSSLConfCmd Certificate.
1438 */
1439 if (sc->server->stapling_enabled == TRUE) {
1440 X509 *cert;
1441 int i = 0;
1442 int ret = SSL_CTX_set_current_cert(sc->server->ssl_ctx,
1443 SSL_CERT_SET_FIRST);
1444 while (ret) {
1445 cert = SSL_CTX_get0_certificate(sc->server->ssl_ctx);
1446 if (!cert || !ssl_stapling_init_cert(s, sc->server, cert)) {
1447 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02604)
1448 "Unable to configure certificate %s:%d "
1449 "for stapling", sc->vhost_id, i);
1450 }
1451 ret = SSL_CTX_set_current_cert(sc->server->ssl_ctx,
1452 SSL_CERT_SET_NEXT);
1453 i++;
1454 }
1455 }
1456 #endif
1457
1458 #ifdef HAVE_TLS_SESSION_TICKETS
1459 if ((rv = ssl_init_ticket_key(s, p, ptemp, sc->server)) != APR_SUCCESS) {
1460 return rv;
1461 }
1462 #endif
1463
1464 return APR_SUCCESS;
1465 }
1466
1467 /*
1468 * Configure a particular server
1469 */
1470 apr_status_t ssl_init_ConfigureServer(server_rec *s,
1471 apr_pool_t *p,
1472 apr_pool_t *ptemp,
1473 SSLSrvConfigRec *sc,
1474 apr_array_header_t *pphrases)
1475 {
1476 apr_status_t rv;
1477
1478 /* Initialize the server if SSL is enabled or optional.
1479 */
1480 if ((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) {
1481 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01914)
1482 "Configuring server %s for SSL protocol", sc->vhost_id);
1483 if ((rv = ssl_init_server_ctx(s, p, ptemp, sc, pphrases))
1484 != APR_SUCCESS) {
1485 return rv;
1486 }
1487 }
1488
1489 if (sc->proxy_enabled) {
1490 if ((rv = ssl_init_proxy_ctx(s, p, ptemp, sc)) != APR_SUCCESS) {
1491 return rv;
1492 }
1493 }
1494
1495 return APR_SUCCESS;
1496 }
1497
1498 apr_status_t ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
1499 {
1500 server_rec *s;
1501 SSLSrvConfigRec *sc;
1502 #ifndef HAVE_TLSEXT
1503 server_rec *ps;
1504 apr_hash_t *table;
1505 const char *key;
1506 apr_ssize_t klen;
1507
1508 BOOL conflict = FALSE;
1509 #endif
1510
1511 /*
1512 * Give out warnings when a server has HTTPS configured
1513 * for the HTTP port or vice versa
1514 */
1515 for (s = base_server; s; s = s->next) {
1516 sc = mySrvConfig(s);
1517
1518 if ((sc->enabled == SSL_ENABLED_TRUE) && (s->port == DEFAULT_HTTP_PORT)) {
1519 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1520 base_server, APLOGNO(01915)
1521 "Init: (%s) You configured HTTPS(%d) "
1522 "on the standard HTTP(%d) port!",
1523 ssl_util_vhostid(p, s),
1524 DEFAULT_HTTPS_PORT, DEFAULT_HTTP_PORT);
1525 }
1526
1527 if ((sc->enabled == SSL_ENABLED_FALSE) && (s->port == DEFAULT_HTTPS_PORT)) {
1528 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1529 base_server, APLOGNO(01916)
1530 "Init: (%s) You configured HTTP(%d) "
1531 "on the standard HTTPS(%d) port!",
1532 ssl_util_vhostid(p, s),
1533 DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT);
1534 }
1535 }
1536
1537 #ifndef HAVE_TLSEXT
1538 /*
1539 * Give out warnings when more than one SSL-aware virtual server uses the
1540 * same IP:port and an OpenSSL version without support for TLS extensions
1541 * (SNI in particular) is used.
1542 */
1543 table = apr_hash_make(p);
1544
1545 for (s = base_server; s; s = s->next) {
1546 char *addr;
1547
1548 sc = mySrvConfig(s);
1549
1550 if (!((sc->enabled == SSL_ENABLED_TRUE) && s->addrs)) {
1551 continue;
1552 }
1553
1554 apr_sockaddr_ip_get(&addr, s->addrs->host_addr);
1555 key = apr_psprintf(p, "%s:%u", addr, s->addrs->host_port);
1556 klen = strlen(key);
1557
1558 if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
1559 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
1560 "Init: SSL server IP/port conflict: "
1561 "%s (%s:%d) vs. %s (%s:%d)",
1562 ssl_util_vhostid(p, s),
1563 (s->defn_name ? s->defn_name : "unknown"),
1564 s->defn_line_number,
1565 ssl_util_vhostid(p, ps),
1566 (ps->defn_name ? ps->defn_name : "unknown"),
1567 ps->defn_line_number);
1568 conflict = TRUE;
1569 continue;
1570 }
1571
1572 apr_hash_set(table, key, klen, s);
1573 }
1574
1575 if (conflict) {
1576 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01917)
1577 "Init: Name-based SSL virtual hosts require "
1578 "an OpenSSL version with support for TLS extensions "
1579 "(RFC 6066 - Server Name Indication / SNI), "
1580 "but the currently used library version (%s) is "
1581 "lacking this feature", SSLeay_version(SSLEAY_VERSION));
1582 }
1583 #endif
1584
1585 return APR_SUCCESS;
1586 }
1587
1588 static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
1589 const X509_NAME * const *b)
1590 {
1591 return(X509_NAME_cmp(*a, *b));
1592 }
1593
1594 static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
1595 server_rec *s, apr_pool_t *ptemp,
1596 const char *file)
1597 {
1598 int n;
1599 STACK_OF(X509_NAME) *sk;
1600
1601 sk = (STACK_OF(X509_NAME) *)
1602 SSL_load_client_CA_file(file);
1603
1604 if (!sk) {
1605 return;
1606 }
1607
1608 for (n = 0; n < sk_X509_NAME_num(sk); n++) {
1609 X509_NAME *name = sk_X509_NAME_value(sk, n);
1610
1611 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209)
1612 "CA certificate: %s",
1613 SSL_X509_NAME_to_string(ptemp, name, 0));
1614
1615 /*
1616 * note that SSL_load_client_CA_file() checks for duplicates,
1617 * but since we call it multiple times when reading a directory
1618 * we must also check for duplicates ourselves.
1619 */
1620
1621 if (sk_X509_NAME_find(ca_list, name) < 0) {
1622 /* this will be freed when ca_list is */
1623 sk_X509_NAME_push(ca_list, name);
1624 }
1625 else {
1626 /* need to free this ourselves, else it will leak */
1627 X509_NAME_free(name);
1628 }
1629 }
1630
1631 sk_X509_NAME_free(sk);
1632 }
1633
1634 STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
1635 apr_pool_t *ptemp,
1636 const char *ca_file,
1637 const char *ca_path)
1638 {
1639 STACK_OF(X509_NAME) *ca_list;
1640
1641 /*
1642 * Start with a empty stack/list where new
1643 * entries get added in sorted order.
1644 */
1645 ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp);
1646
1647 /*
1648 * Process CA certificate bundle file
1649 */
1650 if (ca_file) {
1651 ssl_init_PushCAList(ca_list, s, ptemp, ca_file);
1652 /*
1653 * If ca_list is still empty after trying to load ca_file
1654 * then the file failed to load, and users should hear about that.
1655 */
1656 if (sk_X509_NAME_num(ca_list) == 0) {
1657 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02210)
1658 "Failed to load SSLCACertificateFile: %s", ca_file);
1659 ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
1660 }
1661 }
1662
1663 /*
1664 * Process CA certificate path files
1665 */
1666 if (ca_path) {
1667 apr_dir_t *dir;
1668 apr_finfo_t direntry;
1669 apr_int32_t finfo_flags = APR_FINFO_TYPE|APR_FINFO_NAME;
1670 apr_status_t rv;
1671
1672 if ((rv = apr_dir_open(&dir, ca_path, ptemp)) != APR_SUCCESS) {
1673 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02211)
1674 "Failed to open Certificate Path `%s'",
1675 ca_path);
1676 sk_X509_NAME_pop_free(ca_list, X509_NAME_free);
1677 return NULL;
1678 }
1679
1680 while ((apr_dir_read(&direntry, finfo_flags, dir)) == APR_SUCCESS) {
1681 const char *file;
1682 if (direntry.filetype == APR_DIR) {
1683 continue; /* don't try to load directories */
1684 }
1685 file = apr_pstrcat(ptemp, ca_path, "/", direntry.name, NULL);
1686 ssl_init_PushCAList(ca_list, s, ptemp, file);
1687 }
1688
1689 apr_dir_close(dir);
1690 }
1691
1692 /*
1693 * Cleanup
1694 */
1695 (void) sk_X509_NAME_set_cmp_func(ca_list, NULL);
1696
1697 return ca_list;
1698 }
1699
1700 void ssl_init_Child(apr_pool_t *p, server_rec *s)
1701 {
1702 SSLModConfigRec *mc = myModConfig(s);
1703 mc->pid = getpid(); /* only call getpid() once per-process */
1704
1705 /* XXX: there should be an ap_srand() function */
1706 srand((unsigned int)time(NULL));
1707
1708 /* open the mutex lockfile */
1709 ssl_mutex_reinit(s, p);
1710 #ifdef HAVE_OCSP_STAPLING
1711 ssl_stapling_mutex_reinit(s, p);
1712 #endif
1713 }
1714
1715 #define MODSSL_CFG_ITEM_FREE(func, item) \
1716 if (item) { \
1717 func(item); \
1718 item = NULL; \
1719 }
1720
1721 static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
1722 {
1723 MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
1724
1725 #ifdef HAVE_SRP
1726 if (mctx->srp_vbase != NULL) {
1727 SRP_VBASE_free(mctx->srp_vbase);
1728 mctx->srp_vbase = NULL;
1729 }
1730 #endif
1731 }
1732
1733 static void ssl_init_ctx_cleanup_proxy(modssl_ctx_t *mctx)
1734 {
1735 ssl_init_ctx_cleanup(mctx);
1736
1737 if (mctx->pkp->certs) {
1738 int i = 0;
1739 int ncerts = sk_X509_INFO_num(mctx->pkp->certs);
1740
1741 if (mctx->pkp->ca_certs) {
1742 for (i = 0; i < ncerts; i++) {
1743 if (mctx->pkp->ca_certs[i] != NULL) {
1744 sk_X509_pop_free(mctx->pkp->ca_certs[i], X509_free);
1745 }
1746 }
1747 }
1748
1749 sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free);
1750 mctx->pkp->certs = NULL;
1751 }
1752 }
1753
1754 apr_status_t ssl_init_ModuleKill(void *data)
1755 {
1756 SSLSrvConfigRec *sc;
1757 server_rec *base_server = (server_rec *)data;
1758 server_rec *s;
1759
1760 /*
1761 * Drop the session cache and mutex
1762 */
1763 ssl_scache_kill(base_server);
1764
1765 /*
1766 * Free the non-pool allocated structures
1767 * in the per-server configurations
1768 */
1769 for (s = base_server; s; s = s->next) {
1770 sc = mySrvConfig(s);
1771
1772 ssl_init_ctx_cleanup_proxy(sc->proxy);
1773
1774 ssl_init_ctx_cleanup(sc->server);
1775 }
1776
1777 free_dh_params();
1778
1779 return APR_SUCCESS;
1780 }

Properties

Name Value
svn:eol-style native

infrastructure at apache.org
ViewVC Help
Powered by ViewVC 1.1.26