summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authordoug <>2017-08-11 05:06:34 +0000
committerdoug <>2017-08-11 05:06:34 +0000
commit2c7289aaf0a5e656e3db4ad3e101b1dd3e2dc610 (patch)
treecf9f734a8e9d38d5af29ff18c56720f241220b61 /src/lib
parentae58363a3ade3f9016687060c0c4efe3702141f8 (diff)
downloadopenbsd-2c7289aaf0a5e656e3db4ad3e101b1dd3e2dc610.tar.gz
openbsd-2c7289aaf0a5e656e3db4ad3e101b1dd3e2dc610.tar.bz2
openbsd-2c7289aaf0a5e656e3db4ad3e101b1dd3e2dc610.zip
Rewrite the ECPointFormats TLS extension handling using CBB/CBS and the
new extension framework. input + ok jsing@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/ssl_locl.h5
-rw-r--r--src/lib/libssl/ssl_tlsext.c108
-rw-r--r--src/lib/libssl/ssl_tlsext.h9
-rw-r--r--src/lib/libssl/t1_lib.c150
4 files changed, 125 insertions, 147 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__)
1381void SSL_error_internal(const SSL *s, int r, char *f, int l); 1381void 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,
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 */
26static int
27tlsext_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
50static int
51tlsext_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
81int
82tlsext_ecpf_clienthello_needs(SSL *s)
83{
84 return ssl_has_ecc_ciphers(s);
85}
86
87int
88tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb)
89{
90 return tlsext_ecpf_build(s, cbb);
91}
92
93int
94tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert)
95{
96 return tlsext_ecpf_parse(s, cbs, alert);
97}
98
99int
100tlsext_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
108int
109tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb)
110{
111 return tlsext_ecpf_build(s, cbb);
112}
113
114int
115tlsext_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 */
26int 123int
@@ -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);
29int tlsext_sni_serverhello_build(SSL *s, CBB *cbb); 29int tlsext_sni_serverhello_build(SSL *s, CBB *cbb);
30int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert); 30int tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert);
31 31
32int tlsext_ecpf_clienthello_needs(SSL *s);
33int tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb);
34int tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert);
35int tlsext_ecpf_serverhello_needs(SSL *s);
36int tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb);
37int tlsext_ecpf_serverhello_parse(SSL *s, CBS *cbs, int *alert);
38
32int tlsext_clienthello_build(SSL *s, CBB *cbb); 39int tlsext_clienthello_build(SSL *s, CBB *cbb);
33int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, 40int 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 */
345static void 345void
346tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, 346tls1_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:
931unsigned char * 908unsigned char *
932ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) 909ssl_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)