Project

General

Profile

lighttpd_1.4.x_r2118_tls_server_name_indication.patch

TLS server name indication support (lighttpd 1.4.x-svn) - phc, 2008-03-08 17:42

View differences:

src/base.h Sun Mar 02 12:59:05 2008 +0000 → src/base.h Sat Mar 08 18:06:17 2008 +0100
31 31
#if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
32 32
# define USE_OPENSSL
33 33
# include <openssl/ssl.h>
34
# if ! defined OPENSSL_NO_TLSEXT && ! defined SSL_CTRL_SET_TLSEXT_HOSTNAME
35
#  define OPENSSL_NO_TLSEXT
36
# endif
34 37
#endif
35 38

  
36 39
#ifdef HAVE_FAM_H
......
415 418
#ifdef USE_OPENSSL
416 419
	SSL *ssl;
417 420
	buffer *ssl_error_want_reuse_buffer;
421
#ifndef OPENSSL_NO_TLSEXT
422
	buffer *tlsext_server_name;
423
#endif
418 424
#endif
419 425
	/* etag handling */
420 426
	etag_flags_t etag_flags;
src/configfile-glue.c Sun Mar 02 12:59:05 2008 +0000 → src/configfile-glue.c Sat Mar 08 18:06:17 2008 +0100
272 272
			default:
273 273
				break;
274 274
			}
275
#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
276
		} else if (!buffer_is_empty(con->tlsext_server_name)) {
277
			l = con->tlsext_server_name;
278
#endif
275 279
		} else {
276 280
			l = srv->empty_string;
277 281
		}
src/configfile.c Sun Mar 02 12:59:05 2008 +0000 → src/configfile.c Sat Mar 08 18:06:17 2008 +0100
285 285
	PATCH(is_ssl);
286 286

  
287 287
	PATCH(ssl_pemfile);
288
	PATCH(ssl_ctx);
288 289
	PATCH(ssl_ca_file);
289 290
	PATCH(ssl_cipher_list);
290 291
	PATCH(ssl_use_sslv2);
......
343 344
				PATCH(etag_use_size);
344 345
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.pemfile"))) {
345 346
				PATCH(ssl_pemfile);
347
				PATCH(ssl_ctx);
346 348
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) {
347 349
				PATCH(ssl_ca_file);
348 350
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-sslv2"))) {
src/connections.c Sun Mar 02 12:59:05 2008 +0000 → src/connections.c Sat Mar 08 18:06:17 2008 +0100
674 674
	CLEAN(server_name);
675 675
	CLEAN(error_handler);
676 676
	CLEAN(dst_addr_buf);
677
#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
678
	CLEAN(tlsext_server_name);
679
#endif
677 680

  
678 681
#undef CLEAN
679 682
	con->write_queue = chunkqueue_init();
......
738 741
		CLEAN(server_name);
739 742
		CLEAN(error_handler);
740 743
		CLEAN(dst_addr_buf);
744
#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
745
		CLEAN(tlsext_server_name);
746
#endif
741 747
#undef CLEAN
742 748
		free(con->plugin_ctx);
743 749
		free(con->cond_cache);
......
1345 1351
				return NULL;
1346 1352
			}
1347 1353

  
1354
#ifndef OPENSSL_NO_TLSEXT
1355
			SSL_set_app_data(con->ssl, con);
1356
#endif
1348 1357
			SSL_set_accept_state(con->ssl);
1349 1358
			con->conf.is_ssl=1;
1350 1359

  
src/network.c Sun Mar 02 12:59:05 2008 +0000 → src/network.c Sat Mar 08 18:06:17 2008 +0100
61 61
	}
62 62
	return HANDLER_GO_ON;
63 63
}
64

  
65
#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
66
int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) {
67
	const char *servername;
68
	connection *con = (connection *) SSL_get_app_data(ssl);
69

  
70
	buffer_copy_string(con->uri.scheme, "https");
71

  
72
	if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
73
		log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
74
				"failed to get TLS server name");
75
		return SSL_TLSEXT_ERR_NOACK;
76
	}
77
	buffer_copy_string(con->tlsext_server_name, servername);
78
	buffer_to_lower(con->tlsext_server_name);
79

  
80
	config_cond_cache_reset(srv, con);
81
	config_setup_connection(srv, con);
82

  
83
	config_patch_connection(srv, con, COMP_SERVER_SOCKET);
84
	config_patch_connection(srv, con, COMP_HTTP_SCHEME);
85
	config_patch_connection(srv, con, COMP_HTTP_HOST);
86

  
87
	if (NULL == con->conf.ssl_ctx) {
88
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
89
				"null SSL_CTX for TLS server name", con->tlsext_server_name);
90
		return SSL_TLSEXT_ERR_ALERT_FATAL;
91
	}
92

  
93
	/* switch to new SSL_CTX in reaction to a client's server_name extension */
94
	if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) {
95
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
96
				"failed to set SSL_CTX for TLS server name", con->tlsext_server_name);
97
		return SSL_TLSEXT_ERR_ALERT_FATAL;
98
	}
99

  
100
	return SSL_TLSEXT_ERR_OK;
