diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/ssl_locl.h | 5 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 108 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.h | 9 | ||||
| -rw-r--r-- | src/lib/libssl/t1_lib.c | 150 | ||||
| -rw-r--r-- | src/regress/lib/libssl/tlsext/tlsexttest.c | 471 |
5 files changed, 595 insertions, 148 deletions
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 8ef2d01402..c11c5899e3 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.184 2017/08/10 17:18:38 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.185 2017/08/11 05:06:34 doug 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 | * |
| @@ -1380,6 +1380,9 @@ int SSL_state_func_code(int _state); | |||
| 1380 | #define SSLerrorx(r) ERR_PUT_error(ERR_LIB_SSL,(0xfff),(r),__FILE__,__LINE__) | 1380 | #define SSLerrorx(r) ERR_PUT_error(ERR_LIB_SSL,(0xfff),(r),__FILE__,__LINE__) |
| 1381 | void SSL_error_internal(const SSL *s, int r, char *f, int l); | 1381 | void SSL_error_internal(const SSL *s, int r, char *f, int l); |
| 1382 | 1382 | ||
| 1383 | void tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, | ||
| 1384 | size_t *pformatslen); | ||
| 1385 | |||
| 1383 | __END_HIDDEN_DECLS | 1386 | __END_HIDDEN_DECLS |
| 1384 | 1387 | ||
| 1385 | #endif | 1388 | #endif |
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index 400c69fa87..e8723b502c 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.3 2017/07/24 17:39:43 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.4 2017/08/11 05:06:34 doug Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -21,6 +21,103 @@ | |||
| 21 | #include "ssl_tlsext.h" | 21 | #include "ssl_tlsext.h" |
| 22 | 22 | ||
| 23 | /* | 23 | /* |
| 24 | * Supported Point Formats Extension - RFC 4492 section 5.1.2 | ||
| 25 | */ | ||
| 26 | static int | ||
| 27 | tlsext_ecpf_build(SSL *s, CBB *cbb) | ||
| 28 | { | ||
| 29 | CBB ecpf; | ||
| 30 | size_t formats_len; | ||
| 31 | const uint8_t *formats; | ||
| 32 | |||
| 33 | tls1_get_formatlist(s, 0, &formats, &formats_len); | ||
| 34 | |||
| 35 | if (formats_len == 0) { | ||
| 36 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | if (!CBB_add_u8_length_prefixed(cbb, &ecpf)) | ||
| 41 | return 0; | ||
| 42 | if (!CBB_add_bytes(&ecpf, formats, formats_len)) | ||
| 43 | return 0; | ||
| 44 | if (!CBB_flush(cbb)) | ||
| 45 | return 0; | ||
| 46 | |||
| 47 | return 1; | ||
| 48 | } | ||
| 49 | |||
| 50 | static int | ||
| 51 | tlsext_ecpf_parse(SSL *s, CBS *cbs, int *alert) | ||
| 52 | { | ||
| 53 | CBS ecpf; | ||
| 54 | |||
| 55 | if (!CBS_get_u8_length_prefixed(cbs, &ecpf)) | ||
| 56 | goto err; | ||
| 57 | if (CBS_len(&ecpf) == 0) | ||
| 58 | goto err; | ||
| 59 | if (CBS_len(cbs) != 0) | ||
| 60 | goto err; | ||
| 61 | |||
| 62 | /* Must contain uncompressed (0) */ | ||
| 63 | if (!CBS_contains_zero_byte(&ecpf)) { | ||
| 64 | SSLerror(s, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); | ||
| 65 | goto err; | ||
| 66 | } | ||
| 67 | |||
| 68 | if (!s->internal->hit) { | ||
| 69 | if (!CBS_stow(&ecpf, &(SSI(s)->tlsext_ecpointformatlist), | ||
| 70 | &(SSI(s)->tlsext_ecpointformatlist_length))) | ||
| 71 | goto err; | ||
| 72 | } | ||
| 73 | |||
| 74 | return 1; | ||
| 75 | |||
| 76 | err: | ||
| 77 | *alert = TLS1_AD_INTERNAL_ERROR; | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | int | ||
| 82 | tlsext_ecpf_clienthello_needs(SSL *s) | ||
| 83 | { | ||
| 84 | return ssl_has_ecc_ciphers(s); | ||
| 85 | } | ||
| 86 | |||
| 87 | int | ||
| 88 | tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb) | ||
| 89 | { | ||
| 90 | return tlsext_ecpf_build(s, cbb); | ||
| 91 | } | ||
| 92 | |||
| 93 | int | ||
| 94 | tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert) | ||
| 95 | { | ||
| 96 | return tlsext_ecpf_parse(s, cbs, alert); | ||
| 97 | } | ||
| 98 | |||
| 99 | int | ||
| 100 | tlsext_ecpf_serverhello_needs(SSL *s) | ||
| 101 | { | ||
| 102 | if (s->version == DTLS1_VERSION) | ||
| 103 | return 0; | ||
| 104 | |||
| 105 | return ssl_using_ecc_cipher(s); | ||
| 106 | } | ||
| 107 | |||
| 108 | int | ||
| 109 | tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb) | ||
| 110 | { | ||
| 111 | return tlsext_ecpf_build(s, cbb); | ||
| 112 | } | ||
| 113 | |||
| 114 | int | ||
| 115 | tlsext_ecpf_serverhello_parse(SSL *s, CBS *cbs, int *alert) | ||
| 116 | { | ||
| 117 | return tlsext_ecpf_parse(s, cbs, alert); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* | ||
| 24 | * Renegotiation Indication - RFC 5746. | 121 | * Renegotiation Indication - RFC 5746. |
| 25 | */ | 122 | */ |
| 26 | int | 123 | int |
| @@ -313,6 +410,15 @@ static struct tls_extension tls_extensions[] = { | |||
| 313 | .serverhello_build = tlsext_ri_serverhello_build, | 410 | .serverhello_build = tlsext_ri_serverhello_build, |
| 314 | .serverhello_parse = tlsext_ri_serverhello_parse, | 411 | .serverhello_parse = tlsext_ri_serverhello_parse, |
| 315 | }, | 412 | }, |
| 413 | { | ||
| 414 | .type = TLSEXT_TYPE_ec_point_formats, | ||
| 415 | .clienthello_needs = tlsext_ecpf_clienthello_needs, | ||
| 416 | .clienthello_build = tlsext_ecpf_clienthello_build, | ||
| 417 | .clienthello_parse = tlsext_ecpf_clienthello_parse, | ||
| 418 | .serverhello_needs = tlsext_ecpf_serverhello_needs, | ||
| 419 | .serverhello_build = tlsext_ecpf_serverhello_build, | ||
| 420 | .serverhello_parse = tlsext_ecpf_serverhello_parse, | ||
| 421 | }, | ||
| 316 | }; | 422 | }; |
| 317 | 423 | ||
| 318 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) | 424 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) |
diff --git a/src/lib/libssl/ssl_tlsext.h b/src/lib/libssl/ssl_tlsext.h index 4b0194861a..67a9cfb688 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.2 2017/07/24 17:10:31 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.h,v 1.3 2017/08/11 05:06:34 doug Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -29,6 +29,13 @@ int tlsext_sni_serverhello_needs(SSL *s); | |||
| 29 | int tlsext_sni_serverhello_build(SSL *s, CBB *cbb); | 29 | int tlsext_sni_serverhello_build(SSL *s, CBB *cbb); |
| 30 | int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert); | 30 | int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert); |
| 31 | 31 | ||
| 32 | int tlsext_ecpf_clienthello_needs(SSL *s); | ||
| 33 | int tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb); | ||
| 34 | int tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert); | ||
| 35 | int tlsext_ecpf_serverhello_needs(SSL *s); | ||
| 36 | int tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb); | ||
| 37 | int tlsext_ecpf_serverhello_parse(SSL *s, CBS *cbs, int *alert); | ||
| 38 | |||
| 32 | int tlsext_clienthello_build(SSL *s, CBB *cbb); | 39 | int tlsext_clienthello_build(SSL *s, CBB *cbb); |
| 33 | int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, | 40 | int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, |
| 34 | int *alert); | 41 | int *alert); |
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index 42fd18fe2d..2e90d3e9df 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.124 2017/08/10 17:18:38 jsing Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.125 2017/08/11 05:06:34 doug 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 | * |
| @@ -342,7 +342,7 @@ tls1_ec_nid2curve_id(int nid) | |||
| 342 | * the client/session formats. Otherwise return the custom format list if one | 342 | * the client/session formats. Otherwise return the custom format list if one |
| 343 | * exists, or the default formats if a custom list has not been specified. | 343 | * exists, or the default formats if a custom list has not been specified. |
| 344 | */ | 344 | */ |
| 345 | static void | 345 | void |
| 346 | tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, | 346 | tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, |
| 347 | size_t *pformatslen) | 347 | size_t *pformatslen) |
| 348 | { | 348 | { |
| @@ -699,34 +699,11 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 699 | ret += len; | 699 | ret += len; |
| 700 | 700 | ||
| 701 | if (using_ecc) { | 701 | if (using_ecc) { |
| 702 | size_t curveslen, formatslen, lenmax; | 702 | size_t curveslen, lenmax; |
| 703 | const uint16_t *curves; | 703 | const uint16_t *curves; |
| 704 | const uint8_t *formats; | ||
| 705 | int i; | 704 | int i; |
| 706 | 705 | ||
| 707 | /* | 706 | /* |
| 708 | * Add TLS extension ECPointFormats to the ClientHello message. | ||
| 709 | */ | ||
| 710 | tls1_get_formatlist(s, 0, &formats, &formatslen); | ||
| 711 | |||
| 712 | if ((size_t)(limit - ret) < 5) | ||
| 713 | return NULL; | ||
| 714 | |||
| 715 | lenmax = limit - ret - 5; | ||
| 716 | if (formatslen > lenmax) | ||
| 717 | return NULL; | ||
| 718 | if (formatslen > 255) { | ||
| 719 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 720 | return NULL; | ||
| 721 | } | ||
| 722 | |||
| 723 | s2n(TLSEXT_TYPE_ec_point_formats, ret); | ||
| 724 | s2n(formatslen + 1, ret); | ||
| 725 | *(ret++) = (unsigned char)formatslen; | ||
| 726 | memcpy(ret, formats, formatslen); | ||
| 727 | ret += formatslen; | ||
| 728 | |||
| 729 | /* | ||
| 730 | * Add TLS extension EllipticCurves to the ClientHello message. | 707 | * Add TLS extension EllipticCurves to the ClientHello message. |
| 731 | */ | 708 | */ |
| 732 | tls1_get_curvelist(s, 0, &curves, &curveslen); | 709 | tls1_get_curvelist(s, 0, &curves, &curveslen); |
| @@ -931,14 +908,12 @@ skip_ext: | |||
| 931 | unsigned char * | 908 | unsigned char * |
| 932 | ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | 909 | ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) |
| 933 | { | 910 | { |
| 934 | int using_ecc, extdatalen = 0; | 911 | int extdatalen = 0; |
| 935 | unsigned char *ret = p; | 912 | unsigned char *ret = p; |
| 936 | int next_proto_neg_seen; | 913 | int next_proto_neg_seen; |
| 937 | size_t len; | 914 | size_t len; |
| 938 | CBB cbb; | 915 | CBB cbb; |
| 939 | 916 | ||
| 940 | using_ecc = ssl_using_ecc_cipher(s); | ||
| 941 | |||
| 942 | ret += 2; | 917 | ret += 2; |
| 943 | if (ret >= limit) | 918 | if (ret >= limit) |
| 944 | return NULL; /* this really never occurs, but ... */ | 919 | return NULL; /* this really never occurs, but ... */ |
| @@ -957,33 +932,6 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
| 957 | return NULL; | 932 | return NULL; |
| 958 | ret += len; | 933 | ret += len; |
| 959 | 934 | ||
| 960 | if (using_ecc && s->version != DTLS1_VERSION) { | ||
| 961 | const unsigned char *formats; | ||
| 962 | size_t formatslen, lenmax; | ||
| 963 | |||
| 964 | /* | ||
| 965 | * Add TLS extension ECPointFormats to the ServerHello message. | ||
| 966 | */ | ||
| 967 | tls1_get_formatlist(s, 0, &formats, &formatslen); | ||
| 968 | |||
| 969 | if ((size_t)(limit - ret) < 5) | ||
| 970 | return NULL; | ||
| 971 | |||
| 972 | lenmax = limit - ret - 5; | ||
| 973 | if (formatslen > lenmax) | ||
| 974 | return NULL; | ||
| 975 | if (formatslen > 255) { | ||
| 976 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 977 | return NULL; | ||
| 978 | } | ||
| 979 | |||
| 980 | s2n(TLSEXT_TYPE_ec_point_formats, ret); | ||
| 981 | s2n(formatslen + 1, ret); | ||
| 982 | *(ret++) = (unsigned char)formatslen; | ||
| 983 | memcpy(ret, formats, formatslen); | ||
| 984 | ret += formatslen; | ||
| 985 | } | ||
| 986 | |||
| 987 | /* | 935 | /* |
| 988 | * Currently the server should not respond with a SupportedCurves | 936 | * Currently the server should not respond with a SupportedCurves |
| 989 | * extension. | 937 | * extension. |
| @@ -1194,38 +1142,7 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
| 1194 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) | 1142 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) |
| 1195 | return 0; | 1143 | return 0; |
| 1196 | 1144 | ||
| 1197 | if (type == TLSEXT_TYPE_ec_point_formats && | 1145 | if (type == TLSEXT_TYPE_elliptic_curves && |
| 1198 | s->version != DTLS1_VERSION) { | ||
| 1199 | unsigned char *sdata = data; | ||
| 1200 | size_t formatslen; | ||
| 1201 | uint8_t *formats; | ||
| 1202 | |||
| 1203 | if (size < 1) { | ||
| 1204 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1205 | return 0; | ||
| 1206 | } | ||
| 1207 | formatslen = *(sdata++); | ||
| 1208 | if (formatslen != size - 1) { | ||
| 1209 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1210 | return 0; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | if (!s->internal->hit) { | ||
| 1214 | free(SSI(s)->tlsext_ecpointformatlist); | ||
| 1215 | SSI(s)->tlsext_ecpointformatlist = NULL; | ||
| 1216 | SSI(s)->tlsext_ecpointformatlist_length = 0; | ||
| 1217 | |||
| 1218 | if ((formats = reallocarray(NULL, formatslen, | ||
| 1219 | sizeof(uint8_t))) == NULL) { | ||
| 1220 | *al = TLS1_AD_INTERNAL_ERROR; | ||
| 1221 | return 0; | ||
| 1222 | } | ||
| 1223 | memcpy(formats, sdata, formatslen); | ||
| 1224 | SSI(s)->tlsext_ecpointformatlist = formats; | ||
| 1225 | SSI(s)->tlsext_ecpointformatlist_length = | ||
| 1226 | formatslen; | ||
| 1227 | } | ||
| 1228 | } else if (type == TLSEXT_TYPE_elliptic_curves && | ||
| 1229 | s->version != DTLS1_VERSION) { | 1146 | s->version != DTLS1_VERSION) { |
| 1230 | unsigned char *sdata = data; | 1147 | unsigned char *sdata = data; |
| 1231 | size_t curveslen, i; | 1148 | size_t curveslen, i; |
| @@ -1510,39 +1427,7 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, size_t n, int *al) | |||
| 1510 | if (!tlsext_serverhello_parse_one(s, &cbs, type, al)) | 1427 | if (!tlsext_serverhello_parse_one(s, &cbs, type, al)) |
| 1511 | return 0; | 1428 | return 0; |
| 1512 | 1429 | ||
| 1513 | if (type == TLSEXT_TYPE_ec_point_formats && | 1430 | if (type == TLSEXT_TYPE_session_ticket) { |
| 1514 | s->version != DTLS1_VERSION) { | ||
| 1515 | unsigned char *sdata = data; | ||
| 1516 | size_t formatslen; | ||
| 1517 | uint8_t *formats; | ||
| 1518 | |||
| 1519 | if (size < 1) { | ||
| 1520 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1521 | return 0; | ||
| 1522 | } | ||
| 1523 | formatslen = *(sdata++); | ||
| 1524 | if (formatslen != size - 1) { | ||
| 1525 | *al = TLS1_AD_DECODE_ERROR; | ||
| 1526 | return 0; | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | if (!s->internal->hit) { | ||
| 1530 | free(SSI(s)->tlsext_ecpointformatlist); | ||
| 1531 | SSI(s)->tlsext_ecpointformatlist = NULL; | ||
| 1532 | SSI(s)->tlsext_ecpointformatlist_length = 0; | ||
| 1533 | |||
| 1534 | if ((formats = reallocarray(NULL, formatslen, | ||
| 1535 | sizeof(uint8_t))) == NULL) { | ||
| 1536 | *al = TLS1_AD_INTERNAL_ERROR; | ||
| 1537 | return 0; | ||
| 1538 | } | ||
| 1539 | memcpy(formats, sdata, formatslen); | ||
| 1540 | SSI(s)->tlsext_ecpointformatlist = formats; | ||
| 1541 | SSI(s)->tlsext_ecpointformatlist_length = | ||
| 1542 | formatslen; | ||
| 1543 | } | ||
| 1544 | } | ||
| 1545 | else if (type == TLSEXT_TYPE_session_ticket) { | ||
| 1546 | if (s->internal->tls_session_ticket_ext_cb && | 1431 | if (s->internal->tls_session_ticket_ext_cb && |
| 1547 | !s->internal->tls_session_ticket_ext_cb(s, data, size, s->internal->tls_session_ticket_ext_cb_arg)) { | 1432 | !s->internal->tls_session_ticket_ext_cb(s, data, size, s->internal->tls_session_ticket_ext_cb_arg)) { |
| 1548 | *al = TLS1_AD_INTERNAL_ERROR; | 1433 | *al = TLS1_AD_INTERNAL_ERROR; |
| @@ -1779,29 +1664,6 @@ ssl_check_serverhello_tlsext(SSL *s) | |||
| 1779 | int ret = SSL_TLSEXT_ERR_NOACK; | 1664 | int ret = SSL_TLSEXT_ERR_NOACK; |
| 1780 | int al = SSL_AD_UNRECOGNIZED_NAME; | 1665 | int al = SSL_AD_UNRECOGNIZED_NAME; |
| 1781 | 1666 | ||
| 1782 | /* If we are client and using an elliptic curve cryptography cipher | ||
| 1783 | * suite, then if server returns an EC point formats lists extension | ||
| 1784 | * it must contain uncompressed. | ||
| 1785 | */ | ||
| 1786 | if (ssl_using_ecc_cipher(s) && | ||
| 1787 | s->internal->tlsext_ecpointformatlist != NULL && | ||
| 1788 | s->internal->tlsext_ecpointformatlist_length > 0) { | ||
| 1789 | /* we are using an ECC cipher */ | ||
| 1790 | size_t i; | ||
| 1791 | unsigned char *list; | ||
| 1792 | int found_uncompressed = 0; | ||
| 1793 | list = SSI(s)->tlsext_ecpointformatlist; | ||
| 1794 | for (i = 0; i < SSI(s)->tlsext_ecpointformatlist_length; i++) { | ||
| 1795 | if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) { | ||
| 1796 | found_uncompressed = 1; | ||
| 1797 | break; | ||
| 1798 | } | ||
| 1799 | } | ||
| 1800 | if (!found_uncompressed) { | ||
| 1801 | SSLerror(s, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); | ||
| 1802 | return -1; | ||
| 1803 | } | ||
| 1804 | } | ||
| 1805 | ret = SSL_TLSEXT_ERR_OK; | 1667 | ret = SSL_TLSEXT_ERR_OK; |
| 1806 | 1668 | ||
| 1807 | if (s->ctx != NULL && s->ctx->internal->tlsext_servername_callback != 0) | 1669 | if (s->ctx != NULL && s->ctx->internal->tlsext_servername_callback != 0) |
diff --git a/src/regress/lib/libssl/tlsext/tlsexttest.c b/src/regress/lib/libssl/tlsext/tlsexttest.c index 792ccfe706..5a7a34c56c 100644 --- a/src/regress/lib/libssl/tlsext/tlsexttest.c +++ b/src/regress/lib/libssl/tlsext/tlsexttest.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tlsexttest.c,v 1.3 2017/07/24 17:42:14 jsing Exp $ */ | 1 | /* $OpenBSD: tlsexttest.c,v 1.4 2017/08/11 05:06:34 doug Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -33,6 +33,23 @@ hexdump(const unsigned char *buf, size_t len) | |||
| 33 | fprintf(stderr, "\n"); | 33 | fprintf(stderr, "\n"); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | static void | ||
| 37 | compare_data(const uint8_t *recv, size_t recv_len, const uint8_t *expect, | ||
| 38 | size_t expect_len) | ||
| 39 | { | ||
| 40 | fprintf(stderr, "received:\n"); | ||
| 41 | hexdump(recv, recv_len); | ||
| 42 | |||
| 43 | fprintf(stderr, "test data:\n"); | ||
| 44 | hexdump(expect, expect_len); | ||
| 45 | } | ||
| 46 | |||
| 47 | #define FAIL(msg, ...) \ | ||
| 48 | do { \ | ||
| 49 | fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ | ||
| 50 | fprintf(stderr, msg, ##__VA_ARGS__); \ | ||
| 51 | } while(0) | ||
| 52 | |||
| 36 | /* | 53 | /* |
| 37 | * Renegotiation Indication - RFC 5746. | 54 | * Renegotiation Indication - RFC 5746. |
| 38 | */ | 55 | */ |
| @@ -522,6 +539,455 @@ test_tlsext_sni_serverhello(void) | |||
| 522 | return (failure); | 539 | return (failure); |
| 523 | } | 540 | } |
| 524 | 541 | ||
| 542 | /* | ||
| 543 | * ECPointFormats - RFC 4492 section 5.1.2 (Supported Point Formats). | ||
| 544 | * | ||
| 545 | * Examples are from the RFC. Both client and server have the same build and | ||
| 546 | * parse but the needs differ. | ||
| 547 | */ | ||
| 548 | |||
| 549 | static uint8_t tlsext_ecpf_hello_uncompressed_val[] = { | ||
| 550 | TLSEXT_ECPOINTFORMAT_uncompressed | ||
| 551 | }; | ||
| 552 | static uint8_t tlsext_ecpf_hello_uncompressed[] = { | ||
| 553 | 0x01, | ||
| 554 | 0x00 /* TLSEXT_ECPOINTFORMAT_uncompressed */ | ||
| 555 | }; | ||
| 556 | |||
| 557 | static uint8_t tlsext_ecpf_hello_prime[] = { | ||
| 558 | 0x01, | ||
| 559 | 0x01 /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime */ | ||
| 560 | }; | ||
| 561 | |||
| 562 | static uint8_t tlsext_ecpf_hello_prefer_order_val[] = { | ||
| 563 | TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, | ||
| 564 | TLSEXT_ECPOINTFORMAT_uncompressed, | ||
| 565 | TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 | ||
| 566 | }; | ||
| 567 | static uint8_t tlsext_ecpf_hello_prefer_order[] = { | ||
| 568 | 0x03, | ||
| 569 | 0x01, /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime */ | ||
| 570 | 0x00, /* TLSEXT_ECPOINTFORMAT_uncompressed */ | ||
| 571 | 0x02 /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 */ | ||
| 572 | }; | ||
| 573 | |||
| 574 | static int | ||
| 575 | test_tlsext_ecpf_clienthello(void) | ||
| 576 | { | ||
| 577 | uint8_t *data = NULL; | ||
| 578 | SSL_CTX *ssl_ctx = NULL; | ||
| 579 | SSL *ssl = NULL; | ||
| 580 | size_t dlen; | ||
| 581 | int failure, alert; | ||
| 582 | CBB cbb; | ||
| 583 | CBS cbs; | ||
| 584 | |||
| 585 | failure = 1; | ||
| 586 | |||
| 587 | CBB_init(&cbb, 0); | ||
| 588 | |||
| 589 | if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) | ||
| 590 | errx(1, "failed to create SSL_CTX"); | ||
| 591 | if ((ssl = SSL_new(ssl_ctx)) == NULL) | ||
| 592 | errx(1, "failed to create SSL"); | ||
| 593 | |||
| 594 | /* | ||
| 595 | * Default ciphers include EC so we need it by default. | ||
| 596 | */ | ||
| 597 | if (!tlsext_ecpf_clienthello_needs(ssl)) { | ||
| 598 | FAIL("clienthello should need ECPointFormats for default " | ||
| 599 | "ciphers\n"); | ||
| 600 | goto err; | ||
| 601 | } | ||
| 602 | |||
| 603 | /* | ||
| 604 | * Exclude EC cipher suites so we can test not including it. | ||
| 605 | */ | ||
| 606 | if (!SSL_set_cipher_list(ssl, "ALL:!ECDHE:!ECDH")) { | ||
| 607 | FAIL("clienthello should be able to set cipher list\n"); | ||
| 608 | goto err; | ||
| 609 | } | ||
| 610 | if (tlsext_ecpf_clienthello_needs(ssl)) { | ||
| 611 | FAIL("clienthello should not need ECPointFormats\n"); | ||
| 612 | goto err; | ||
| 613 | } | ||
| 614 | |||
| 615 | /* | ||
| 616 | * Use libtls default for the rest of the testing | ||
| 617 | */ | ||
| 618 | if (!SSL_set_cipher_list(ssl, "TLSv1.2+AEAD+ECDHE")) { | ||
| 619 | FAIL("clienthello should be able to set cipher list\n"); | ||
| 620 | goto err; | ||
| 621 | } | ||
| 622 | if (!tlsext_ecpf_clienthello_needs(ssl)) { | ||
| 623 | FAIL("clienthello should need ECPointFormats\n"); | ||
| 624 | goto err; | ||
| 625 | } | ||
| 626 | |||
| 627 | /* | ||
| 628 | * The default ECPointFormats should only have uncompressed | ||
| 629 | */ | ||
| 630 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 631 | errx(1, "failed to create session"); | ||
| 632 | |||
| 633 | if (!tlsext_ecpf_clienthello_build(ssl, &cbb)) { | ||
| 634 | FAIL("clienthello failed to build ECPointFormats\n"); | ||
| 635 | goto err; | ||
| 636 | } | ||
| 637 | |||
| 638 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
| 639 | errx(1, "failed to finish CBB"); | ||
| 640 | |||
| 641 | if (dlen != sizeof(tlsext_ecpf_hello_uncompressed)) { | ||
| 642 | FAIL("got clienthello ECPointFormats with length %zu, " | ||
| 643 | "want length %zu\n", dlen, | ||
| 644 | sizeof(tlsext_ecpf_hello_uncompressed)); | ||
| 645 | compare_data(data, dlen, tlsext_ecpf_hello_uncompressed, | ||
| 646 | sizeof(tlsext_ecpf_hello_uncompressed)); | ||
| 647 | goto err; | ||
| 648 | } | ||
| 649 | |||
| 650 | if (memcmp(data, tlsext_ecpf_hello_uncompressed, dlen) != 0) { | ||
| 651 | FAIL("clienthello ECPointFormats differs:\n"); | ||
| 652 | compare_data(data, dlen, tlsext_ecpf_hello_uncompressed, | ||
| 653 | sizeof(tlsext_ecpf_hello_uncompressed)); | ||
| 654 | goto err; | ||
| 655 | } | ||
| 656 | |||
| 657 | /* | ||
| 658 | * Make sure we can parse the default. | ||
| 659 | */ | ||
| 660 | CBB_cleanup(&cbb); | ||
| 661 | CBB_init(&cbb, 0); | ||
| 662 | free(data); | ||
| 663 | data = NULL; | ||
| 664 | |||
| 665 | SSL_SESSION_free(ssl->session); | ||
| 666 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 667 | errx(1, "failed to create session"); | ||
| 668 | |||
| 669 | CBS_init(&cbs, tlsext_ecpf_hello_uncompressed, | ||
| 670 | sizeof(tlsext_ecpf_hello_uncompressed)); | ||
| 671 | if (!tlsext_ecpf_clienthello_parse(ssl, &cbs, &alert)) { | ||
| 672 | FAIL("failed to parse clienthello ECPointFormats\n"); | ||
| 673 | goto err; | ||
| 674 | } | ||
| 675 | |||
| 676 | if (SSI(ssl)->tlsext_ecpointformatlist_length != | ||
| 677 | sizeof(tlsext_ecpf_hello_uncompressed_val)) { | ||
| 678 | FAIL("no tlsext_ecpointformats from clienthello " | ||
| 679 | "ECPointFormats\n"); | ||
| 680 | goto err; | ||
| 681 | } | ||
| 682 | |||
| 683 | if (memcmp(SSI(ssl)->tlsext_ecpointformatlist, | ||
| 684 | tlsext_ecpf_hello_uncompressed_val, | ||
| 685 | sizeof(tlsext_ecpf_hello_uncompressed_val)) != 0) { | ||
| 686 | FAIL("clienthello had an incorrect ECPointFormats entry\n"); | ||
| 687 | goto err; | ||
| 688 | } | ||
| 689 | |||
| 690 | /* | ||
| 691 | * Test with a custom order. | ||
| 692 | */ | ||
| 693 | CBB_cleanup(&cbb); | ||
| 694 | CBB_init(&cbb, 0); | ||
| 695 | free(data); | ||
| 696 | data = NULL; | ||
| 697 | |||
| 698 | SSL_SESSION_free(ssl->session); | ||
| 699 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 700 | errx(1, "failed to create session"); | ||
| 701 | |||
| 702 | if ((ssl->internal->tlsext_ecpointformatlist = malloc(sizeof(uint8_t) * 3)) == NULL) { | ||
| 703 | FAIL("client could not malloc\n"); | ||
| 704 | goto err; | ||
| 705 | } | ||
| 706 | ssl->internal->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; | ||
| 707 | ssl->internal->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_uncompressed; | ||
| 708 | ssl->internal->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; | ||
| 709 | ssl->internal->tlsext_ecpointformatlist_length = 3; | ||
| 710 | |||
| 711 | if (!tlsext_ecpf_clienthello_needs(ssl)) { | ||
| 712 | FAIL("clienthello should need ECPointFormats with a custom " | ||
| 713 | "format\n"); | ||
| 714 | goto err; | ||
| 715 | } | ||
| 716 | |||
| 717 | if (!tlsext_ecpf_clienthello_build(ssl, &cbb)) { | ||
| 718 | FAIL("clienthello failed to build ECPointFormats\n"); | ||
| 719 | goto err; | ||
| 720 | } | ||
| 721 | |||
| 722 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
| 723 | errx(1, "failed to finish CBB"); | ||
| 724 | |||
| 725 | if (dlen != sizeof(tlsext_ecpf_hello_prefer_order)) { | ||
| 726 | FAIL("got clienthello ECPointFormats with length %zu, " | ||
| 727 | "want length %zu\n", dlen, | ||
| 728 | sizeof(tlsext_ecpf_hello_prefer_order)); | ||
| 729 | compare_data(data, dlen, tlsext_ecpf_hello_prefer_order, | ||
| 730 | sizeof(tlsext_ecpf_hello_prefer_order)); | ||
| 731 | goto err; | ||
| 732 | } | ||
| 733 | |||
| 734 | if (memcmp(data, tlsext_ecpf_hello_prefer_order, dlen) != 0) { | ||
| 735 | FAIL("clienthello ECPointFormats differs:\n"); | ||
| 736 | compare_data(data, dlen, tlsext_ecpf_hello_prefer_order, | ||
| 737 | sizeof(tlsext_ecpf_hello_prefer_order)); | ||
| 738 | goto err; | ||
| 739 | } | ||
| 740 | |||
| 741 | /* | ||
| 742 | * Make sure that we can parse this custom order. | ||
| 743 | */ | ||
| 744 | CBB_cleanup(&cbb); | ||
| 745 | CBB_init(&cbb, 0); | ||
| 746 | free(data); | ||
| 747 | data = NULL; | ||
| 748 | |||
| 749 | SSL_SESSION_free(ssl->session); | ||
| 750 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 751 | errx(1, "failed to create session"); | ||
| 752 | |||
| 753 | /* Reset the custom list so we go back to the default uncompressed. */ | ||
| 754 | free(ssl->internal->tlsext_ecpointformatlist); | ||
| 755 | ssl->internal->tlsext_ecpointformatlist = NULL; | ||
| 756 | ssl->internal->tlsext_ecpointformatlist_length = 0; | ||
| 757 | |||
| 758 | CBS_init(&cbs, tlsext_ecpf_hello_prefer_order, | ||
| 759 | sizeof(tlsext_ecpf_hello_prefer_order)); | ||
| 760 | if (!tlsext_ecpf_clienthello_parse(ssl, &cbs, &alert)) { | ||
| 761 | FAIL("failed to parse clienthello ECPointFormats\n"); | ||
| 762 | goto err; | ||
| 763 | } | ||
| 764 | |||
| 765 | if (SSI(ssl)->tlsext_ecpointformatlist_length != | ||
| 766 | sizeof(tlsext_ecpf_hello_prefer_order_val)) { | ||
| 767 | FAIL("no tlsext_ecpointformats from clienthello " | ||
| 768 | "ECPointFormats\n"); | ||
| 769 | goto err; | ||
| 770 | } | ||
| 771 | |||
| 772 | if (memcmp(SSI(ssl)->tlsext_ecpointformatlist, | ||
| 773 | tlsext_ecpf_hello_prefer_order_val, | ||
| 774 | sizeof(tlsext_ecpf_hello_prefer_order_val)) != 0) { | ||
| 775 | FAIL("clienthello had an incorrect ECPointFormats entry\n"); | ||
| 776 | goto err; | ||
| 777 | } | ||
| 778 | |||
| 779 | |||
| 780 | failure = 0; | ||
| 781 | |||
| 782 | err: | ||
| 783 | CBB_cleanup(&cbb); | ||
| 784 | SSL_CTX_free(ssl_ctx); | ||
| 785 | SSL_free(ssl); | ||
| 786 | free(data); | ||
| 787 | |||
| 788 | return (failure); | ||
| 789 | } | ||
| 790 | |||
| 791 | |||
| 792 | static int | ||
| 793 | test_tlsext_ecpf_serverhello(void) | ||
| 794 | { | ||
| 795 | uint8_t *data = NULL; | ||
| 796 | SSL_CTX *ssl_ctx = NULL; | ||
| 797 | SSL *ssl = NULL; | ||
| 798 | size_t dlen; | ||
| 799 | int failure, alert; | ||
| 800 | CBB cbb; | ||
| 801 | CBS cbs; | ||
| 802 | |||
| 803 | failure = 1; | ||
| 804 | |||
| 805 | CBB_init(&cbb, 0); | ||
| 806 | |||
| 807 | if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) | ||
| 808 | errx(1, "failed to create SSL_CTX"); | ||
| 809 | if ((ssl = SSL_new(ssl_ctx)) == NULL) | ||
| 810 | errx(1, "failed to create SSL"); | ||
| 811 | |||
| 812 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 813 | errx(1, "failed to create session"); | ||
| 814 | |||
| 815 | /* Setup the state so we can call needs. */ | ||
| 816 | if ((S3I(ssl)->hs.new_cipher = | ||
| 817 | ssl3_get_cipher_by_id(TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305)) | ||
| 818 | == NULL) { | ||
| 819 | FAIL("serverhello cannot find cipher\n"); | ||
| 820 | goto err; | ||
| 821 | } | ||
| 822 | if ((SSI(ssl)->tlsext_ecpointformatlist = malloc(sizeof(uint8_t))) | ||
| 823 | == NULL) { | ||
| 824 | FAIL("server could not malloc\n"); | ||
| 825 | goto err; | ||
| 826 | } | ||
| 827 | SSI(ssl)->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; | ||
| 828 | SSI(ssl)->tlsext_ecpointformatlist_length = 1; | ||
| 829 | |||
| 830 | if (!tlsext_ecpf_serverhello_needs(ssl)) { | ||
| 831 | FAIL("serverhello should need ECPointFormats now\n"); | ||
| 832 | goto err; | ||
| 833 | } | ||
| 834 | |||
| 835 | /* | ||
| 836 | * The server will ignore the session list and use either a custom | ||
| 837 | * list or the default (uncompressed). | ||
| 838 | */ | ||
| 839 | if (!tlsext_ecpf_serverhello_build(ssl, &cbb)) { | ||
| 840 | FAIL("serverhello failed to build ECPointFormats\n"); | ||
| 841 | goto err; | ||
| 842 | } | ||
| 843 | |||
| 844 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
| 845 | errx(1, "failed to finish CBB"); | ||
| 846 | |||
| 847 | if (dlen != sizeof(tlsext_ecpf_hello_uncompressed)) { | ||
| 848 | FAIL("got serverhello ECPointFormats with length %zu, " | ||
| 849 | "want length %zu\n", dlen, | ||
| 850 | sizeof(tlsext_ecpf_hello_uncompressed)); | ||
| 851 | compare_data(data, dlen, tlsext_ecpf_hello_uncompressed, | ||
| 852 | sizeof(tlsext_ecpf_hello_uncompressed)); | ||
| 853 | goto err; | ||
| 854 | } | ||
| 855 | |||
| 856 | if (memcmp(data, tlsext_ecpf_hello_uncompressed, dlen) != 0) { | ||
| 857 | FAIL("serverhello ECPointFormats differs:\n"); | ||
| 858 | compare_data(data, dlen, tlsext_ecpf_hello_uncompressed, | ||
| 859 | sizeof(tlsext_ecpf_hello_uncompressed)); | ||
| 860 | goto err; | ||
| 861 | } | ||
| 862 | |||
| 863 | /* | ||
| 864 | * Cannot parse a non-default list without at least uncompressed. | ||
| 865 | */ | ||
| 866 | CBB_cleanup(&cbb); | ||
| 867 | CBB_init(&cbb, 0); | ||
| 868 | free(data); | ||
| 869 | data = NULL; | ||
| 870 | |||
| 871 | SSL_SESSION_free(ssl->session); | ||
| 872 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 873 | errx(1, "failed to create session"); | ||
| 874 | |||
| 875 | CBS_init(&cbs, tlsext_ecpf_hello_prime, | ||
| 876 | sizeof(tlsext_ecpf_hello_prime)); | ||
| 877 | if (tlsext_ecpf_serverhello_parse(ssl, &cbs, &alert)) { | ||
| 878 | FAIL("must include uncompressed in serverhello ECPointFormats\n"); | ||
| 879 | goto err; | ||
| 880 | } | ||
| 881 | |||
| 882 | /* | ||
| 883 | * Test with a custom order that replaces the default uncompressed. | ||
| 884 | */ | ||
| 885 | CBB_cleanup(&cbb); | ||
| 886 | CBB_init(&cbb, 0); | ||
| 887 | free(data); | ||
| 888 | data = NULL; | ||
| 889 | |||
| 890 | SSL_SESSION_free(ssl->session); | ||
| 891 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 892 | errx(1, "failed to create session"); | ||
| 893 | |||
| 894 | /* Add a session list even though it will be ignored. */ | ||
| 895 | if ((SSI(ssl)->tlsext_ecpointformatlist = malloc(sizeof(uint8_t))) | ||
| 896 | == NULL) { | ||
| 897 | FAIL("server could not malloc\n"); | ||
| 898 | goto err; | ||
| 899 | } | ||
| 900 | SSI(ssl)->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; | ||
| 901 | SSI(ssl)->tlsext_ecpointformatlist_length = 1; | ||
| 902 | |||
| 903 | /* Replace the default list with a custom one. */ | ||
| 904 | if ((ssl->internal->tlsext_ecpointformatlist = malloc(sizeof(uint8_t) * 3)) == NULL) { | ||
| 905 | FAIL("server could not malloc\n"); | ||
| 906 | goto err; | ||
| 907 | } | ||
| 908 | ssl->internal->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; | ||
| 909 | ssl->internal->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_uncompressed; | ||
| 910 | ssl->internal->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; | ||
| 911 | ssl->internal->tlsext_ecpointformatlist_length = 3; | ||
| 912 | |||
| 913 | if (!tlsext_ecpf_serverhello_needs(ssl)) { | ||
| 914 | FAIL("serverhello should need ECPointFormats\n"); | ||
| 915 | goto err; | ||
| 916 | } | ||
| 917 | |||
| 918 | if (!tlsext_ecpf_serverhello_build(ssl, &cbb)) { | ||
| 919 | FAIL("serverhello failed to build ECPointFormats\n"); | ||
| 920 | goto err; | ||
| 921 | } | ||
| 922 | |||
| 923 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
| 924 | errx(1, "failed to finish CBB"); | ||
| 925 | |||
| 926 | if (dlen != sizeof(tlsext_ecpf_hello_prefer_order)) { | ||
| 927 | FAIL("got serverhello ECPointFormats with length %zu, " | ||
| 928 | "want length %zu\n", dlen, | ||
| 929 | sizeof(tlsext_ecpf_hello_prefer_order)); | ||
| 930 | compare_data(data, dlen, tlsext_ecpf_hello_prefer_order, | ||
| 931 | sizeof(tlsext_ecpf_hello_prefer_order)); | ||
| 932 | goto err; | ||
| 933 | } | ||
| 934 | |||
| 935 | if (memcmp(data, tlsext_ecpf_hello_prefer_order, dlen) != 0) { | ||
| 936 | FAIL("serverhello ECPointFormats differs:\n"); | ||
| 937 | compare_data(data, dlen, tlsext_ecpf_hello_prefer_order, | ||
| 938 | sizeof(tlsext_ecpf_hello_prefer_order)); | ||
| 939 | goto err; | ||
| 940 | } | ||
| 941 | |||
| 942 | /* | ||
| 943 | * Should be able to parse the custom list into a session list. | ||
| 944 | */ | ||
| 945 | CBB_cleanup(&cbb); | ||
| 946 | CBB_init(&cbb, 0); | ||
| 947 | free(data); | ||
| 948 | data = NULL; | ||
| 949 | |||
| 950 | SSL_SESSION_free(ssl->session); | ||
| 951 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
| 952 | errx(1, "failed to create session"); | ||
| 953 | |||
| 954 | /* Reset back to the default (uncompressed) */ | ||
| 955 | free(ssl->internal->tlsext_ecpointformatlist); | ||
| 956 | ssl->internal->tlsext_ecpointformatlist = NULL; | ||
| 957 | ssl->internal->tlsext_ecpointformatlist_length = 0; | ||
| 958 | |||
| 959 | CBS_init(&cbs, tlsext_ecpf_hello_prefer_order, | ||
| 960 | sizeof(tlsext_ecpf_hello_prefer_order)); | ||
| 961 | if (!tlsext_ecpf_serverhello_parse(ssl, &cbs, &alert)) { | ||
| 962 | FAIL("failed to parse serverhello ECPointFormats\n"); | ||
| 963 | goto err; | ||
| 964 | } | ||
| 965 | |||
| 966 | if (SSI(ssl)->tlsext_ecpointformatlist_length != | ||
| 967 | sizeof(tlsext_ecpf_hello_prefer_order_val)) { | ||
| 968 | FAIL("no tlsext_ecpointformats from serverhello " | ||
| 969 | "ECPointFormats\n"); | ||
| 970 | goto err; | ||
| 971 | } | ||
| 972 | |||
| 973 | if (memcmp(SSI(ssl)->tlsext_ecpointformatlist, | ||
| 974 | tlsext_ecpf_hello_prefer_order_val, | ||
| 975 | sizeof(tlsext_ecpf_hello_prefer_order_val)) != 0) { | ||
| 976 | FAIL("serverhello had an incorrect ECPointFormats entry\n"); | ||
| 977 | goto err; | ||
| 978 | } | ||
| 979 | |||
| 980 | failure = 0; | ||
| 981 | |||
| 982 | err: | ||
| 983 | CBB_cleanup(&cbb); | ||
| 984 | SSL_CTX_free(ssl_ctx); | ||
| 985 | SSL_free(ssl); | ||
| 986 | free(data); | ||
| 987 | |||
| 988 | return (failure); | ||
| 989 | } | ||
| 990 | |||
| 525 | int | 991 | int |
| 526 | main(int argc, char **argv) | 992 | main(int argc, char **argv) |
| 527 | { | 993 | { |
| @@ -535,5 +1001,8 @@ main(int argc, char **argv) | |||
| 535 | failed |= test_tlsext_sni_clienthello(); | 1001 | failed |= test_tlsext_sni_clienthello(); |
| 536 | failed |= test_tlsext_sni_serverhello(); | 1002 | failed |= test_tlsext_sni_serverhello(); |
| 537 | 1003 | ||
| 1004 | failed |= test_tlsext_ecpf_clienthello(); | ||
| 1005 | failed |= test_tlsext_ecpf_serverhello(); | ||
| 1006 | |||
| 538 | return (failed); | 1007 | return (failed); |
| 539 | } | 1008 | } |
