Browse Source

[tls] Add support for Server Name Indication (SNI)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
b7f8d1bbfd
4 changed files with 39 additions and 5 deletions
  1. 1
    0
      src/include/ipxe/http.h
  2. 7
    1
      src/include/ipxe/tls.h
  3. 2
    1
      src/net/tcp/httpcore.c
  4. 29
    3
      src/net/tls.c

+ 1
- 0
src/include/ipxe/http.h View File

@@ -18,6 +18,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
18 18
 extern int http_open_filter ( struct interface *xfer, struct uri *uri,
19 19
 			      unsigned int default_port,
20 20
 			      int ( * filter ) ( struct interface *,
21
+						 const char *,
21 22
 						 struct interface ** ) );
22 23
 
23 24
 #endif /* _IPXE_HTTP_H */

+ 7
- 1
src/include/ipxe/tls.h View File

@@ -74,6 +74,10 @@ struct tls_header {
74 74
 #define TLS_RSA_WITH_AES_128_CBC_SHA 0x002f
75 75
 #define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
76 76
 
77
+/* TLS extension types */
78
+#define TLS_SERVER_NAME 0
79
+#define TLS_SERVER_NAME_HOST_NAME 0
80
+
77 81
 /** TLS RX state machine state */
78 82
 enum tls_rx_state {
79 83
 	TLS_RX_HEADER = 0,
@@ -133,6 +137,8 @@ struct tls_session {
133 137
 	/** Reference counter */
134 138
 	struct refcnt refcnt;
135 139
 
140
+	/** Server name */
141
+	const char *name;
136 142
 	/** Plaintext stream */
137 143
 	struct interface plainstream;
138 144
 	/** Ciphertext stream */
@@ -183,7 +189,7 @@ struct tls_session {
183 189
 	void *rx_data;
184 190
 };
185 191
 
186
-extern int add_tls ( struct interface *xfer,
192
+extern int add_tls ( struct interface *xfer, const char *name,
187 193
 		     struct interface **next );
188 194
 
189 195
 #endif /* _IPXE_TLS_H */

+ 2
- 1
src/net/tcp/httpcore.c View File

@@ -838,6 +838,7 @@ static struct process_descriptor http_process_desc =
838 838
 int http_open_filter ( struct interface *xfer, struct uri *uri,
839 839
 		       unsigned int default_port,
840 840
 		       int ( * filter ) ( struct interface *xfer,
841
+					  const char *name,
841 842
 					  struct interface **next ) ) {
842 843
 	struct http_request *http;
843 844
 	struct sockaddr_tcpip server;
@@ -865,7 +866,7 @@ int http_open_filter ( struct interface *xfer, struct uri *uri,
865 866
 	server.st_port = htons ( uri_port ( http->uri, default_port ) );
866 867
 	socket = &http->socket;
867 868
 	if ( filter ) {
868
-		if ( ( rc = filter ( socket, &socket ) ) != 0 )
869
+		if ( ( rc = filter ( socket, uri->host, &socket ) ) != 0 )
869 870
 			goto err;
870 871
 	}
871 872
 	if ( ( rc = xfer_open_named_socket ( socket, SOCK_STREAM,

+ 29
- 3
src/net/tls.c View File

@@ -691,6 +691,19 @@ static int tls_send_client_hello ( struct tls_session *tls ) {
691 691
 		uint16_t cipher_suites[2];
692 692
 		uint8_t compression_methods_len;
693 693
 		uint8_t compression_methods[1];
694
+		uint16_t extensions_len;
695
+		struct {
696
+			uint16_t server_name_type;
697
+			uint16_t server_name_len;
698
+			struct {
699
+				uint16_t len;
700
+				struct {
701
+					uint8_t type;
702
+					uint16_t len;
703
+					uint8_t name[ strlen ( tls->name ) ];
704
+				} __attribute__ (( packed )) list[1];
705
+			} __attribute__ (( packed )) server_name;
706
+		} __attribute__ (( packed )) extensions;
694 707
 	} __attribute__ (( packed )) hello;
695 708
 
696 709
 	memset ( &hello, 0, sizeof ( hello ) );
@@ -703,6 +716,17 @@ static int tls_send_client_hello ( struct tls_session *tls ) {
703 716
 	hello.cipher_suites[0] = htons ( TLS_RSA_WITH_AES_128_CBC_SHA );
704 717
 	hello.cipher_suites[1] = htons ( TLS_RSA_WITH_AES_256_CBC_SHA );
705 718
 	hello.compression_methods_len = sizeof ( hello.compression_methods );
719
+	hello.extensions_len = htons ( sizeof ( hello.extensions ) );
720
+	hello.extensions.server_name_type = htons ( TLS_SERVER_NAME );
721
+	hello.extensions.server_name_len
722
+		= htons ( sizeof ( hello.extensions.server_name ) );
723
+	hello.extensions.server_name.len
724
+		= htons ( sizeof ( hello.extensions.server_name.list ) );
725
+	hello.extensions.server_name.list[0].type = TLS_SERVER_NAME_HOST_NAME;
726
+	hello.extensions.server_name.list[0].len
727
+		= htons ( sizeof ( hello.extensions.server_name.list[0].name ));
728
+	memcpy ( hello.extensions.server_name.list[0].name, tls->name,
729
+		 sizeof ( hello.extensions.server_name.list[0].name ) );
706 730
 
707 731
 	return tls_send_handshake ( tls, &hello, sizeof ( hello ) );
708 732
 }
@@ -881,8 +905,8 @@ static int tls_new_server_hello ( struct tls_session *tls,
881 905
 	int rc;
882 906
 
883 907
 	/* Sanity check */
884
-	if ( end != ( data + len ) ) {
885
-		DBGC ( tls, "TLS %p received overlength Server Hello\n", tls );
908
+	if ( end > ( data + len ) ) {
909
+		DBGC ( tls, "TLS %p received underlength Server Hello\n", tls );
886 910
 		DBGC_HD ( tls, data, len );
887 911
 		return -EINVAL;
888 912
 	}
@@ -1805,7 +1829,8 @@ static struct process_descriptor tls_process_desc =
1805 1829
  ******************************************************************************
1806 1830
  */
1807 1831
 
1808
-int add_tls ( struct interface *xfer, struct interface **next ) {
1832
+int add_tls ( struct interface *xfer, const char *name,
1833
+	      struct interface **next ) {
1809 1834
 	struct tls_session *tls;
1810 1835
 	int rc;
1811 1836
 
@@ -1817,6 +1842,7 @@ int add_tls ( struct interface *xfer, struct interface **next ) {
1817 1842
 	}
1818 1843
 	memset ( tls, 0, sizeof ( *tls ) );
1819 1844
 	ref_init ( &tls->refcnt, free_tls );
1845
+	tls->name = name;
1820 1846
 	intf_init ( &tls->plainstream, &tls_plainstream_desc, &tls->refcnt );
1821 1847
 	intf_init ( &tls->cipherstream, &tls_cipherstream_desc, &tls->refcnt );
1822 1848
 	tls->version = TLS_VERSION_TLS_1_1;

Loading…
Cancel
Save