Project

General

Profile

lighttpd_1.5.0_r2022_tls_server_name_indication.patch

TLS server name indication support (lighttpd 1.5.0-svn) - phc, 2007-11-18 13:53

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)
920 920
				return NULL;
921 921
			}
922 922

  
923
#ifndef OPENSSL_NO_TLSEXT
924
			SSL_set_app_data(con->sock->ssl, con);
925
#endif
923 926
			SSL_set_accept_state(con->sock->ssl);
924 927
			con->conf.is_ssl=1;
925 928

  
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 (buffer_is_empty(s->ssl_pemfile)) {
507
		if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) {
490 508
			log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set");
491 509
			return -1;
492 510
		}
493

  
494
		if (!buffer_is_empty(s->ssl_ca_file)) {
495
			if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
496
				log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
497
						ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
498
				return -1;
499
			}
500
		}
501

  
502
		if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
503
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
504
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
505
			return -1;
506
		}
507

  
508
		if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
509
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
510
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
511
			return -1;
512
		}
513

  
514
		if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
515
			log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
516
					"Private key does not match the certificate public key, reason:",
517
					ERR_error_string(ERR_get_error(), NULL),
518
					s->ssl_pemfile);
519
			return -1;
520
		}
521
		srv_socket->ssl_ctx = s->ssl_ctx;
522 511
#else
523 512

  
524 513
		buffer_free(srv_socket->srv_token);
......
577 566
			}
578 567
		}
579 568

  
580
		if (srv_socket->is_ssl) {
581
#ifdef USE_OPENSSL
582
			SSL_CTX_free(srv_socket->ssl_ctx);
583
#endif
584
		}
585

  
586 569
		iosocket_free(srv_socket->sock);
587 570

  
588 571
		buffer_free(srv_socket->srv_token);
......
603 586
	size_t i;
604 587
	const network_backend_info_t *backend;
605 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 (!buffer_is_empty(s->ssl_ca_file)) {
624
			if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
625
				log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
626
						ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
627
				return -1;
628
			}
629
		}
630

  
631
		if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
632
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
633
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
634
			return -1;
635
		}
636

  
637
		if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
638
			log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
639
					ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
640
			return -1;
641
		}
642

  
643
		if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
644
			log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
645
					"Private key does not match the certificate public key, reason:",
646
					ERR_error_string(ERR_get_error(), NULL),
647
					s->ssl_pemfile);
648
			return -1;
649
		}
650

  
651
#ifndef OPENSSL_NO_TLSEXT
652
		if (!SSL_CTX_set_tlsext_servername_callback(s->ssl_ctx, network_ssl_servername_callback) ||
653
		    !SSL_CTX_set_tlsext_servername_arg(s->ssl_ctx, srv)) {
654
			log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
655
					"failed to initialize TLS servername callback, openssl library does not support TLS servername extension");
656
			return -1;
657
		}
658
#endif
659
	}
660
#endif
661

  
606 662
	b = buffer_init();
607 663

  
608 664
	buffer_copy_string_buffer(b, srv->srvconf.bindhost);
trunk/src/configfile.c (working copy)
288 288
	PATCH(is_ssl);
289 289

  
290 290
	PATCH(ssl_pemfile);
291
	PATCH(ssl_ctx);
291 292
	PATCH(ssl_ca_file);
292 293
	return 0;
293 294
}
......
336 337
				PATCH(use_xattr);
337 338
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.pemfile"))) {
338 339
				PATCH(ssl_pemfile);
340
				PATCH(ssl_ctx);
339 341
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) {
340 342
				PATCH(ssl_ca_file);
341 343
			} 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;