summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libssl/ssl_locl.h4
-rw-r--r--src/lib/libssl/ssl_tlsext.c121
-rw-r--r--src/lib/libssl/ssl_tlsext.h10
-rw-r--r--src/lib/libssl/t1_lib.c76
-rw-r--r--src/regress/lib/libssl/tlsext/tlsexttest.c338
5 files changed, 472 insertions, 77 deletions
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 84bb6879b0..52e4b6c5e9 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.186 2017/08/11 17:54:41 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.187 2017/08/11 20:14:13 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 *
@@ -1382,6 +1382,8 @@ void SSL_error_internal(const SSL *s, int r, char *f, int l);
1382 1382
1383void tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, 1383void tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats,
1384 size_t *pformatslen); 1384 size_t *pformatslen);
1385void tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves,
1386 size_t *pcurveslen);
1385 1387
1386__END_HIDDEN_DECLS 1388__END_HIDDEN_DECLS
1387 1389
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c
index ad30f43389..c050224c70 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.5 2017/08/11 06:30:41 jsing Exp $ */ 1/* $OpenBSD: ssl_tlsext.c,v 1.6 2017/08/11 20:14:13 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 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -21,6 +21,116 @@
21#include "bytestring.h" 21#include "bytestring.h"
22#include "ssl_tlsext.h" 22#include "ssl_tlsext.h"
23 23
24
25/*
26 * Supported Elliptic Curves - RFC 4492 section 5.1.1
27 */
28int
29tlsext_ec_clienthello_needs(SSL *s)
30{
31 return ssl_has_ecc_ciphers(s);
32}
33
34int
35tlsext_ec_clienthello_build(SSL *s, CBB *cbb)
36{
37 CBB curvelist;
38 size_t curves_len;
39 int i;
40 const uint16_t *curves;
41
42 tls1_get_curvelist(s, 0, &curves, &curves_len);
43
44 if (curves_len == 0) {
45 SSLerror(s, ERR_R_INTERNAL_ERROR);
46 return 0;
47 }
48
49 if (!CBB_add_u16_length_prefixed(cbb, &curvelist))
50 return 0;
51
52 for (i = 0; i < curves_len; i++) {
53 if (!CBB_add_u16(&curvelist, curves[i]))
54 return 0;
55 }
56
57 if (!CBB_flush(cbb))
58 return 0;
59
60 return 1;
61}
62
63int
64tlsext_ec_clienthello_parse(SSL *s, CBS *cbs, int *alert)
65{
66 CBS curvelist;
67 size_t curves_len;
68
69 if (!CBS_get_u16_length_prefixed(cbs, &curvelist))
70 goto err;
71 if (CBS_len(cbs) != 0)
72 goto err;
73
74 curves_len = CBS_len(&curvelist);
75 if (curves_len == 0 || curves_len % 2 != 0)
76 goto err;
77 curves_len /= 2;
78
79 if (!s->internal->hit) {
80 int i;
81 uint16_t *curves;
82
83 if (SSI(s)->tlsext_supportedgroups != NULL)
84 goto err;
85
86 if ((curves = reallocarray(NULL, curves_len,
87 sizeof(uint16_t))) == NULL) {
88 *alert = TLS1_AD_INTERNAL_ERROR;
89 return 0;
90 }
91
92 for (i = 0; i < curves_len; i++) {
93 if (!CBS_get_u16(&curvelist, &curves[i])) {
94 free(curves);
95 goto err;
96 }
97 }
98
99 if (CBS_len(&curvelist) != 0) {
100 free(curves);
101 goto err;
102 }
103
104 SSI(s)->tlsext_supportedgroups = curves;
105 SSI(s)->tlsext_supportedgroups_length = curves_len;
106 }
107
108 return 1;
109
110 err:
111 *alert = TLS1_AD_DECODE_ERROR;
112 return 0;
113}
114
115/* This extension is never used by the server. */
116int
117tlsext_ec_serverhello_needs(SSL *s)
118{
119 return 0;
120}
121
122int
123tlsext_ec_serverhello_build(SSL *s, CBB *cbb)
124{
125 return 0;
126}
127
128int
129tlsext_ec_serverhello_parse(SSL *s, CBS *cbs, int *alert)
130{
131 return 0;
132}
133
24/* 134/*
25 * Supported Point Formats Extension - RFC 4492 section 5.1.2 135 * Supported Point Formats Extension - RFC 4492 section 5.1.2
26 */ 136 */
@@ -420,6 +530,15 @@ static struct tls_extension tls_extensions[] = {
420 .serverhello_build = tlsext_ecpf_serverhello_build, 530 .serverhello_build = tlsext_ecpf_serverhello_build,
421 .serverhello_parse = tlsext_ecpf_serverhello_parse, 531 .serverhello_parse = tlsext_ecpf_serverhello_parse,
422 }, 532 },
533 {
534 .type = TLSEXT_TYPE_elliptic_curves,
535 .clienthello_needs = tlsext_ec_clienthello_needs,
536 .clienthello_build = tlsext_ec_clienthello_build,
537 .clienthello_parse = tlsext_ec_clienthello_parse,
538 .serverhello_needs = tlsext_ec_serverhello_needs,
539 .serverhello_build = tlsext_ec_serverhello_build,
540 .serverhello_parse = tlsext_ec_serverhello_parse,
541 },
423}; 542};
424 543
425#define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) 544#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 6f79755f81..38f8ffaa65 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.4 2017/08/11 06:30:41 jsing Exp $ */ 1/* $OpenBSD: ssl_tlsext.h,v 1.5 2017/08/11 20:14:13 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 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -30,6 +30,13 @@ int tlsext_sni_serverhello_needs(SSL *s);
30int tlsext_sni_serverhello_build(SSL *s, CBB *cbb); 30int tlsext_sni_serverhello_build(SSL *s, CBB *cbb);
31int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert); 31int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert);
32 32
33int tlsext_ec_clienthello_needs(SSL *s);
34int tlsext_ec_clienthello_build(SSL *s, CBB *cbb);
35int tlsext_ec_clienthello_parse(SSL *s, CBS *cbs, int *alert);
36int tlsext_ec_serverhello_needs(SSL *s);
37int tlsext_ec_serverhello_build(SSL *s, CBB *cbb);
38int tlsext_ec_serverhello_parse(SSL *s, CBS *cbs, int *alert);
39
33int tlsext_ecpf_clienthello_needs(SSL *s); 40int tlsext_ecpf_clienthello_needs(SSL *s);
34int tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb); 41int tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb);
35int tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert); 42int tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert);
@@ -37,6 +44,7 @@ int tlsext_ecpf_serverhello_needs(SSL *s);
37int tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb); 44int tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb);
38int tlsext_ecpf_serverhello_parse(SSL *s, CBS *cbs, int *alert); 45int tlsext_ecpf_serverhello_parse(SSL *s, CBS *cbs, int *alert);
39 46
47
40int tlsext_clienthello_build(SSL *s, CBB *cbb); 48int tlsext_clienthello_build(SSL *s, CBB *cbb);
41int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, 49int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type,
42 int *alert); 50 int *alert);
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 2e90d3e9df..4983ad27fa 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.125 2017/08/11 05:06:34 doug Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.126 2017/08/11 20:14:13 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 *
@@ -365,7 +365,7 @@ tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats,
365 * the client/session curves. Otherwise return the custom curve list if one 365 * the client/session curves. Otherwise return the custom curve list if one
366 * exists, or the default curves if a custom list has not been specified. 366 * exists, or the default curves if a custom list has not been specified.
367 */ 367 */
368static void 368void
369tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves, 369tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves,
370 size_t *pcurveslen) 370 size_t *pcurveslen)
371{ 371{
@@ -674,12 +674,9 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
674{ 674{
675 int extdatalen = 0; 675 int extdatalen = 0;
676 unsigned char *ret = p; 676 unsigned char *ret = p;
677 int using_ecc;
678 size_t len; 677 size_t len;
679 CBB cbb; 678 CBB cbb;
680 679
681 using_ecc = ssl_has_ecc_ciphers(s);
682
683 ret += 2; 680 ret += 2;
684 if (ret >= limit) 681 if (ret >= limit)
685 return NULL; /* this really never occurs, but ... */ 682 return NULL; /* this really never occurs, but ... */
@@ -698,40 +695,6 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
698 return NULL; 695 return NULL;
699 ret += len; 696 ret += len;
700 697
701 if (using_ecc) {
702 size_t curveslen, lenmax;
703 const uint16_t *curves;
704 int i;
705
706 /*
707 * Add TLS extension EllipticCurves to the ClientHello message.
708 */
709 tls1_get_curvelist(s, 0, &curves, &curveslen);
710
711 if ((size_t)(limit - ret) < 6)
712 return NULL;
713
714 lenmax = limit - ret - 6;
715 if (curveslen * 2 > lenmax)
716 return NULL;
717 if (curveslen * 2 > 65532) {
718 SSLerror(s, ERR_R_INTERNAL_ERROR);
719 return NULL;
720 }
721
722 s2n(TLSEXT_TYPE_elliptic_curves, ret);
723 s2n((curveslen * 2) + 2, ret);
724
725 /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
726 * elliptic_curve_list, but the examples use two bytes.
727 * https://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
728 * resolves this to two bytes.
729 */
730 s2n(curveslen * 2, ret);
731 for (i = 0; i < curveslen; i++)
732 s2n(curves[i], ret);
733 }
734
735 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { 698 if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
736 int ticklen; 699 int ticklen;
737 if (!s->internal->new_session && s->session && s->session->tlsext_tick) 700 if (!s->internal->new_session && s->session && s->session->tlsext_tick)
@@ -1142,40 +1105,7 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
1142 if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) 1105 if (!tlsext_clienthello_parse_one(s, &cbs, type, al))
1143 return 0; 1106 return 0;
1144 1107
1145 if (type == TLSEXT_TYPE_elliptic_curves && 1108 if (type == TLSEXT_TYPE_session_ticket) {
1146 s->version != DTLS1_VERSION) {
1147 unsigned char *sdata = data;
1148 size_t curveslen, i;
1149 uint16_t *curves;
1150
1151 if (size < 2) {
1152 *al = TLS1_AD_DECODE_ERROR;
1153 return 0;
1154 }
1155 n2s(sdata, curveslen);
1156 if (curveslen != size - 2 || curveslen % 2 != 0) {
1157 *al = TLS1_AD_DECODE_ERROR;
1158 return 0;
1159 }
1160 curveslen /= 2;
1161
1162 if (!s->internal->hit) {
1163 if (SSI(s)->tlsext_supportedgroups) {
1164 *al = TLS1_AD_DECODE_ERROR;
1165 return 0;
1166 }
1167 SSI(s)->tlsext_supportedgroups_length = 0;
1168 if ((curves = reallocarray(NULL, curveslen,
1169 sizeof(uint16_t))) == NULL) {
1170 *al = TLS1_AD_INTERNAL_ERROR;
1171 return 0;
1172 }
1173 for (i = 0; i < curveslen; i++)
1174 n2s(sdata, curves[i]);
1175 SSI(s)->tlsext_supportedgroups = curves;
1176 SSI(s)->tlsext_supportedgroups_length = curveslen;
1177 }
1178 } else if (type == TLSEXT_TYPE_session_ticket) {
1179 if (s->internal->tls_session_ticket_ext_cb && 1109 if (s->internal->tls_session_ticket_ext_cb &&
1180 !s->internal->tls_session_ticket_ext_cb(s, data, size, s->internal->tls_session_ticket_ext_cb_arg)) { 1110 !s->internal->tls_session_ticket_ext_cb(s, data, size, s->internal->tls_session_ticket_ext_cb_arg)) {
1181 *al = TLS1_AD_INTERNAL_ERROR; 1111 *al = TLS1_AD_INTERNAL_ERROR;
diff --git a/src/regress/lib/libssl/tlsext/tlsexttest.c b/src/regress/lib/libssl/tlsext/tlsexttest.c
index 5a7a34c56c..4f9e6e29e2 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.4 2017/08/11 05:06:34 doug Exp $ */ 1/* $OpenBSD: tlsexttest.c,v 1.5 2017/08/11 20:14:13 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -34,6 +34,17 @@ hexdump(const unsigned char *buf, size_t len)
34} 34}
35 35
36static void 36static void
37hexdump2(const uint16_t *buf, size_t len)
38{
39 size_t i;
40
41 for (i = 1; i <= len / 2; i++)
42 fprintf(stderr, " 0x%04hx,%s", buf[i - 1], i % 8 ? "" : "\n");
43
44 fprintf(stderr, "\n");
45}
46
47static void
37compare_data(const uint8_t *recv, size_t recv_len, const uint8_t *expect, 48compare_data(const uint8_t *recv, size_t recv_len, const uint8_t *expect,
38 size_t expect_len) 49 size_t expect_len)
39{ 50{
@@ -44,6 +55,17 @@ compare_data(const uint8_t *recv, size_t recv_len, const uint8_t *expect,
44 hexdump(expect, expect_len); 55 hexdump(expect, expect_len);
45} 56}
46 57
58static void
59compare_data2(const uint16_t *recv, size_t recv_len, const uint16_t *expect,
60 size_t expect_len)
61{
62 fprintf(stderr, "received:\n");
63 hexdump2(recv, recv_len);
64
65 fprintf(stderr, "test data:\n");
66 hexdump2(expect, expect_len);
67}
68
47#define FAIL(msg, ...) \ 69#define FAIL(msg, ...) \
48do { \ 70do { \
49 fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ 71 fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \
@@ -988,6 +1010,317 @@ test_tlsext_ecpf_serverhello(void)
988 return (failure); 1010 return (failure);
989} 1011}
990 1012
1013/*
1014 * ellliptic_curves - RFC 4492 section 5.1.1 (Supported Elliptic Curves).
1015 *
1016 * This extension is only used by the client.
1017 */
1018
1019static uint8_t tlsext_ec_clienthello_default[] = {
1020 0x00, 0x06,
1021 0x00, 0x1d, /* X25519 (29) */
1022 0x00, 0x17, /* secp256r1 (23) */
1023 0x00, 0x18 /* secp384r1 (24) */
1024};
1025
1026static uint16_t tlsext_ec_clienthello_secp384r1_val[] = {
1027 0x0018 /* tls1_ec_nid2curve_id(NID_secp384r1) */
1028};
1029static uint8_t tlsext_ec_clienthello_secp384r1[] = {
1030 0x00, 0x02,
1031 0x00, 0x18 /* secp384r1 (24) */
1032};
1033
1034/* Example from RFC 4492 section 5.1.1 */
1035static uint16_t tlsext_ec_clienthello_nistp192and224_val[] = {
1036 0x0013, /* tls1_ec_nid2curve_id(NID_X9_62_prime192v1) */
1037 0x0015 /* tls1_ec_nid2curve_id(NID_secp224r1) */
1038};
1039static uint8_t tlsext_ec_clienthello_nistp192and224[] = {
1040 0x00, 0x04,
1041 0x00, 0x13, /* secp192r1 aka NIST P-192 */
1042 0x00, 0x15 /* secp224r1 aka NIST P-224 */
1043};
1044
1045static int
1046test_tlsext_ec_clienthello(void)
1047{
1048 unsigned char *data = NULL;
1049 SSL_CTX *ssl_ctx = NULL;
1050 SSL *ssl = NULL;
1051 size_t dlen;
1052 int failure, alert;
1053 CBB cbb;
1054 CBS cbs;
1055
1056 failure = 1;
1057
1058 CBB_init(&cbb, 0);
1059
1060 if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL)
1061 errx(1, "failed to create SSL_CTX");
1062 if ((ssl = SSL_new(ssl_ctx)) == NULL)
1063 errx(1, "failed to create SSL");
1064
1065 /*
1066 * Default ciphers include EC so we need it by default.
1067 */
1068 if (!tlsext_ec_clienthello_needs(ssl)) {
1069 FAIL("clienthello should need Ellipticcurves for default "
1070 "ciphers\n");
1071 goto err;
1072 }
1073
1074 /*
1075 * Exclude cipher suites so we can test not including it.
1076 */
1077 if (!SSL_set_cipher_list(ssl, "TLSv1.2:!ECDHE:!ECDSA")) {
1078 FAIL("clienthello should be able to set cipher list\n");
1079 goto err;
1080 }
1081 if (tlsext_ec_clienthello_needs(ssl)) {
1082 FAIL("clienthello should not need Ellipticcurves\n");
1083 goto err;
1084 }
1085
1086 /*
1087 * Use libtls default for the rest of the testing
1088 */
1089 if (!SSL_set_cipher_list(ssl, "TLSv1.2+AEAD+ECDHE")) {
1090 FAIL("clienthello should be able to set cipher list\n");
1091 goto err;
1092 }
1093 if (!tlsext_ec_clienthello_needs(ssl)) {
1094 FAIL("clienthello should need Ellipticcurves\n");
1095 goto err;
1096 }
1097
1098 /*
1099 * Test with a session secp384r1. The default is used instead.
1100 */
1101 if ((ssl->session = SSL_SESSION_new()) == NULL)
1102 errx(1, "failed to create session");
1103
1104 if ((SSI(ssl)->tlsext_supportedgroups = malloc(sizeof(uint16_t)))
1105 == NULL) {
1106 FAIL("client could not malloc\n");
1107 goto err;
1108 }
1109 SSI(ssl)->tlsext_supportedgroups[0] = tls1_ec_nid2curve_id(NID_secp384r1);
1110 SSI(ssl)->tlsext_supportedgroups_length = 1;
1111
1112 if (!tlsext_ec_clienthello_needs(ssl)) {
1113 FAIL("clienthello should need Ellipticcurves\n");
1114 goto err;
1115 }
1116
1117 if (!tlsext_ec_clienthello_build(ssl, &cbb)) {
1118 FAIL("clienthello failed to build Ellipticcurves\n");
1119 goto err;
1120 }
1121
1122 if (!CBB_finish(&cbb, &data, &dlen))
1123 errx(1, "failed to finish CBB");
1124
1125 if (dlen != sizeof(tlsext_ec_clienthello_default)) {
1126 FAIL("got clienthello Ellipticcurves with length %zu, "
1127 "want length %zu\n", dlen,
1128 sizeof(tlsext_ec_clienthello_default));
1129 compare_data(data, dlen, tlsext_ec_clienthello_default,
1130 sizeof(tlsext_ec_clienthello_default));
1131 goto err;
1132 }
1133
1134 if (memcmp(data, tlsext_ec_clienthello_default, dlen) != 0) {
1135 FAIL("clienthello Ellipticcurves differs:\n");
1136 compare_data(data, dlen, tlsext_ec_clienthello_default,
1137 sizeof(tlsext_ec_clienthello_default));
1138 goto err;
1139 }
1140
1141 /*
1142 * Test parsing secp384r1
1143 */
1144 CBB_cleanup(&cbb);
1145 CBB_init(&cbb, 0);
1146 free(data);
1147 data = NULL;
1148
1149 SSL_SESSION_free(ssl->session);
1150 if ((ssl->session = SSL_SESSION_new()) == NULL)
1151 errx(1, "failed to create session");
1152
1153 CBS_init(&cbs, tlsext_ec_clienthello_secp384r1,
1154 sizeof(tlsext_ec_clienthello_secp384r1));
1155 if (!tlsext_ec_clienthello_parse(ssl, &cbs, &alert)) {
1156 FAIL("failed to parse clienthello Ellipticcurves\n");
1157 goto err;
1158 }
1159
1160 if (SSI(ssl)->tlsext_supportedgroups_length !=
1161 sizeof(tlsext_ec_clienthello_secp384r1_val) / sizeof(uint16_t)) {
1162 FAIL("no tlsext_ellipticcurves from clienthello "
1163 "Ellipticcurves\n");
1164 goto err;
1165 }
1166
1167 if (memcmp(SSI(ssl)->tlsext_supportedgroups,
1168 tlsext_ec_clienthello_secp384r1_val,
1169 sizeof(tlsext_ec_clienthello_secp384r1_val)) != 0) {
1170 FAIL("clienthello had an incorrect Ellipticcurves "
1171 "entry\n");
1172 compare_data2(SSI(ssl)->tlsext_supportedgroups,
1173 SSI(ssl)->tlsext_supportedgroups_length * 2,
1174 tlsext_ec_clienthello_secp384r1_val,
1175 sizeof(tlsext_ec_clienthello_secp384r1_val));
1176 goto err;
1177 }
1178
1179 /*
1180 * Use a custom order.
1181 */
1182 CBB_cleanup(&cbb);
1183 CBB_init(&cbb, 0);
1184
1185 SSL_SESSION_free(ssl->session);
1186 if ((ssl->session = SSL_SESSION_new()) == NULL)
1187 errx(1, "failed to create session");
1188
1189 if ((ssl->internal->tlsext_supportedgroups = malloc(sizeof(uint16_t) * 2)) == NULL) {
1190 FAIL("client could not malloc\n");
1191 goto err;
1192 }
1193 ssl->internal->tlsext_supportedgroups[0] = tls1_ec_nid2curve_id(NID_X9_62_prime192v1);
1194 ssl->internal->tlsext_supportedgroups[1] = tls1_ec_nid2curve_id(NID_secp224r1);
1195 ssl->internal->tlsext_supportedgroups_length = 2;
1196
1197 if (!tlsext_ec_clienthello_needs(ssl)) {
1198 FAIL("clienthello should need Ellipticcurves\n");
1199 goto err;
1200 }
1201
1202 if (!tlsext_ec_clienthello_build(ssl, &cbb)) {
1203 FAIL("clienthello failed to build Ellipticcurves\n");
1204 goto err;
1205 }
1206
1207 if (!CBB_finish(&cbb, &data, &dlen))
1208 errx(1, "failed to finish CBB");
1209
1210 if (dlen != sizeof(tlsext_ec_clienthello_nistp192and224)) {
1211 FAIL("got clienthello Ellipticcurves with length %zu, "
1212 "want length %zu\n", dlen,
1213 sizeof(tlsext_ec_clienthello_nistp192and224));
1214 fprintf(stderr, "received:\n");
1215 hexdump(data, dlen);
1216 fprintf(stderr, "test data:\n");
1217 hexdump(tlsext_ec_clienthello_nistp192and224,
1218 sizeof(tlsext_ec_clienthello_nistp192and224));
1219 goto err;
1220 }
1221
1222 if (memcmp(data, tlsext_ec_clienthello_nistp192and224, dlen) != 0) {
1223 FAIL("clienthello Ellipticcurves differs:\n");
1224 fprintf(stderr, "received:\n");
1225 hexdump(data, dlen);
1226 fprintf(stderr, "test data:\n");
1227 hexdump(tlsext_ec_clienthello_nistp192and224,
1228 sizeof(tlsext_ec_clienthello_nistp192and224));
1229 goto err;
1230 }
1231
1232 /*
1233 * Parse non-default curves to session.
1234 */
1235 CBB_cleanup(&cbb);
1236 CBB_init(&cbb, 0);
1237 free(data);
1238 data = NULL;
1239
1240 SSL_SESSION_free(ssl->session);
1241 if ((ssl->session = SSL_SESSION_new()) == NULL)
1242 errx(1, "failed to create session");
1243
1244 /* Reset back to the default list. */
1245 free(ssl->internal->tlsext_supportedgroups);
1246 ssl->internal->tlsext_supportedgroups = NULL;
1247 ssl->internal->tlsext_supportedgroups_length = 0;
1248
1249 CBS_init(&cbs, tlsext_ec_clienthello_nistp192and224,
1250 sizeof(tlsext_ec_clienthello_nistp192and224));
1251 if (!tlsext_ec_clienthello_parse(ssl, &cbs, &alert)) {
1252 FAIL("failed to parse clienthello Ellipticcurves\n");
1253 goto err;
1254 }
1255
1256 if (SSI(ssl)->tlsext_supportedgroups_length !=
1257 sizeof(tlsext_ec_clienthello_nistp192and224_val) / sizeof(uint16_t)) {
1258 FAIL("no tlsext_ellipticcurves from clienthello "
1259 "Ellipticcurves\n");
1260 goto err;
1261 }
1262
1263 if (memcmp(SSI(ssl)->tlsext_supportedgroups,
1264 tlsext_ec_clienthello_nistp192and224_val,
1265 sizeof(tlsext_ec_clienthello_nistp192and224_val)) != 0) {
1266 FAIL("clienthello had an incorrect Ellipticcurves entry\n");
1267 compare_data2(SSI(ssl)->tlsext_supportedgroups,
1268 SSI(ssl)->tlsext_supportedgroups_length * 2,
1269 tlsext_ec_clienthello_nistp192and224_val,
1270 sizeof(tlsext_ec_clienthello_nistp192and224_val));
1271 goto err;
1272 }
1273
1274 failure = 0;
1275
1276 err:
1277 CBB_cleanup(&cbb);
1278 SSL_CTX_free(ssl_ctx);
1279 SSL_free(ssl);
1280 free(data);
1281
1282 return (failure);
1283}
1284
1285
1286/* elliptic_curves is only used by the client so this doesn't test much. */
1287static int
1288test_tlsext_ec_serverhello(void)
1289{
1290 SSL_CTX *ssl_ctx = NULL;
1291 SSL *ssl = NULL;
1292 int failure;
1293
1294 failure = 1;
1295
1296 if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL)
1297 errx(1, "failed to create SSL_CTX");
1298 if ((ssl = SSL_new(ssl_ctx)) == NULL)
1299 errx(1, "failed to create SSL");
1300
1301 if (tlsext_ec_serverhello_needs(ssl)) {
1302 FAIL("serverhello should not need elliptic_curves\n");
1303 goto err;
1304 }
1305
1306 if ((ssl->session = SSL_SESSION_new()) == NULL)
1307 errx(1, "failed to create session");
1308
1309 if (tlsext_ec_serverhello_needs(ssl)) {
1310 FAIL("serverhello should not need elliptic_curves\n");
1311 goto err;
1312 }
1313
1314 failure = 0;
1315
1316 err:
1317 SSL_CTX_free(ssl_ctx);
1318 SSL_free(ssl);
1319
1320 return (failure);
1321
1322}
1323
991int 1324int
992main(int argc, char **argv) 1325main(int argc, char **argv)
993{ 1326{
@@ -1004,5 +1337,8 @@ main(int argc, char **argv)
1004 failed |= test_tlsext_ecpf_clienthello(); 1337 failed |= test_tlsext_ecpf_clienthello();
1005 failed |= test_tlsext_ecpf_serverhello(); 1338 failed |= test_tlsext_ecpf_serverhello();
1006 1339
1340 failed |= test_tlsext_ec_clienthello();
1341 failed |= test_tlsext_ec_serverhello();
1342
1007 return (failed); 1343 return (failed);
1008} 1344}