Project

General

Profile

Feature #386 » lighttpd_1.5.0_r2171_tls_server_name_indication.patch

TLS server name indication support (lighttpd 1.5.0-svn) - phc, 2008-05-15 20:00

View differences:

trunk/src/configfile-glue.c (working copy)
300 300
			default:
301 301
				break;
302 302
			}
303
#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
304
		} else if (!buffer_is_empty(con->sock->tlsext_server_name)) {
305
			l = con->sock->tlsext_server_name;
306
#endif
303 307
		} else {
304 308
			l = srv->empty_string;
305 309
		}
trunk/src/base.h (working copy)
37 37
#if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
38 38
# define USE_OPENSSL
39 39
# include <openssl/ssl.h>
40
# if ! defined OPENSSL_NO_TLSEXT && ! defined SSL_CTRL_SET_TLSEXT_HOSTNAME
41
#  define OPENSSL_NO_TLSEXT
42
# endif
40 43
#endif
41 44

  
42 45
#ifdef HAVE_SYS_INOTIFY_H
trunk/src/connections.c (working copy)
955 955
				return NULL;
956 956
			}
957 957

  
958
#ifndef OPENSSL_NO_TLSEXT
959
			SSL_set_app_data(con->sock->ssl, con);
960
#endif
958 961
			SSL_set_accept_state(con->sock->ssl);
959 962
			con->conf.is_ssl=1;
960 963

  
trunk/src/network.c (working copy)
219 219
	return HANDLER_GO_ON;
220 220
}
221 221

  
222
#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
223
int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) {
224
	const char *servername;
225
	connection *con = (connection *) SSL_get_app_data(ssl);
226

  
227
	buffer_copy_string(con->uri.scheme, "https");
228

  
229
	if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
230
		log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
231
				"failed to get TLS server name");
232
		return SSL_TLSEXT_ERR_NOACK;
233
	}
234
	buffer_copy_string(con->sock->tlsext_server_name, servername);
235
	buffer_to_lower(con->sock->tlsext_server_name);
236

  
237
	config_patch_connection(srv, con, COMP_SERVER_SOCKET);
238
	config_patch_connection(srv, con, COMP_HTTP_SCHEME);
239
	config_patch_connection(srv, con, COMP_HTTP_HOST);
240

  
241
	if (NULL == con->conf.ssl_ctx) {
242
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
243
				"null SSL_CTX for TLS server name", con->sock->tlsext_server_name);
244
		return SSL_TLSEXT_ERR_ALERT_FATAL;
245
	}
246

  
247
	/* switch to new SSL_CTX in reaction to a client's server_name extension */
248
	if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) {
249
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
250
				"failed to set SSL_CTX for TLS server name", con->sock->tlsext_server_name);
251
		return SSL_TLSEXT_ERR_ALERT_FATAL;
252
	}
253

  
254
	return SSL_TLSEXT_ERR_OK;
255
}
256
#endif
257

  
222 258
int network_server_init(server *srv, buffer *host_token, specific_config *s) {
223 259
	int val;
224 260
	socklen_t addr_len;
......
468 504

  
469 505
	if (s->is_ssl) {
470 506
#ifdef USE_OPENSSL
471
		if (srv->ssl_is_init == 0) {
472
			SSL_load_error_strings();
473
			SSL_library_init();
474
			srv->ssl_is_init = 1;
475

  
476
			if (0 == RAND_status()) {
477
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
478
						"not enough entropy in the pool");
479
				return -1;
480
			}
481
		}
482

  
483
		if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
484
			log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
485
					ERR_error_string(ERR_get_error(), NULL));
486
			return -1;
487
		}
488
		
489
		if (!s->ssl_use_sslv2) {
490
			/* disable SSLv2 */
491
			if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) {
492
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
493
						ERR_error_string(ERR_get_error(), NULL));
494
				return -1;
495
			}
496
		}
497
		
498
		if (!buffer_is_empty(s->ssl_cipher_list)) {
499
			if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
500
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
501
						ERR_error_string(ERR_get_error(), NULL));
502
				return -1;
503
			}
504
		}
505
		
506
		if (buffer_is_empty(s->ssl_pemfile)) {
507
		if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) {
507 508
			log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set");
508 509
			return -1;
509 510
		}
510

  
511
		if (!buffer_is_empty(s->ssl_ca_file)) {
512
			if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
513
				log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
514
						ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
515
				return -1;
516
			}
517
		}
518

  
519
		if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
520
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
521
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
522
			return -1;
523
		}
524

  
525
		if (SSL_CTX_use_PrivateKey_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_check_private_key(s->ssl_ctx) != 1) {
532
			log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
533
					"Private key does not match the certificate public key, reason:",
534
					ERR_error_string(ERR_get_error(), NULL),
535
					s->ssl_pemfile);
536
			return -1;
537
		}
538
		srv_socket->ssl_ctx = s->ssl_ctx;
539 511
#else
540 512

  
541 513
		buffer_free(srv_socket->srv_token);
......
594 566
			}
595 567
		}
596 568

  
597
		if (srv_socket->is_ssl) {
598
#ifdef USE_OPENSSL
599
			SSL_CTX_free(srv_socket->ssl_ctx);
600
#endif
601
		}
