summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2018-01-27 15:30:05 +0000
committerjsing <>2018-01-27 15:30:05 +0000
commit7e9d176210d3d878a8e83ab3e422f4bf370711e6 (patch)
tree3d53d5ec7c827462ec31ee3156e980e4c951418a /src
parentcccafe604becdfd2326c3f4d1c5664d824934cb4 (diff)
downloadopenbsd-7e9d176210d3d878a8e83ab3e422f4bf370711e6.tar.gz
openbsd-7e9d176210d3d878a8e83ab3e422f4bf370711e6.tar.bz2
openbsd-7e9d176210d3d878a8e83ab3e422f4bf370711e6.zip
Complete the TLS extension handling rewrite for the server-side.
This removes ssl_parse_clienthello_tlsext() and allows the CBS to be passed all the way through from ssl3_get_client_hello(). The renegotation check gets pulled up into ssl3_get_client_hello() which is where other such checks exist. The TLS extension parsing now also ensures that we do not get duplicates of any known extensions (the old pre-rewrite code only did this for some extensions). ok inoguchi@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libssl/ssl_locl.h7
-rw-r--r--src/lib/libssl/ssl_srvr.c19
-rw-r--r--src/lib/libssl/ssl_tlsext.c82
-rw-r--r--src/lib/libssl/ssl_tlsext.h5
-rw-r--r--src/lib/libssl/t1_lib.c71
5 files changed, 86 insertions, 98 deletions
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index f6e922e99c..d2a99afaa4 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.201 2017/10/12 16:06:32 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.202 2018/01/27 15:30:05 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 *
@@ -164,6 +164,9 @@
164 164
165__BEGIN_HIDDEN_DECLS 165__BEGIN_HIDDEN_DECLS
166 166
167#define CTASSERT(x) extern char _ctassert[(x) ? 1 : -1 ] \
168 __attribute__((__unused__))
169
167#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ 170#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
168 *((c)++)=(unsigned char)(((l)>>16)&0xff), \ 171 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
169 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ 172 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
@@ -1275,8 +1278,6 @@ uint16_t tls1_ec_nid2curve_id(const int nid);
1275int tls1_check_curve(SSL *s, const uint16_t curve_id); 1278int tls1_check_curve(SSL *s, const uint16_t curve_id);
1276int tls1_get_shared_curve(SSL *s); 1279int tls1_get_shared_curve(SSL *s);
1277 1280
1278int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data,
1279 unsigned char *d, int n, int *al);
1280int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, 1281int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data,
1281 size_t n, int *al); 1282 size_t n, int *al);
1282int ssl_check_clienthello_tlsext_early(SSL *s); 1283int ssl_check_clienthello_tlsext_early(SSL *s);
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c
index 5d741cdc81..6450623d4a 100644
--- a/src/lib/libssl/ssl_srvr.c
+++ b/src/lib/libssl/ssl_srvr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_srvr.c,v 1.26 2017/10/12 15:52:50 jsing Exp $ */ 1/* $OpenBSD: ssl_srvr.c,v 1.27 2018/01/27 15:30:05 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 *
@@ -813,7 +813,6 @@ ssl3_get_client_hello(SSL *s)
813 int i, j, ok, al, ret = -1, cookie_valid = 0; 813 int i, j, ok, al, ret = -1, cookie_valid = 0;
814 long n; 814 long n;
815 unsigned long id; 815 unsigned long id;
816 unsigned char *p, *d;
817 SSL_CIPHER *c; 816 SSL_CIPHER *c;
818 STACK_OF(SSL_CIPHER) *ciphers = NULL; 817 STACK_OF(SSL_CIPHER) *ciphers = NULL;
819 unsigned long alg_k; 818 unsigned long alg_k;
@@ -843,8 +842,7 @@ ssl3_get_client_hello(SSL *s)
843 if (n < 0) 842 if (n < 0)
844 goto err; 843 goto err;
845 844
846 d = p = (unsigned char *)s->internal->init_msg; 845 end = (unsigned char *)s->internal->init_msg + n;
847 end = d + n;
848 846
849 CBS_init(&cbs, s->internal->init_msg, n); 847 CBS_init(&cbs, s->internal->init_msg, n);
850 848
@@ -1038,14 +1036,17 @@ ssl3_get_client_hello(SSL *s)
1038 goto f_err; 1036 goto f_err;
1039 } 1037 }
1040 1038
1041 p = (unsigned char *)CBS_data(&cbs); 1039 if (!tlsext_clienthello_parse(s, &cbs, &al)) {
1042
1043 /* TLS extensions*/
1044 if (!ssl_parse_clienthello_tlsext(s, &p, d, n, &al)) {
1045 /* 'al' set by ssl_parse_clienthello_tlsext */
1046 SSLerror(s, SSL_R_PARSE_TLSEXT); 1040 SSLerror(s, SSL_R_PARSE_TLSEXT);
1047 goto f_err; 1041 goto f_err;
1048 } 1042 }
1043
1044 if (!S3I(s)->renegotiate_seen && s->internal->renegotiate) {
1045 al = SSL_AD_HANDSHAKE_FAILURE;
1046 SSLerror(s, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
1047 goto f_err;
1048 }
1049
1049 if (ssl_check_clienthello_tlsext_early(s) <= 0) { 1050 if (ssl_check_clienthello_tlsext_early(s) <= 0) {
1050 SSLerror(s, SSL_R_CLIENTHELLO_TLSEXT); 1051 SSLerror(s, SSL_R_CLIENTHELLO_TLSEXT);
1051 goto err; 1052 goto err;
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c
index d0764af3c0..0e3ef7da15 100644
--- a/src/lib/libssl/ssl_tlsext.c
+++ b/src/lib/libssl/ssl_tlsext.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_tlsext.c,v 1.19 2018/01/27 15:17:13 jsing Exp $ */ 1/* $OpenBSD: ssl_tlsext.c,v 1.20 2018/01/27 15:30:05 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -1292,6 +1292,35 @@ static struct tls_extension tls_extensions[] = {
1292 1292
1293#define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) 1293#define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions))
1294 1294
1295/* Ensure that extensions fit in a uint32_t bitmask. */
1296CTASSERT(N_TLS_EXTENSIONS <= (sizeof(uint32_t) * 8));
1297
1298static struct tls_extension *
1299tls_extension_find(uint16_t type, size_t *tls_extensions_idx)
1300{
1301 size_t i;
1302
1303 for (i = 0; i < N_TLS_EXTENSIONS; i++) {
1304 if (tls_extensions[i].type == type) {
1305 *tls_extensions_idx = i;
1306 return &tls_extensions[i];
1307 }
1308 }
1309
1310 return NULL;
1311}
1312
1313static void
1314tlsext_clienthello_reset_state(SSL *s)
1315{
1316 s->internal->servername_done = 0;
1317 s->tlsext_status_type = -1;
1318 S3I(s)->renegotiate_seen = 0;
1319 free(S3I(s)->alpn_selected);
1320 S3I(s)->alpn_selected = NULL;
1321 s->internal->srtp_profile = NULL;
1322}
1323
1295int 1324int
1296tlsext_clienthello_build(SSL *s, CBB *cbb) 1325tlsext_clienthello_build(SSL *s, CBB *cbb)
1297{ 1326{
@@ -1329,28 +1358,55 @@ tlsext_clienthello_build(SSL *s, CBB *cbb)
1329} 1358}
1330 1359
1331int 1360int
1332tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert) 1361tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert)
1333{ 1362{
1363 CBS extensions, extension_data;
1334 struct tls_extension *tlsext; 1364 struct tls_extension *tlsext;
1335 size_t i; 1365 uint32_t extensions_seen = 0;
1366 uint16_t type;
1367 size_t idx;
1336 1368
1337 for (i = 0; i < N_TLS_EXTENSIONS; i++) { 1369 /* XXX - this possibly should be done by the caller... */
1338 tlsext = &tls_extensions[i]; 1370 tlsext_clienthello_reset_state(s);
1339 1371
1340 if (tlsext->type != type) 1372 /* An empty extensions block is valid. */
1373 if (CBS_len(cbs) == 0)
1374 return 1;
1375
1376 *alert = SSL_AD_DECODE_ERROR;
1377
1378 if (!CBS_get_u16_length_prefixed(cbs, &extensions))
1379 return 0;
1380
1381 while (CBS_len(&extensions) > 0) {
1382 if (!CBS_get_u16(&extensions, &type))
1383 return 0;
1384 if (!CBS_get_u16_length_prefixed(&extensions, &extension_data))
1385 return 0;
1386
1387 if (s->internal->tlsext_debug_cb != NULL)
1388 s->internal->tlsext_debug_cb(s, 0, type,
1389 (unsigned char *)CBS_data(&extension_data),
1390 CBS_len(&extension_data),
1391 s->internal->tlsext_debug_arg);
1392
1393 /* Unknown extensions are ignored. */
1394 if ((tlsext = tls_extension_find(type, &idx)) == NULL)
1341 continue; 1395 continue;
1342 if (!tlsext->clienthello_parse(s, cbs, alert)) 1396
1397 /* Check for duplicate extensions. */
1398 if ((extensions_seen & (1 << idx)) != 0)
1343 return 0; 1399 return 0;
1344 if (CBS_len(cbs) != 0) { 1400 extensions_seen |= (1 << idx);
1345 *alert = SSL_AD_DECODE_ERROR; 1401
1402 if (!tlsext->clienthello_parse(s, &extension_data, alert))
1346 return 0; 1403 return 0;
1347 }
1348 1404
1349 return 1; 1405 if (CBS_len(&extension_data) != 0)
1406 return 0;
1350 } 1407 }
1351 1408
1352 /* Not found. */ 1409 return 1;
1353 return 2;
1354} 1410}
1355 1411
1356int 1412int
diff --git a/src/lib/libssl/ssl_tlsext.h b/src/lib/libssl/ssl_tlsext.h
index 7c6250a7f7..1af2e6cb3b 100644
--- a/src/lib/libssl/ssl_tlsext.h
+++ b/src/lib/libssl/ssl_tlsext.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_tlsext.h,v 1.10 2017/08/27 02:58:04 doug Exp $ */ 1/* $OpenBSD: ssl_tlsext.h,v 1.11 2018/01/27 15:30:05 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -82,8 +82,7 @@ int tlsext_srtp_serverhello_parse(SSL *s, CBS *cbs, int *alert);
82#endif 82#endif
83 83
84int tlsext_clienthello_build(SSL *s, CBB *cbb); 84int tlsext_clienthello_build(SSL *s, CBB *cbb);
85int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, 85int tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert);
86 int *alert);
87 86
88int tlsext_serverhello_build(SSL *s, CBB *cbb); 87int tlsext_serverhello_build(SSL *s, CBB *cbb);
89int tlsext_serverhello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, 88int tlsext_serverhello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type,
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 1cef08d094..fbd79431db 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.139 2017/10/11 17:35:00 jsing Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.140 2018/01/27 15:30:05 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 *
@@ -662,75 +662,6 @@ tls12_get_req_sig_algs(SSL *s, unsigned char **sigalgs, size_t *sigalgs_len)
662} 662}
663 663
664int 664int
665ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
666 int n, int *al)
667{
668 unsigned short type;
669 unsigned short size;
670 unsigned short len;
671 unsigned char *data = *p;
672 unsigned char *end = d + n;
673 CBS cbs;
674
675 s->internal->servername_done = 0;
676 s->tlsext_status_type = -1;
677 S3I(s)->renegotiate_seen = 0;
678 free(S3I(s)->alpn_selected);
679 S3I(s)->alpn_selected = NULL;
680 s->internal->srtp_profile = NULL;
681
682 if (data == end)
683 goto ri_check;
684
685 if (end - data < 2)
686 goto err;
687 n2s(data, len);
688
689 if (end - data != len)
690 goto err;
691
692 while (end - data >= 4) {
693 n2s(data, type);
694 n2s(data, size);
695
696 if (end - data < size)
697 goto err;
698
699 if (s->internal->tlsext_debug_cb)
700 s->internal->tlsext_debug_cb(s, 0, type, data, size,
701 s->internal->tlsext_debug_arg);
702
703 CBS_init(&cbs, data, size);
704 if (!tlsext_clienthello_parse_one(s, &cbs, type, al))
705 return 0;
706
707 data += size;
708 }
709
710 /* Spurious data on the end */
711 if (data != end)
712 goto err;
713
714 *p = data;
715
716ri_check:
717
718 /* Need RI if renegotiating */
719
720 if (!S3I(s)->renegotiate_seen && s->internal->renegotiate) {
721 *al = SSL_AD_HANDSHAKE_FAILURE;
722 SSLerror(s, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
723 return 0;
724 }
725
726 return 1;
727
728err:
729 *al = SSL_AD_DECODE_ERROR;
730 return 0;
731}
732
733int
734ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, size_t n, int *al) 665ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, size_t n, int *al)
735{ 666{
736 unsigned short type; 667 unsigned short type;