diff options
Diffstat (limited to 'src/lib/libssl/ssl_tlsext.c')
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 121 |
1 files changed, 120 insertions, 1 deletions
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 | */ | ||
28 | int | ||
29 | tlsext_ec_clienthello_needs(SSL *s) | ||
30 | { | ||
31 | return ssl_has_ecc_ciphers(s); | ||
32 | } | ||
33 | |||
34 | int | ||
35 | tlsext_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 | |||
63 | int | ||
64 | tlsext_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. */ | ||
116 | int | ||
117 | tlsext_ec_serverhello_needs(SSL *s) | ||
118 | { | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | int | ||
123 | tlsext_ec_serverhello_build(SSL *s, CBB *cbb) | ||
124 | { | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | int | ||
129 | tlsext_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)) |