diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/ssl_locl.h | 7 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_srvr.c | 19 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 82 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.h | 5 | ||||
| -rw-r--r-- | src/lib/libssl/t1_lib.c | 71 |
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); | |||
| 1275 | int tls1_check_curve(SSL *s, const uint16_t curve_id); | 1278 | int tls1_check_curve(SSL *s, const uint16_t curve_id); |
| 1276 | int tls1_get_shared_curve(SSL *s); | 1279 | int tls1_get_shared_curve(SSL *s); |
| 1277 | 1280 | ||
| 1278 | int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, | ||
| 1279 | unsigned char *d, int n, int *al); | ||
| 1280 | int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, | 1281 | int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, |
| 1281 | size_t n, int *al); | 1282 | size_t n, int *al); |
| 1282 | int ssl_check_clienthello_tlsext_early(SSL *s); | 1283 | int 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. */ | ||
| 1296 | CTASSERT(N_TLS_EXTENSIONS <= (sizeof(uint32_t) * 8)); | ||
| 1297 | |||
| 1298 | static struct tls_extension * | ||
| 1299 | tls_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 | |||
| 1313 | static void | ||
| 1314 | tlsext_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 | |||
| 1295 | int | 1324 | int |
| 1296 | tlsext_clienthello_build(SSL *s, CBB *cbb) | 1325 | tlsext_clienthello_build(SSL *s, CBB *cbb) |
| 1297 | { | 1326 | { |
| @@ -1329,28 +1358,55 @@ tlsext_clienthello_build(SSL *s, CBB *cbb) | |||
| 1329 | } | 1358 | } |
| 1330 | 1359 | ||
| 1331 | int | 1360 | int |
| 1332 | tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert) | 1361 | tlsext_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 | ||
| 1356 | int | 1412 | int |
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 | ||
| 84 | int tlsext_clienthello_build(SSL *s, CBB *cbb); | 84 | int tlsext_clienthello_build(SSL *s, CBB *cbb); |
| 85 | int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, | 85 | int tlsext_clienthello_parse(SSL *s, CBS *cbs, int *alert); |
| 86 | int *alert); | ||
| 87 | 86 | ||
| 88 | int tlsext_serverhello_build(SSL *s, CBB *cbb); | 87 | int tlsext_serverhello_build(SSL *s, CBB *cbb); |
| 89 | int tlsext_serverhello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, | 88 | int 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 | ||
| 664 | int | 664 | int |
| 665 | ssl_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 | |||
| 716 | ri_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 | |||
| 728 | err: | ||
| 729 | *al = SSL_AD_DECODE_ERROR; | ||
| 730 | return 0; | ||
| 731 | } | ||
| 732 | |||
| 733 | int | ||
| 734 | ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, size_t n, int *al) | 665 | ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, size_t n, int *al) |
| 735 | { | 666 | { |
| 736 | unsigned short type; | 667 | unsigned short type; |