602

  
603 569
		iosocket_free(srv_socket->sock);
604 570

  
605 571
		buffer_free(srv_socket->srv_token);
......
620 586
	size_t i;
621 587
	const network_backend_info_t *backend;
622 588

  
589
#ifdef USE_OPENSSL
590
	/* load SSL certificates */
591
	for (i = 0; i < srv->config_context->used; i++) {
592
		data_config *dc = (data_config *)srv->config_context->data[i];
593
		specific_config *s = srv->config_storage[i];
594

  
595
		if (buffer_is_empty(s->ssl_pemfile)) continue;
596

  
597
#ifdef OPENSSL_NO_TLSEXT
598
		if (COMP_HTTP_HOST == dc->comp) {
599
			log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
600
					"can't use ssl.pemfile with $HTTP[\"host\"], openssl version does not support TLS extensions");
601
			return -1;
602
		}
603
#endif
604

  
605
		if (srv->ssl_is_init == 0) {
606
			SSL_load_error_strings();
607
			SSL_library_init();
608
			srv->ssl_is_init = 1;
609

  
610
			if (0 == RAND_status()) {
611
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
612
						"not enough entropy in the pool");
613
				return -1;
614
			}
615
		}
616

  
617
		if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
618
			log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
619
					ERR_error_string(ERR_get_error(), NULL));
620
			return -1;
621
		}
622

  
623
		if (!s->ssl_use_sslv2) {
624
			/* disable SSLv2 */
625
			if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) {
626
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
627
						ERR_error_string(ERR_get_error(), NULL));
628
				return -1;
629
			}
630
		}
631

  
632
		if (!buffer_is_empty(s->ssl_cipher_list)) {
633
			if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
634
				log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
635
						ERR_error_string(ERR_get_error(), NULL));
636
				return -1;
637
			}
638
		}
639

  
640
		if (!buffer_is_empty(s->ssl_ca_file)) {
641
			if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
642
				log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
643
						ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
644
				return -1;
645
			}
646
		}
647

  
648
		if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
649
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
650
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
651
			return -1;
652
		}
653

  
654
		if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
655
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
656
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
657
			return -1;
658
		}
659

  
660
		if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
661
			log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
662
					"Private key does not match the certificate public key, reason:",
663
					ERR_error_string(ERR_get_error(), NULL),
664
					s->ssl_pemfile);
665
			return -1;
666
		}
667

  
668
#ifndef OPENSSL_NO_TLSEXT
669
		if (!SSL_CTX_set_tlsext_servername_callback(s->ssl_ctx, network_ssl_servername_callback) ||
670
		    !SSL_CTX_set_tlsext_servername_arg(s->ssl_ctx, srv)) {
671
			log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
672
					"failed to initialize TLS servername callback, openssl library does not support TLS servername extension");
673
			return -1;
674
		}
675
#endif
676
	}
677
#endif
678

  
623 679
	b = buffer_init();
624 680

  
625 681
	buffer_copy_string_buffer(b, srv->srvconf.bindhost);
trunk/src/configfile.c (working copy)
294 294
	PATCH(is_ssl);
295 295

  
296 296
	PATCH(ssl_pemfile);
297
	PATCH(ssl_ctx);
297 298
	PATCH(ssl_ca_file);
298 299
	PATCH(ssl_cipher_list);
299 300
	PATCH(ssl_use_sslv2);
......
344 345
				PATCH(use_xattr);
345 346
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.pemfile"))) {
346 347
				PATCH(ssl_pemfile);
348
				PATCH(ssl_ctx);
347 349
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) {
348 350
				PATCH(ssl_ca_file);
349 351
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.engine"))) {
trunk/src/server.c (working copy)
309 309
			buffer_free(s->error_handler);
310 310
			buffer_free(s->errorfile_prefix);
311 311
			array_free(s->mimetypes);
312
#ifdef USE_OPENSSL
313
			SSL_CTX_free(s->ssl_ctx);
314
#endif
312 315

  
313 316
			free(s);
314 317
		}
trunk/src/iosocket.c (working copy)
13 13

  
14 14
	sock->type = IOSOCKET_TYPE_SOCKET;
15 15

  
16
#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
17
	sock->tlsext_server_name = buffer_init();
18
#endif
19

  
16 20
	return sock;
17 21
}
18 22

  
......
32 36
		}
33 37
	}
34 38

  
39
#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
40
	buffer_free(sock->tlsext_server_name);
41
#endif
42

  
35 43
	free(sock);
36 44
}
trunk/src/iosocket.h (working copy)
19 19
#endif
20 20

  
21 21
#include "settings.h"
22
#include "buffer.h"
22 23

  
23 24
typedef enum {
24 25
	IOSOCKET_TYPE_UNSET,
......
35 36

  
36 37
#ifdef USE_OPENSSL
37 38
	SSL *ssl;
39
#ifndef OPENSSL_NO_TLSEXT
40
	buffer *tlsext_server_name;
38 41
#endif
42
#endif
39 43

  
40 44
	iosocket_t type; /**< sendfile on solaris doesn't work on pipes */
41 45
} iosocket;
(5-5/6)