summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libssl/Makefile4
-rw-r--r--src/lib/libssl/ssl_tlsext.c261
-rw-r--r--src/lib/libssl/ssl_tlsext.h31
-rw-r--r--src/lib/libssl/t1_lib.c173
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
37SRCS+= s3_cbc.c 37SRCS+= s3_cbc.c
38SRCS+= bs_ber.c bs_cbb.c bs_cbs.c 38SRCS+= 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 */
26int
27tlsext_sni_clienthello_needs(SSL *s)
28{
29 return (s->tlsext_hostname != NULL);
30}
31
32int
33tlsext_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
52int
53tlsext_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
110int
111tlsext_sni_serverhello_needs(SSL *s)
112{
113 return (s->session->tlsext_hostname != NULL);
114}
115
116int
117tlsext_sni_serverhello_build(SSL *s, CBB *cbb)
118{
119 return 1;
120}
121
122int
123tlsext_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
133struct 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
143static 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
157int
158tlsext_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
185int
186tlsext_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
210int
211tlsext_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
238int
239tlsext_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
18int tlsext_sni_clienthello_needs(SSL *s);
19int tlsext_sni_clienthello_build(SSL *s, CBB *cbb);
20int tlsext_sni_clienthello_parse(SSL *s, CBS *cbs, int *alert);
21int tlsext_sni_serverhello_needs(SSL *s);
22int tlsext_sni_serverhello_build(SSL *s, CBB *cbb);
23int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert);
24
25int tlsext_clienthello_build(SSL *s, CBB *cbb);
26int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type,
27 int *alert);
28
29int tlsext_serverhello_build(SSL *s, CBB *cbb);
30int 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
122static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, 124static 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;