diff options
author | jsing <> | 2017-07-16 18:14:37 +0000 |
---|---|---|
committer | jsing <> | 2017-07-16 18:14:37 +0000 |
commit | 231770c97badca4c3da92986469ccbd7bf13471d (patch) | |
tree | d9fc4f0686256f704a616fd78164deb16cbfba14 | |
parent | 78c8f5de9ccfc2a6133cb7cb00d67a257d2d4f46 (diff) | |
download | openbsd-231770c97badca4c3da92986469ccbd7bf13471d.tar.gz openbsd-231770c97badca4c3da92986469ccbd7bf13471d.tar.bz2 openbsd-231770c97badca4c3da92986469ccbd7bf13471d.zip |
Start rewriting TLS extension handling.
Introduce a TLS extension handling framework that has per-extension type
functions to determine if an extension is needed, to build the extension
data and parse the extension data. This is somewhat analogous to BoringSSL,
however these build and parse functions are intentionally symetrical. The
framework is hooked into the existing TLS handling code in such a way that
we can gradual convert the extension handling code.
Convert the TLS Server Name Indication extension to the new framework,
while rewriting it to use CBB/CBS and be more strict in the process.
Discussed with beck@
ok inoguchi@
-rw-r--r-- | src/lib/libssl/Makefile | 4 | ||||
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 261 | ||||
-rw-r--r-- | src/lib/libssl/ssl_tlsext.h | 31 | ||||
-rw-r--r-- | src/lib/libssl/t1_lib.c | 173 |
4 files changed, 328 insertions, 141 deletions
diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile index 809851d251..f004507060 100644 --- a/src/lib/libssl/Makefile +++ b/src/lib/libssl/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.35 2017/04/30 04:44:58 jsing Exp $ | 1 | # $OpenBSD: Makefile,v 1.36 2017/07/16 18:14:37 jsing Exp $ |
2 | 2 | ||
3 | .include <bsd.own.mk> | 3 | .include <bsd.own.mk> |
4 | .ifndef NOMAN | 4 | .ifndef NOMAN |
@@ -33,7 +33,7 @@ SRCS= \ | |||
33 | ssl_ciph.c ssl_stat.c ssl_rsa.c \ | 33 | ssl_ciph.c ssl_stat.c ssl_rsa.c \ |
34 | ssl_asn1.c ssl_txt.c ssl_algs.c \ | 34 | ssl_asn1.c ssl_txt.c ssl_algs.c \ |
35 | bio_ssl.c ssl_err.c t1_reneg.c \ | 35 | bio_ssl.c ssl_err.c t1_reneg.c \ |
36 | ssl_packet.c ssl_versions.c pqueue.c | 36 | ssl_packet.c ssl_tlsext.c ssl_versions.c pqueue.c |
37 | SRCS+= s3_cbc.c | 37 | SRCS+= s3_cbc.c |
38 | SRCS+= bs_ber.c bs_cbb.c bs_cbs.c | 38 | SRCS+= bs_ber.c bs_cbb.c bs_cbs.c |
39 | 39 | ||
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c new file mode 100644 index 0000000000..18ac98103a --- /dev/null +++ b/src/lib/libssl/ssl_tlsext.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* $OpenBSD: ssl_tlsext.c,v 1.1 2017/07/16 18:14:37 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include "ssl_locl.h" | ||
19 | |||
20 | #include "bytestring.h" | ||
21 | #include "ssl_tlsext.h" | ||
22 | |||
23 | /* | ||
24 | * Server Name Indication - RFC 6066, section 3. | ||
25 | */ | ||
26 | int | ||
27 | tlsext_sni_clienthello_needs(SSL *s) | ||
28 | { | ||
29 | return (s->tlsext_hostname != NULL); | ||
30 | } | ||
31 | |||
32 | int | ||
33 | tlsext_sni_clienthello_build(SSL *s, CBB *cbb) | ||
34 | { | ||
35 | CBB server_name_list, host_name; | ||
36 | |||
37 | if (!CBB_add_u16_length_prefixed(cbb, &server_name_list)) | ||
38 | return 0; | ||
39 | if (!CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name)) | ||
40 | return 0; | ||
41 | if (!CBB_add_u16_length_prefixed(&server_name_list, &host_name)) | ||
42 | return 0; | ||
43 | if (!CBB_add_bytes(&host_name, (const uint8_t *)s->tlsext_hostname, | ||
44 | strlen(s->tlsext_hostname))) | ||
45 | return 0; | ||
46 | if (!CBB_flush(cbb)) | ||
47 | return 0; | ||
48 | |||
49 | return 1; | ||
50 | } | ||
51 | |||
52 | int | ||
53 | tlsext_sni_clienthello_parse(SSL *s, CBS *cbs, int *alert) | ||
54 | { | ||
55 | CBS server_name_list, host_name; | ||
56 | uint8_t name_type; | ||
57 | |||
58 | if (!CBS_get_u16_length_prefixed(cbs, &server_name_list)) | ||
59 | goto err; | ||
60 | |||
61 | /* | ||
62 | * RFC 6066 section 3 forbids multiple host names with the same type. | ||
63 | * Additionally, only one type (host_name) is specified. | ||
64 | */ | ||
65 | if (!CBS_get_u8(&server_name_list, &name_type)) | ||
66 | goto err; | ||
67 | if (name_type != TLSEXT_NAMETYPE_host_name) | ||
68 | goto err; | ||
69 | |||
70 | if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name)) | ||
71 | goto err; | ||
72 | if (CBS_len(&host_name) == 0 || | ||
73 | CBS_len(&host_name) > TLSEXT_MAXLEN_host_name || | ||
74 | CBS_contains_zero_byte(&host_name)) { | ||
75 | *alert = TLS1_AD_UNRECOGNIZED_NAME; | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | if (s->internal->hit) { | ||
80 | if (s->session->tlsext_hostname == NULL) { | ||
81 | *alert = TLS1_AD_UNRECOGNIZED_NAME; | ||
82 | return 0; | ||
83 | } | ||
84 | if (!CBS_mem_equal(&host_name, s->session->tlsext_hostname, | ||
85 | strlen(s->session->tlsext_hostname))) { | ||
86 | *alert = TLS1_AD_UNRECOGNIZED_NAME; | ||
87 | return 0; | ||
88 | } | ||
89 | } else { | ||
90 | if (s->session->tlsext_hostname != NULL) | ||
91 | goto err; | ||
92 | if (!CBS_strdup(&host_name, &s->session->tlsext_hostname)) { | ||
93 | *alert = TLS1_AD_INTERNAL_ERROR; | ||
94 | return 0; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | if (CBS_len(&server_name_list) != 0) | ||
99 | goto err; | ||
100 | if (CBS_len(cbs) != 0) | ||
101 | goto err; | ||
102 | |||
103 | return 1; | ||
104 | |||
105 | err: | ||
106 | *alert = SSL_AD_DECODE_ERROR; | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | int | ||
111 | tlsext_sni_serverhello_needs(SSL *s) | ||
112 | { | ||
113 | return (s->session->tlsext_hostname != NULL); | ||
114 | } | ||
115 | |||
116 | int | ||
117 | tlsext_sni_serverhello_build(SSL *s, CBB *cbb) | ||
118 | { | ||
119 | return 1; | ||
120 | } | ||
121 | |||
122 | int | ||
123 | tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert) | ||
124 | { | ||
125 | if (s->tlsext_hostname == NULL || CBS_len(cbs) != 0) { | ||
126 | *alert = TLS1_AD_UNRECOGNIZED_NAME; | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | return 1; | ||
131 | } | ||
132 | |||
133 | struct tls_extension { | ||
134 | uint16_t type; | ||
135 | int (*clienthello_needs)(SSL *s); | ||
136 | int (*clienthello_build)(SSL *s, CBB *cbb); | ||
137 | int (*clienthello_parse)(SSL *s, CBS *cbs, int *alert); | ||
138 | int (*serverhello_needs)(SSL *s); | ||
139 | int (*serverhello_build)(SSL *s, CBB *cbb); | ||
140 | int (*serverhello_parse)(SSL *s, CBS *cbs, int *alert); | ||
141 | }; | ||
142 | |||
143 | static struct tls_extension tls_extensions[] = { | ||
144 | { | ||
145 | .type = TLSEXT_TYPE_server_name, | ||
146 | .clienthello_needs = tlsext_sni_clienthello_needs, | ||
147 | .clienthello_build = tlsext_sni_clienthello_build, | ||
148 | .clienthello_parse = tlsext_sni_clienthello_parse, | ||
149 | .serverhello_needs = tlsext_sni_serverhello_needs, | ||
150 | .serverhello_build = tlsext_sni_serverhello_build, | ||
151 | .serverhello_parse = tlsext_sni_serverhello_parse, | ||
152 | }, | ||
153 | }; | ||
154 | |||
155 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) | ||
156 | |||
157 | int | ||
158 | tlsext_clienthello_build(SSL *s, CBB *cbb) | ||
159 | { | ||
160 | struct tls_extension *tlsext; | ||
161 | CBB extension_data; | ||
162 | size_t i; | ||
163 | |||
164 | memset(&extension_data, 0, sizeof(extension_data)); | ||
165 | |||
166 | for (i = 0; i < N_TLS_EXTENSIONS; i++) { | ||
167 | tlsext = &tls_extensions[i]; | ||
168 | |||
169 | if (!tlsext->clienthello_needs(s)) | ||
170 | continue; | ||
171 | |||
172 | if (!CBB_add_u16(cbb, tlsext->type)) | ||
173 | return 0; | ||
174 | if (!CBB_add_u16_length_prefixed(cbb, &extension_data)) | ||
175 | return 0; | ||
176 | if (!tls_extensions[i].clienthello_build(s, &extension_data)) | ||
177 | return 0; | ||
178 | if (!CBB_flush(cbb)) | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | return 1; | ||
183 | } | ||
184 | |||
185 | int | ||
186 | tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert) | ||
187 | { | ||
188 | struct tls_extension *tlsext; | ||
189 | size_t i; | ||
190 | |||
191 | for (i = 0; i < N_TLS_EXTENSIONS; i++) { | ||
192 | tlsext = &tls_extensions[i]; | ||
193 | |||
194 | if (tlsext->type != type) | ||
195 | continue; | ||
196 | if (!tlsext->clienthello_parse(s, cbs, alert)) | ||
197 | return 0; | ||
198 | if (CBS_len(cbs) != 0) { | ||
199 | *alert = SSL_AD_DECODE_ERROR; | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | return 1; | ||
204 | } | ||
205 | |||
206 | /* Not found. */ | ||
207 | return 2; | ||
208 | } | ||
209 | |||
210 | int | ||
211 | tlsext_serverhello_build(SSL *s, CBB *cbb) | ||
212 | { | ||
213 | struct tls_extension *tlsext; | ||
214 | CBB extension_data; | ||
215 | size_t i; | ||
216 | |||
217 | memset(&extension_data, 0, sizeof(extension_data)); | ||
218 | |||
219 | for (i = 0; i < N_TLS_EXTENSIONS; i++) { | ||
220 | tlsext = &tls_extensions[i]; | ||
221 | |||
222 | if (!tlsext->serverhello_needs(s)) | ||
223 | continue; | ||
224 | |||
225 | if (!CBB_add_u16(cbb, tlsext->type)) | ||
226 | return 0; | ||
227 | if (!CBB_add_u16_length_prefixed(cbb, &extension_data)) | ||
228 | return 0; | ||
229 | if (!tlsext->serverhello_build(s, &extension_data)) | ||
230 | return 0; | ||
231 | if (!CBB_flush(cbb)) | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | return 1; | ||
236 | } | ||
237 | |||
238 | int | ||
239 | tlsext_serverhello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert) | ||
240 | { | ||
241 | struct tls_extension *tlsext; | ||
242 | size_t i; | ||
243 | |||
244 | for (i = 0; i < N_TLS_EXTENSIONS; i++) { | ||
245 | tlsext = &tls_extensions[i]; | ||
246 | |||
247 | if (tlsext->type != type) | ||
248 | continue; | ||
249 | if (!tlsext->serverhello_parse(s, cbs, alert)) | ||
250 | return 0; | ||
251 | if (CBS_len(cbs) != 0) { | ||
252 | *alert = SSL_AD_DECODE_ERROR; | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | return 1; | ||
257 | } | ||
258 | |||
259 | /* Not found. */ | ||
260 | return 2; | ||
261 | } | ||
diff --git a/src/lib/libssl/ssl_tlsext.h b/src/lib/libssl/ssl_tlsext.h new file mode 100644 index 0000000000..a8e478d9c0 --- /dev/null +++ b/src/lib/libssl/ssl_tlsext.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* $OpenBSD: ssl_tlsext.h,v 1.1 2017/07/16 18:14:37 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | int tlsext_sni_clienthello_needs(SSL *s); | ||
19 | int tlsext_sni_clienthello_build(SSL *s, CBB *cbb); | ||
20 | int tlsext_sni_clienthello_parse(SSL *s, CBS *cbs, int *alert); | ||
21 | int tlsext_sni_serverhello_needs(SSL *s); | ||
22 | int tlsext_sni_serverhello_build(SSL *s, CBB *cbb); | ||
23 | int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert); | ||
24 | |||
25 | int tlsext_clienthello_build(SSL *s, CBB *cbb); | ||
26 | int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, | ||
27 | int *alert); | ||
28 | |||
29 | int tlsext_serverhello_build(SSL *s, CBB *cbb); | ||
30 | int tlsext_serverhello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, | ||
31 | int *alert); | ||
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index eb2314ac26..e3046fec09 100644 --- a/src/lib/libssl/t1_lib.c +++ b/src/lib/libssl/t1_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_lib.c,v 1.117 2017/05/07 04:22:24 beck Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.118 2017/07/16 18:14:37 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -117,7 +117,9 @@ | |||
117 | #include <openssl/ocsp.h> | 117 | #include <openssl/ocsp.h> |
118 | 118 | ||
119 | #include "ssl_locl.h" | 119 | #include "ssl_locl.h" |
120 | |||
120 | #include "bytestring.h" | 121 | #include "bytestring.h" |
122 | #include "ssl_tlsext.h" | ||
121 | 123 | ||
122 | static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, | 124 | static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, |
123 | const unsigned char *sess_id, int sesslen, | 125 | const unsigned char *sess_id, int sesslen, |
@@ -678,6 +680,8 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
678 | int extdatalen = 0; | 680 | int extdatalen = 0; |
679 | unsigned char *ret = p; | 681 | unsigned char *ret = p; |
680 | int using_ecc = 0; | 682 | int using_ecc = 0; |
683 | size_t len; | ||
684 | CBB cbb; | ||
681 | 685 | ||
682 | /* See if we support any ECC ciphersuites. */ | 686 | /* See if we support any ECC ciphersuites. */ |
683 | if (s->version != DTLS1_VERSION && s->version >= TLS1_VERSION) { | 687 | if (s->version != DTLS1_VERSION && s->version >= TLS1_VERSION) { |
@@ -699,43 +703,21 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
699 | } | 703 | } |
700 | 704 | ||
701 | ret += 2; | 705 | ret += 2; |
702 | |||
703 | if (ret >= limit) | 706 | if (ret >= limit) |
704 | return NULL; /* this really never occurs, but ... */ | 707 | return NULL; /* this really never occurs, but ... */ |
705 | 708 | ||
706 | if (s->tlsext_hostname != NULL) { | 709 | CBB_init_fixed(&cbb, ret, limit - ret); |
707 | /* Add TLS extension servername to the Client Hello message */ | 710 | if (!tlsext_clienthello_build(s, &cbb)) { |
708 | size_t size_str, lenmax; | 711 | CBB_cleanup(&cbb); |
709 | 712 | return NULL; | |
710 | /* check for enough space. | 713 | } |
711 | 4 for the servername type and extension length | 714 | if (!CBB_finish(&cbb, NULL, &len)) { |
712 | 2 for servernamelist length | 715 | CBB_cleanup(&cbb); |
713 | 1 for the hostname type | 716 | return NULL; |
714 | 2 for hostname length | ||
715 | + hostname length | ||
716 | */ | ||
717 | |||
718 | if ((size_t)(limit - ret) < 9) | ||
719 | return NULL; | ||
720 | |||
721 | lenmax = limit - ret - 9; | ||
722 | if ((size_str = strlen(s->tlsext_hostname)) > lenmax) | ||
723 | return NULL; | ||
724 | |||
725 | /* extension type and length */ | ||
726 | s2n(TLSEXT_TYPE_server_name, ret); | ||
727 | |||
728 | s2n(size_str + 5, ret); | ||
729 | |||
730 | /* length of servername list */ | ||
731 | s2n(size_str + 3, ret); | ||
732 | |||
733 | /* hostname type, length and hostname */ | ||
734 | *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name; | ||
735 | s2n(size_str, ret); | ||
736 | memcpy(ret, s->tlsext_hostname, size_str); | ||
737 | ret += size_str; | ||
738 | } | 717 | } |
718 | if (len > (limit - ret)) | ||
719 | return NULL; | ||
720 | ret += len; | ||
739 | 721 | ||
740 | /* Add RI if renegotiating */ | 722 | /* Add RI if renegotiating */ |
741 | if (s->internal->renegotiate) { | 723 | if (s->internal->renegotiate) { |
@@ -997,6 +979,8 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
997 | unsigned long alg_a, alg_k; | 979 | unsigned long alg_a, alg_k; |
998 | unsigned char *ret = p; | 980 | unsigned char *ret = p; |
999 | int next_proto_neg_seen; | 981 | int next_proto_neg_seen; |
982 | size_t len; | ||
983 | CBB cbb; | ||
1000 | 984 | ||
1001 | alg_a = S3I(s)->hs.new_cipher->algorithm_auth; | 985 | alg_a = S3I(s)->hs.new_cipher->algorithm_auth; |
1002 | alg_k = S3I(s)->hs.new_cipher->algorithm_mkey; | 986 | alg_k = S3I(s)->hs.new_cipher->algorithm_mkey; |
@@ -1007,14 +991,18 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
1007 | if (ret >= limit) | 991 | if (ret >= limit) |
1008 | return NULL; /* this really never occurs, but ... */ | 992 | return NULL; /* this really never occurs, but ... */ |
1009 | 993 | ||
1010 | if (!s->internal->hit && s->internal->servername_done == 1 && | 994 | CBB_init_fixed(&cbb, ret, limit - ret); |
1011 | s->session->tlsext_hostname != NULL) { | 995 | if (!tlsext_serverhello_build(s, &cbb)) { |
1012 | if ((size_t)(limit - ret) < 4) | 996 | CBB_cleanup(&cbb); |
1013 | return NULL; | 997 | return NULL; |
1014 | |||
1015 | s2n(TLSEXT_TYPE_server_name, ret); | ||
1016 | s2n(0, ret); | ||
1017 | } | 998 | } |
999 | if (!CBB_finish(&cbb, NULL, &len)) { | ||
1000 | CBB_cleanup(&cbb); | ||
1001 | return NULL; | ||
1002 | } | ||
1003 | if (len > (limit - ret)) | ||
1004 | return NULL; | ||
1005 | ret += len; | ||
1018 | 1006 | ||
1019 | if (S3I(s)->send_connection_binding) { | 1007 | if (S3I(s)->send_connection_binding) { |
1020 | int el; | 1008 | int el; |
@@ -1241,6 +1229,7 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1241 | unsigned char *end = d + n; | 1229 | unsigned char *end = d + n; |
1242 | int renegotiate_seen = 0; | 1230 | int renegotiate_seen = 0; |
1243 | int sigalg_seen = 0; | 1231 | int sigalg_seen = 0; |
1232 | CBS cbs; | ||
1244 | 1233 | ||
1245 | s->internal->servername_done = 0; | 1234 | s->internal->servername_done = 0; |
1246 | s->tlsext_status_type = -1; | 1235 | s->tlsext_status_type = -1; |
@@ -1269,106 +1258,12 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
1269 | if (s->internal->tlsext_debug_cb) | 1258 | if (s->internal->tlsext_debug_cb) |
1270 | s->internal->tlsext_debug_cb(s, 0, type, data, size, | 1259 | s->internal->tlsext_debug_cb(s, 0, type, data, size, |
1271 | s->internal->tlsext_debug_arg); | 1260 | s->internal->tlsext_debug_arg); |
1272 | /* The servername extension is treated as follows: | ||
1273 | |||
1274 | - Only the hostname type is supported with a maximum length of 255. | ||
1275 | - The servername is rejected if too long or if it contains zeros, | ||
1276 | in which case an fatal alert is generated. | ||
1277 | - The servername field is maintained together with the session cache. | ||
1278 | - When a session is resumed, the servername call back invoked in order | ||
1279 | to allow the application to position itself to the right context. | ||
1280 | - The servername is acknowledged if it is new for a session or when | ||
1281 | it is identical to a previously used for the same session. | ||
1282 | Applications can control the behaviour. They can at any time | ||
1283 | set a 'desirable' servername for a new SSL object. This can be the | ||
1284 | case for example with HTTPS when a Host: header field is received and | ||
1285 | a renegotiation is requested. In this case, a possible servername | ||
1286 | presented in the new client hello is only acknowledged if it matches | ||
1287 | the value of the Host: field. | ||
1288 | - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | ||
1289 | if they provide for changing an explicit servername context for the session, | ||
1290 | i.e. when the session has been established with a servername extension. | ||
1291 | - On session reconnect, the servername extension may be absent. | ||
1292 | |||
1293 | */ | ||
1294 | |||
1295 | if (type == TLSEXT_TYPE_server_name) { | ||
1296 | unsigned char *sdata; | ||
1297 | int servname_type; | ||
1298 | int dsize; | ||
1299 | 1261 | ||
1300 | if (size < 2) { | 1262 | CBS_init(&cbs, data, size); |
1301 | *al = SSL_AD_DECODE_ERROR; | 1263 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) |
1302 | return 0; | 1264 | return 0; |
1303 | } | ||
1304 | n2s(data, dsize); | ||
1305 | |||
1306 | size -= 2; | ||
1307 | if (dsize > size) { | ||
1308 | *al = SSL_AD_DECODE_ERROR; | ||
1309 | return 0; | ||
1310 | } | ||
1311 | |||
1312 | sdata = data; | ||
1313 | while (dsize > 3) { | ||
1314 | servname_type = *(sdata++); | ||
1315 | |||
1316 | n2s(sdata, len); | ||
1317 | dsize -= 3; | ||
1318 | |||
1319 | if (len > dsize) { | ||
1320 | *al = SSL_AD_DECODE_ERROR; | ||
1321 | return 0; | ||
1322 | } | ||
1323 | if (s->internal->servername_done == 0) | ||
1324 | switch (servname_type) { | ||
1325 | case TLSEXT_NAMETYPE_host_name: | ||
1326 | if (!s->internal->hit) { | ||
1327 | if (s->session->tlsext_hostname) { | ||
1328 | *al = SSL_AD_DECODE_ERROR; | ||
1329 | return 0; | ||
1330 | } | ||
1331 | if (len > TLSEXT_MAXLEN_host_name) { | ||
1332 | *al = TLS1_AD_UNRECOGNIZED_NAME; | ||
1333 | return 0; | ||
1334 | } | ||
1335 | if ((s->session->tlsext_hostname = | ||
1336 | malloc(len + 1)) == NULL) { | ||
1337 | *al = TLS1_AD_INTERNAL_ERROR; | ||
1338 | return 0; | ||
1339 | } | ||
1340 | memcpy(s->session->tlsext_hostname, sdata, len); | ||
1341 | s->session->tlsext_hostname[len] = '\0'; | ||
1342 | if (strlen(s->session->tlsext_hostname) != len) { | ||
1343 | free(s->session->tlsext_hostname); | ||
1344 | s->session->tlsext_hostname = NULL; | ||
1345 | *al = TLS1_AD_UNRECOGNIZED_NAME; | ||
1346 | return 0; | ||
1347 | } | ||
1348 | s->internal->servername_done = 1; | ||
1349 | |||
1350 | |||
1351 | } else { | ||
1352 | s->internal->servername_done = s->session->tlsext_hostname && | ||
1353 | strlen(s->session->tlsext_hostname) == len && | ||
1354 | strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0; | ||
1355 | } | ||
1356 | break; | ||
1357 | |||
1358 | default: | ||
1359 | break; | ||
1360 | } | ||
1361 | |||
1362 | dsize -= len; | ||
1363 | } | ||
1364 | if (dsize != 0) { | ||
1365 | *al = SSL_AD_DECODE_ERROR; | ||
1366 | return 0; | ||
1367 | } | ||
1368 | |||
1369 | } | ||
1370 | 1265 | ||
1371 | else if (type == TLSEXT_TYPE_ec_point_formats && | 1266 | if (type == TLSEXT_TYPE_ec_point_formats && |
1372 | s->version != DTLS1_VERSION) { | 1267 | s->version != DTLS1_VERSION) { |
1373 | unsigned char *sdata = data; | 1268 | unsigned char *sdata = data; |
1374 | size_t formatslen; | 1269 | size_t formatslen; |