101
}
102
#endif
64 103

  
65 104
int network_server_init(server *srv, buffer *host_token, specific_config *s) {
66 105
	int val;
......
312 351

  
313 352
	if (s->is_ssl) {
314 353
#ifdef USE_OPENSSL
315
		if (srv->ssl_is_init == 0) {
316
			SSL_load_error_strings();
317
			SSL_library_init();
318
			srv->ssl_is_init = 1;
319

  
320
			if (0 == RAND_status()) {
321
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
322
						"not enough entropy in the pool");
323
				return -1;
324
			}
325
		}
326

  
327
		if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
328
			log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
329
					ERR_error_string(ERR_get_error(), NULL));
330
			return -1;
331
		}
332

  
333
		if (!s->ssl_use_sslv2) {
334
			/* disable SSLv2 */
335
			if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) {
336
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
337
						ERR_error_string(ERR_get_error(), NULL));
338
				return -1;
339
			}
340
		}
341

  
342
		if (!buffer_is_empty(s->ssl_cipher_list)) {
343
			/* Disable support for low encryption ciphers */
344
			if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
345
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
346
						ERR_error_string(ERR_get_error(), NULL));
347
				return -1;
348
			}
349
		}
350

  
351
		if (buffer_is_empty(s->ssl_pemfile)) {
354
		if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) {
352 355
			log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set");
353 356
			return -1;
354 357
		}
355

  
356
		if (!buffer_is_empty(s->ssl_ca_file)) {
357
			if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
358
				log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
359
						ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
360
				return -1;
361
			}
362
		}
363

  
364
		if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
365
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
366
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
367
			return -1;
368
		}
369

  
370
		if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
371
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
372
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
373
			return -1;
374
		}
375

  
376
		if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
377
			log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
378
					"Private key does not match the certificate public key, reason:",
379
					ERR_error_string(ERR_get_error(), NULL),
380
					s->ssl_pemfile);
381
			return -1;
382
		}
383
		SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1);
384
		SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
385

  
386
		srv_socket->ssl_ctx = s->ssl_ctx;
387 358
#else
388 359

  
389 360
		buffer_free(srv_socket->srv_token);
......
490 461
		{ NETWORK_BACKEND_WRITE,		"write" },
491 462
		{ NETWORK_BACKEND_UNSET,        	NULL }
492 463
	};
464

  
465
#ifdef USE_OPENSSL
466
	/* load SSL certificates */
467
	for (i = 0; i < srv->config_context->used; i++) {
468
		data_config *dc = (data_config *)srv->config_context->data[i];
469
		specific_config *s = srv->config_storage[i];
470

  
471
		if (buffer_is_empty(s->ssl_pemfile)) continue;
472

  
473
#ifdef OPENSSL_NO_TLSEXT
474
		if (COMP_HTTP_HOST == dc->comp) {
475
		    log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
476
				    "can't use ssl.pemfile with $HTTP[\"host\"], openssl version does not support TLS extensions");
477
		    return -1;
478
		}
479
#endif
480

  
481
		if (srv->ssl_is_init == 0) {
482
			SSL_load_error_strings();
483
			SSL_library_init();
484
			srv->ssl_is_init = 1;
485

  
486
			if (0 == RAND_status()) {
487
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
488
						"not enough entropy in the pool");
489
				return -1;
490
			}
491
		}
492

  
493
		if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
494
			log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
495
					ERR_error_string(ERR_get_error(), NULL));
496
			return -1;
497
		}
498

  
499
		if (!s->ssl_use_sslv2) {
500
			/* disable SSLv2 */
501
			if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) {
502
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
503
						ERR_error_string(ERR_get_error(), NULL));
504
				return -1;
505
			}
506
		}
507

  
508
		if (!buffer_is_empty(s->ssl_cipher_list)) {
509
			/* Disable support for low encryption ciphers */
510
			if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
511
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
512
						ERR_error_string(ERR_get_error(), NULL));
513
				return -1;
514
			}
515
		}
516

  
517
		if (!buffer_is_empty(s->ssl_ca_file)) {
518
			if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
519
				log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
520
						ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
521
				return -1;
522
			}
523
		}
524

  
525
		if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
526
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
527
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
528
			return -1;
529
		}
530

  
531
		if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
532
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
533
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
534
			return -1;
535
		}
536

  
537
		if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
538
			log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
539
					"Private key does not match the certificate public key, reason:",
540
					ERR_error_string(ERR_get_error(), NULL),
541
					s->ssl_pemfile);
542
			return -1;
543
		}
544
		SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1);
545
		SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
546

  
547
#ifndef OPENSSL_NO_TLSEXT
548
		if (!SSL_CTX_set_tlsext_servername_callback(s->ssl_ctx, network_ssl_servername_callback) ||
549
		    !SSL_CTX_set_tlsext_servername_arg(s->ssl_ctx, srv)) {
550
			log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
551
					"failed to initialize TLS servername callback, openssl library does not support TLS servername extension");
552
			return -1;
553
		}
554
#endif
555
	}
556
#endif
493 557

  
494 558
	b = buffer_init();
495 559