1 |
|
|
/* $OpenBSD: ssl_tlsext.c,v 1.17 2017/09/25 18:02:27 jsing Exp $ */ |
2 |
|
|
/* |
3 |
|
|
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
4 |
|
|
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
5 |
|
|
* Copyright (c) 2017 Bob Beck <beck@openbsd.org> |
6 |
|
|
* |
7 |
|
|
* Permission to use, copy, modify, and distribute this software for any |
8 |
|
|
* purpose with or without fee is hereby granted, provided that the above |
9 |
|
|
* copyright notice and this permission notice appear in all copies. |
10 |
|
|
* |
11 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 |
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 |
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 |
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 |
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 |
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 |
|
|
*/ |
19 |
|
|
#include <openssl/ocsp.h> |
20 |
|
|
|
21 |
|
|
#include "ssl_locl.h" |
22 |
|
|
|
23 |
|
|
#include "bytestring.h" |
24 |
|
|
#include "ssl_tlsext.h" |
25 |
|
|
|
26 |
|
|
/* |
27 |
|
|
* Supported Application-Layer Protocol Negotiation - RFC 7301 |
28 |
|
|
*/ |
29 |
|
|
|
30 |
|
|
int |
31 |
|
|
tlsext_alpn_clienthello_needs(SSL *s) |
32 |
|
|
{ |
33 |
|
|
/* ALPN protos have been specified and this is the initial handshake */ |
34 |
✓✓ |
24711 |
return s->internal->alpn_client_proto_list != NULL && |
35 |
|
42 |
S3I(s)->tmp.finish_md_len == 0; |
36 |
|
|
} |
37 |
|
|
|
38 |
|
|
int |
39 |
|
|
tlsext_alpn_clienthello_build(SSL *s, CBB *cbb) |
40 |
|
|
{ |
41 |
|
84 |
CBB protolist; |
42 |
|
|
|
43 |
✗✓ |
42 |
if (!CBB_add_u16_length_prefixed(cbb, &protolist)) |
44 |
|
|
return 0; |
45 |
|
|
|
46 |
✗✓ |
84 |
if (!CBB_add_bytes(&protolist, s->internal->alpn_client_proto_list, |
47 |
|
42 |
s->internal->alpn_client_proto_list_len)) |
48 |
|
|
return 0; |
49 |
|
|
|
50 |
✗✓ |
42 |
if (!CBB_flush(cbb)) |
51 |
|
|
return 0; |
52 |
|
|
|
53 |
|
42 |
return 1; |
54 |
|
42 |
} |
55 |
|
|
|
56 |
|
|
int |
57 |
|
|
tlsext_alpn_clienthello_parse(SSL *s, CBS *cbs, int *alert) |
58 |
|
|
{ |
59 |
|
102 |
CBS proto_name_list, alpn; |
60 |
|
51 |
const unsigned char *selected; |
61 |
|
51 |
unsigned char selected_len; |
62 |
|
|
int r; |
63 |
|
|
|
64 |
✓✓ |
51 |
if (!CBS_get_u16_length_prefixed(cbs, &alpn)) |
65 |
|
|
goto err; |
66 |
✓✓ |
48 |
if (CBS_len(&alpn) < 2) |
67 |
|
|
goto err; |
68 |
✓✓ |
47 |
if (CBS_len(cbs) != 0) |
69 |
|
|
goto err; |
70 |
|
|
|
71 |
|
46 |
CBS_dup(&alpn, &proto_name_list); |
72 |
✓✓ |
167 |
while (CBS_len(&proto_name_list) > 0) { |
73 |
|
77 |
CBS proto_name; |
74 |
|
|
|
75 |
✓✓ |
77 |
if (!CBS_get_u8_length_prefixed(&proto_name_list, &proto_name)) |
76 |
|
2 |
goto err; |
77 |
✗✓ |
75 |
if (CBS_len(&proto_name) == 0) |
78 |
|
|
goto err; |
79 |
✓✓✓ |
217 |
} |
80 |
|
|
|
81 |
✓✓ |
44 |
if (s->ctx->internal->alpn_select_cb == NULL) |
82 |
|
8 |
return 1; |
83 |
|
|
|
84 |
|
36 |
r = s->ctx->internal->alpn_select_cb(s, &selected, &selected_len, |
85 |
|
36 |
CBS_data(&alpn), CBS_len(&alpn), |
86 |
|
36 |
s->ctx->internal->alpn_select_cb_arg); |
87 |
✓✓ |
36 |
if (r == SSL_TLSEXT_ERR_OK) { |
88 |
|
28 |
free(S3I(s)->alpn_selected); |
89 |
✗✓ |
28 |
if ((S3I(s)->alpn_selected = malloc(selected_len)) == NULL) { |
90 |
|
|
*alert = SSL_AD_INTERNAL_ERROR; |
91 |
|
|
return 0; |
92 |
|
|
} |
93 |
|
28 |
memcpy(S3I(s)->alpn_selected, selected, selected_len); |
94 |
|
28 |
S3I(s)->alpn_selected_len = selected_len; |
95 |
|
28 |
} |
96 |
|
|
|
97 |
|
36 |
return 1; |
98 |
|
|
|
99 |
|
|
err: |
100 |
|
7 |
*alert = SSL_AD_DECODE_ERROR; |
101 |
|
7 |
return 0; |
102 |
|
51 |
} |
103 |
|
|
|
104 |
|
|
int |
105 |
|
|
tlsext_alpn_serverhello_needs(SSL *s) |
106 |
|
|
{ |
107 |
|
552 |
return S3I(s)->alpn_selected != NULL; |
108 |
|
|
} |
109 |
|
|
|
110 |
|
|
int |
111 |
|
|
tlsext_alpn_serverhello_build(SSL *s, CBB *cbb) |
112 |
|
|
{ |
113 |
|
56 |
CBB list, selected; |
114 |
|
|
|
115 |
✗✓ |
28 |
if (!CBB_add_u16_length_prefixed(cbb, &list)) |
116 |
|
|
return 0; |
117 |
|
|
|
118 |
✗✓ |
28 |
if (!CBB_add_u8_length_prefixed(&list, &selected)) |
119 |
|
|
return 0; |
120 |
|
|
|
121 |
✗✓ |
56 |
if (!CBB_add_bytes(&selected, S3I(s)->alpn_selected, |
122 |
|
28 |
S3I(s)->alpn_selected_len)) |
123 |
|
|
return 0; |
124 |
|
|
|
125 |
✗✓ |
28 |
if (!CBB_flush(cbb)) |
126 |
|
|
return 0; |
127 |
|
|
|
128 |
|
28 |
return 1; |
129 |
|
28 |
} |
130 |
|
|
|
131 |
|
|
int |
132 |
|
|
tlsext_alpn_serverhello_parse(SSL *s, CBS *cbs, int *alert) |
133 |
|
|
{ |
134 |
|
90 |
CBS list, proto; |
135 |
|
|
|
136 |
✓✓ |
45 |
if (s->internal->alpn_client_proto_list == NULL) { |
137 |
|
4 |
*alert = TLS1_AD_UNSUPPORTED_EXTENSION; |
138 |
|
4 |
return 0; |
139 |
|
|
} |
140 |
|
|
|
141 |
✓✓ |
41 |
if (!CBS_get_u16_length_prefixed(cbs, &list)) |
142 |
|
|
goto err; |
143 |
✓✓ |
38 |
if (CBS_len(cbs) != 0) |
144 |
|
|
goto err; |
145 |
|
|
|
146 |
✓✓ |
37 |
if (!CBS_get_u8_length_prefixed(&list, &proto)) |
147 |
|
|
goto err; |
148 |
|
|
|
149 |
✓✓ |
36 |
if (CBS_len(&list) != 0) |
150 |
|
|
goto err; |
151 |
✓✓ |
32 |
if (CBS_len(&proto) == 0) |
152 |
|
|
goto err; |
153 |
|
|
|
154 |
✓✗ |
62 |
if (!CBS_stow(&proto, &(S3I(s)->alpn_selected), |
155 |
|
31 |
&(S3I(s)->alpn_selected_len))) |
156 |
|
|
goto err; |
157 |
|
|
|
158 |
|
31 |
return 1; |
159 |
|
|
|
160 |
|
|
err: |
161 |
|
10 |
*alert = TLS1_AD_DECODE_ERROR; |
162 |
|
10 |
return 0; |
163 |
|
45 |
} |
164 |
|
|
|
165 |
|
|
/* |
166 |
|
|
* Supported Elliptic Curves - RFC 4492 section 5.1.1 |
167 |
|
|
*/ |
168 |
|
|
int |
169 |
|
|
tlsext_ec_clienthello_needs(SSL *s) |
170 |
|
|
{ |
171 |
|
16482 |
return ssl_has_ecc_ciphers(s); |
172 |
|
|
} |
173 |
|
|
|
174 |
|
|
int |
175 |
|
|
tlsext_ec_clienthello_build(SSL *s, CBB *cbb) |
176 |
|
|
{ |
177 |
|
16162 |
CBB curvelist; |
178 |
|
8081 |
size_t curves_len; |
179 |
|
|
int i; |
180 |
|
8081 |
const uint16_t *curves; |
181 |
|
|
|
182 |
|
8081 |
tls1_get_curvelist(s, 0, &curves, &curves_len); |
183 |
|
|
|
184 |
✗✓ |
8081 |
if (curves_len == 0) { |
185 |
|
|
SSLerror(s, ERR_R_INTERNAL_ERROR); |
186 |
|
|
return 0; |
187 |
|
|
} |
188 |
|
|
|
189 |
✗✓ |
8081 |
if (!CBB_add_u16_length_prefixed(cbb, &curvelist)) |
190 |
|
|
return 0; |
191 |
|
|
|
192 |
✓✓ |
64640 |
for (i = 0; i < curves_len; i++) { |
193 |
✗✓ |
24239 |
if (!CBB_add_u16(&curvelist, curves[i])) |
194 |
|
|
return 0; |
195 |
|
|
} |
196 |
|
|
|
197 |
✗✓ |
8081 |
if (!CBB_flush(cbb)) |
198 |
|
|
return 0; |
199 |
|
|
|
200 |
|
8081 |
return 1; |
201 |
|
8081 |
} |
202 |
|
|
|
203 |
|
|
int |
204 |
|
|
tlsext_ec_clienthello_parse(SSL *s, CBS *cbs, int *alert) |
205 |
|
|
{ |
206 |
|
240 |
CBS curvelist; |
207 |
|
|
size_t curves_len; |
208 |
|
|
|
209 |
✓✗ |
120 |
if (!CBS_get_u16_length_prefixed(cbs, &curvelist)) |
210 |
|
|
goto err; |
211 |
✓✗ |
120 |
if (CBS_len(cbs) != 0) |
212 |
|
|
goto err; |
213 |
|
|
|
214 |
|
120 |
curves_len = CBS_len(&curvelist); |
215 |
✓✗✓✗
|
240 |
if (curves_len == 0 || curves_len % 2 != 0) |
216 |
|
|
goto err; |
217 |
|
120 |
curves_len /= 2; |
218 |
|
|
|
219 |
✓✗ |
120 |
if (!s->internal->hit) { |
220 |
|
|
int i; |
221 |
|
|
uint16_t *curves; |
222 |
|
|
|
223 |
✗✓ |
120 |
if (SSI(s)->tlsext_supportedgroups != NULL) |
224 |
|
|
goto err; |
225 |
|
|
|
226 |
✗✓ |
240 |
if ((curves = reallocarray(NULL, curves_len, |
227 |
|
120 |
sizeof(uint16_t))) == NULL) { |
228 |
|
|
*alert = TLS1_AD_INTERNAL_ERROR; |
229 |
|
|
return 0; |
230 |
|
|
} |
231 |
|
|
|
232 |
✓✓ |
936 |
for (i = 0; i < curves_len; i++) { |
233 |
✗✓ |
348 |
if (!CBS_get_u16(&curvelist, &curves[i])) { |
234 |
|
|
free(curves); |
235 |
|
|
goto err; |
236 |
|
|
} |
237 |
|
|
} |
238 |
|
|
|
239 |
✗✓ |
120 |
if (CBS_len(&curvelist) != 0) { |
240 |
|
|
free(curves); |
241 |
|
|
goto err; |
242 |
|
|
} |
243 |
|
|
|
244 |
|
120 |
SSI(s)->tlsext_supportedgroups = curves; |
245 |
|
120 |
SSI(s)->tlsext_supportedgroups_length = curves_len; |
246 |
✓✗✓ |
120 |
} |
247 |
|
|
|
248 |
|
120 |
return 1; |
249 |
|
|
|
250 |
|
|
err: |
251 |
|
|
*alert = TLS1_AD_DECODE_ERROR; |
252 |
|
|
return 0; |
253 |
|
120 |
} |
254 |
|
|
|
255 |
|
|
/* This extension is never used by the server. */ |
256 |
|
|
int |
257 |
|
|
tlsext_ec_serverhello_needs(SSL *s) |
258 |
|
|
{ |
259 |
|
544 |
return 0; |
260 |
|
|
} |
261 |
|
|
|
262 |
|
|
int |
263 |
|
|
tlsext_ec_serverhello_build(SSL *s, CBB *cbb) |
264 |
|
|
{ |
265 |
|
|
return 0; |
266 |
|
|
} |
267 |
|
|
|
268 |
|
|
int |
269 |
|
|
tlsext_ec_serverhello_parse(SSL *s, CBS *cbs, int *alert) |
270 |
|
|
{ |
271 |
|
|
/* |
272 |
|
|
* Servers should not send this extension per the RFC. |
273 |
|
|
* |
274 |
|
|
* However, F5 sends it by mistake (case ID 492780) so we need to skip |
275 |
|
|
* over it. This bug is from at least 2014 but as of 2017, there |
276 |
|
|
* are still large sites with this bug in production. |
277 |
|
|
* |
278 |
|
|
* https://devcentral.f5.com/questions/disable-supported-elliptic-curves-extension-from-server |
279 |
|
|
*/ |
280 |
|
|
if (!CBS_skip(cbs, CBS_len(cbs))) { |
281 |
|
|
*alert = TLS1_AD_INTERNAL_ERROR; |
282 |
|
|
return 0; |
283 |
|
|
} |
284 |
|
|
|
285 |
|
|
return 1; |
286 |
|
|
} |
287 |
|
|
|
288 |
|
|
/* |
289 |
|
|
* Supported Point Formats Extension - RFC 4492 section 5.1.2 |
290 |
|
|
*/ |
291 |
|
|
static int |
292 |
|
|
tlsext_ecpf_build(SSL *s, CBB *cbb) |
293 |
|
|
{ |
294 |
|
16402 |
CBB ecpf; |
295 |
|
8201 |
size_t formats_len; |
296 |
|
8201 |
const uint8_t *formats; |
297 |
|
|
|
298 |
|
8201 |
tls1_get_formatlist(s, 0, &formats, &formats_len); |
299 |
|
|
|
300 |
✗✓ |
8201 |
if (formats_len == 0) { |
301 |
|
|
SSLerror(s, ERR_R_INTERNAL_ERROR); |
302 |
|
|
return 0; |
303 |
|
|
} |
304 |
|
|
|
305 |
✗✓ |
8201 |
if (!CBB_add_u8_length_prefixed(cbb, &ecpf)) |
306 |
|
|
return 0; |
307 |
✗✓ |
8201 |
if (!CBB_add_bytes(&ecpf, formats, formats_len)) |
308 |
|
|
return 0; |
309 |
✗✓ |
8201 |
if (!CBB_flush(cbb)) |
310 |
|
|
return 0; |
311 |
|
|
|
312 |
|
8201 |
return 1; |
313 |
|
8201 |
} |
314 |
|
|
|
315 |
|
|
static int |
316 |
|
|
tlsext_ecpf_parse(SSL *s, CBS *cbs, int *alert) |
317 |
|
|
{ |
318 |
|
2238 |
CBS ecpf; |
319 |
|
|
|
320 |
✓✗ |
1119 |
if (!CBS_get_u8_length_prefixed(cbs, &ecpf)) |
321 |
|
|
goto err; |
322 |
✓✗ |
1119 |
if (CBS_len(&ecpf) == 0) |
323 |
|
|
goto err; |
324 |
✓✗ |
1119 |
if (CBS_len(cbs) != 0) |
325 |
|
|
goto err; |
326 |
|
|
|
327 |
|
|
/* Must contain uncompressed (0) */ |
328 |
✓✓ |
1119 |
if (!CBS_contains_zero_byte(&ecpf)) { |
329 |
|
4 |
SSLerror(s, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); |
330 |
|
4 |
goto err; |
331 |
|
|
} |
332 |
|
|
|
333 |
✓✗ |
1115 |
if (!s->internal->hit) { |
334 |
✓✗ |
2230 |
if (!CBS_stow(&ecpf, &(SSI(s)->tlsext_ecpointformatlist), |
335 |
|
1115 |
&(SSI(s)->tlsext_ecpointformatlist_length))) |
336 |
|
|
goto err; |
337 |
|
|
} |
338 |
|
|
|
339 |
|
1115 |
return 1; |
340 |
|
|
|
341 |
|
|
err: |
342 |
|
4 |
*alert = TLS1_AD_INTERNAL_ERROR; |
343 |
|
4 |
return 0; |
344 |
|
1119 |
} |
345 |
|
|
|
346 |
|
|
int |
347 |
|
|
tlsext_ecpf_clienthello_needs(SSL *s) |
348 |
|
|
{ |
349 |
|
16474 |
return ssl_has_ecc_ciphers(s); |
350 |
|
|
} |
351 |
|
|
|
352 |
|
|
int |
353 |
|
|
tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb) |
354 |
|
|
{ |
355 |
|
16162 |
return tlsext_ecpf_build(s, cbb); |
356 |
|
|
} |
357 |
|
|
|
358 |
|
|
int |
359 |
|
|
tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert) |
360 |
|
|
{ |
361 |
|
240 |
return tlsext_ecpf_parse(s, cbs, alert); |
362 |
|
|
} |
363 |
|
|
|
364 |
|
|
int |
365 |
|
|
tlsext_ecpf_serverhello_needs(SSL *s) |
366 |
|
|
{ |
367 |
✓✓ |
544 |
if (s->version == DTLS1_VERSION) |
368 |
|
48 |
return 0; |
369 |
|
|
|
370 |
|
224 |
return ssl_using_ecc_cipher(s); |
371 |
|
272 |
} |
372 |
|
|
|
373 |
|
|
int |
374 |
|
|
tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb) |
375 |
|
|
{ |
376 |
|
240 |
return tlsext_ecpf_build(s, cbb); |
377 |
|
|
} |
378 |
|
|
|
379 |
|
|
int |
380 |
|
|
tlsext_ecpf_serverhello_parse(SSL *s, CBS *cbs, int *alert) |
381 |
|
|
{ |
382 |
|
1998 |
return tlsext_ecpf_parse(s, cbs, alert); |
383 |
|
|
} |
384 |
|
|
|
385 |
|
|
/* |
386 |
|
|
* Renegotiation Indication - RFC 5746. |
387 |
|
|
*/ |
388 |
|
|
int |
389 |
|
|
tlsext_ri_clienthello_needs(SSL *s) |
390 |
|
|
{ |
391 |
|
16458 |
return (s->internal->renegotiate); |
392 |
|
|
} |
393 |
|
|
|
394 |
|
|
int |
395 |
|
|
tlsext_ri_clienthello_build(SSL *s, CBB *cbb) |
396 |
|
|
{ |
397 |
|
8 |
CBB reneg; |
398 |
|
|
|
399 |
✗✓ |
4 |
if (!CBB_add_u8_length_prefixed(cbb, &reneg)) |
400 |
|
|
return 0; |
401 |
✗✓ |
8 |
if (!CBB_add_bytes(&reneg, S3I(s)->previous_client_finished, |
402 |
|
4 |
S3I(s)->previous_client_finished_len)) |
403 |
|
|
return 0; |
404 |
✗✓ |
4 |
if (!CBB_flush(cbb)) |
405 |
|
|
return 0; |
406 |
|
|
|
407 |
|
4 |
return 1; |
408 |
|
4 |
} |
409 |
|
|
|
410 |
|
|
int |
411 |
|
|
tlsext_ri_clienthello_parse(SSL *s, CBS *cbs, int *alert) |
412 |
|
|
{ |
413 |
|
16 |
CBS reneg; |
414 |
|
|
|
415 |
✓✗ |
8 |
if (!CBS_get_u8_length_prefixed(cbs, &reneg)) |
416 |
|
|
goto err; |
417 |
✓✗ |
8 |
if (CBS_len(cbs) != 0) |
418 |
|
|
goto err; |
419 |
|
|
|
420 |
✓✓ |
16 |
if (!CBS_mem_equal(&reneg, S3I(s)->previous_client_finished, |
421 |
|
8 |
S3I(s)->previous_client_finished_len)) { |
422 |
|
4 |
SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH); |
423 |
|
4 |
*alert = SSL_AD_HANDSHAKE_FAILURE; |
424 |
|
4 |
return 0; |
425 |
|
|
} |
426 |
|
|
|
427 |
|
4 |
S3I(s)->renegotiate_seen = 1; |
428 |
|
4 |
S3I(s)->send_connection_binding = 1; |
429 |
|
|
|
430 |
|
4 |
return 1; |
431 |
|
|
|
432 |
|
|
err: |
433 |
|
|
SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR); |
434 |
|
|
*alert = SSL_AD_DECODE_ERROR; |
435 |
|
|
return 0; |
436 |
|
8 |
} |
437 |
|
|
|
438 |
|
|
int |
439 |
|
|
tlsext_ri_serverhello_needs(SSL *s) |
440 |
|
|
{ |
441 |
|
544 |
return (S3I(s)->send_connection_binding); |
442 |
|
|
} |
443 |
|
|
|
444 |
|
|
int |
445 |
|
|
tlsext_ri_serverhello_build(SSL *s, CBB *cbb) |
446 |
|
|
{ |
447 |
|
528 |
CBB reneg; |
448 |
|
|
|
449 |
✗✓ |
264 |
if (!CBB_add_u8_length_prefixed(cbb, &reneg)) |
450 |
|
|
return 0; |
451 |
✗✓ |
528 |
if (!CBB_add_bytes(&reneg, S3I(s)->previous_client_finished, |
452 |
|
264 |
S3I(s)->previous_client_finished_len)) |
453 |
|
|
return 0; |
454 |
✗✓ |
528 |
if (!CBB_add_bytes(&reneg, S3I(s)->previous_server_finished, |
455 |
|
264 |
S3I(s)->previous_server_finished_len)) |
456 |
|
|
return 0; |
457 |
✗✓ |
264 |
if (!CBB_flush(cbb)) |
458 |
|
|
return 0; |
459 |
|
|
|
460 |
|
264 |
return 1; |
461 |
|
264 |
} |
462 |
|
|
|
463 |
|
|
int |
464 |
|
|
tlsext_ri_serverhello_parse(SSL *s, CBS *cbs, int *alert) |
465 |
|
|
{ |
466 |
|
16370 |
CBS reneg, prev_client, prev_server; |
467 |
|
|
|
468 |
|
|
/* |
469 |
|
|
* Ensure that the previous client and server values are both not |
470 |
|
|
* present, or that they are both present. |
471 |
|
|
*/ |
472 |
✓✓✗✓
|
8193 |
if ((S3I(s)->previous_client_finished_len == 0 && |
473 |
✓✗ |
8177 |
S3I(s)->previous_server_finished_len != 0) || |
474 |
✓✓ |
8185 |
(S3I(s)->previous_client_finished_len != 0 && |
475 |
|
8 |
S3I(s)->previous_server_finished_len == 0)) { |
476 |
|
|
*alert = TLS1_AD_INTERNAL_ERROR; |
477 |
|
|
return 0; |
478 |
|
|
} |
479 |
|
|
|
480 |
✓✗ |
8185 |
if (!CBS_get_u8_length_prefixed(cbs, &reneg)) |
481 |
|
|
goto err; |
482 |
✓✗ |
8185 |
if (!CBS_get_bytes(&reneg, &prev_client, |
483 |
|
8185 |
S3I(s)->previous_client_finished_len)) |
484 |
|
|
goto err; |
485 |
✓✗ |
8185 |
if (!CBS_get_bytes(&reneg, &prev_server, |
486 |
|
8185 |
S3I(s)->previous_server_finished_len)) |
487 |
|
|
goto err; |
488 |
✓✗ |
8185 |
if (CBS_len(&reneg) != 0) |
489 |
|
|
goto err; |
490 |
✓✗ |
8185 |
if (CBS_len(cbs) != 0) |
491 |
|
|
goto err; |
492 |
|
|
|
493 |
✓✓ |
16370 |
if (!CBS_mem_equal(&prev_client, S3I(s)->previous_client_finished, |
494 |
|
8185 |
S3I(s)->previous_client_finished_len)) { |
495 |
|
4 |
SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH); |
496 |
|
4 |
*alert = SSL_AD_HANDSHAKE_FAILURE; |
497 |
|
4 |
return 0; |
498 |
|
|
} |
499 |
✗✓ |
16362 |
if (!CBS_mem_equal(&prev_server, S3I(s)->previous_server_finished, |
500 |
|
8181 |
S3I(s)->previous_server_finished_len)) { |
501 |
|
|
SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH); |
502 |
|
|
*alert = SSL_AD_HANDSHAKE_FAILURE; |
503 |
|
|
return 0; |
504 |
|
|
} |
505 |
|
|
|
506 |
|
8181 |
S3I(s)->renegotiate_seen = 1; |
507 |
|
8181 |
S3I(s)->send_connection_binding = 1; |
508 |
|
|
|
509 |
|
8181 |
return 1; |
510 |
|
|
|
511 |
|
|
err: |
512 |
|
|
SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR); |
513 |
|
|
*alert = SSL_AD_DECODE_ERROR; |
514 |
|
|
return 0; |
515 |
|
8185 |
} |
516 |
|
|
|
517 |
|
|
/* |
518 |
|
|
* Signature Algorithms - RFC 5246 section 7.4.1.4.1. |
519 |
|
|
*/ |
520 |
|
|
int |
521 |
|
|
tlsext_sigalgs_clienthello_needs(SSL *s) |
522 |
|
|
{ |
523 |
✓✓ |
32864 |
return (TLS1_get_client_version(s) >= TLS1_2_VERSION); |
524 |
|
|
} |
525 |
|
|
|
526 |
|
|
int |
527 |
|
|
tlsext_sigalgs_clienthello_build(SSL *s, CBB *cbb) |
528 |
|
|
{ |
529 |
|
16154 |
unsigned char *sigalgs_data; |
530 |
|
8077 |
size_t sigalgs_len; |
531 |
|
8077 |
CBB sigalgs; |
532 |
|
|
|
533 |
|
8077 |
tls12_get_req_sig_algs(s, &sigalgs_data, &sigalgs_len); |
534 |
|
|
|
535 |
✗✓ |
8077 |
if (!CBB_add_u16_length_prefixed(cbb, &sigalgs)) |
536 |
|
|
return 0; |
537 |
✗✓ |
8077 |
if (!CBB_add_bytes(&sigalgs, sigalgs_data, sigalgs_len)) |
538 |
|
|
return 0; |
539 |
✗✓ |
8077 |
if (!CBB_flush(cbb)) |
540 |
|
|
return 0; |
541 |
|
|
|
542 |
|
8077 |
return 1; |
543 |
|
8077 |
} |
544 |
|
|
|
545 |
|
|
int |
546 |
|
|
tlsext_sigalgs_clienthello_parse(SSL *s, CBS *cbs, int *alert) |
547 |
|
|
{ |
548 |
|
280 |
CBS sigalgs; |
549 |
|
|
|
550 |
✗✓ |
140 |
if (!CBS_get_u16_length_prefixed(cbs, &sigalgs)) |
551 |
|
|
return 0; |
552 |
|
|
|
553 |
|
140 |
return tls1_process_sigalgs(s, &sigalgs); |
554 |
|
140 |
} |
555 |
|
|
|
556 |
|
|
int |
557 |
|
|
tlsext_sigalgs_serverhello_needs(SSL *s) |
558 |
|
|
{ |
559 |
|
536 |
return 0; |
560 |
|
|
} |
561 |
|
|
|
562 |
|
|
int |
563 |
|
|
tlsext_sigalgs_serverhello_build(SSL *s, CBB *cbb) |
564 |
|
|
{ |
565 |
|
8 |
return 0; |
566 |
|
|
} |
567 |
|
|
|
568 |
|
|
int |
569 |
|
|
tlsext_sigalgs_serverhello_parse(SSL *s, CBS *cbs, int *alert) |
570 |
|
|
{ |
571 |
|
|
/* As per the RFC, servers must not send this extension. */ |
572 |
|
8 |
return 0; |
573 |
|
|
} |
574 |
|
|
|
575 |
|
|
/* |
576 |
|
|
* Server Name Indication - RFC 6066, section 3. |
577 |
|
|
*/ |
578 |
|
|
int |
579 |
|
|
tlsext_sni_clienthello_needs(SSL *s) |
580 |
|
|
{ |
581 |
|
16458 |
return (s->tlsext_hostname != NULL); |
582 |
|
|
} |
583 |
|
|
|
584 |
|
|
int |
585 |
|
|
tlsext_sni_clienthello_build(SSL *s, CBB *cbb) |
586 |
|
|
{ |
587 |
|
40 |
CBB server_name_list, host_name; |
588 |
|
|
|
589 |
✗✓ |
20 |
if (!CBB_add_u16_length_prefixed(cbb, &server_name_list)) |
590 |
|
|
return 0; |
591 |
✗✓ |
20 |
if (!CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name)) |
592 |
|
|
return 0; |
593 |
✗✓ |
20 |
if (!CBB_add_u16_length_prefixed(&server_name_list, &host_name)) |
594 |
|
|
return 0; |
595 |
✗✓ |
40 |
if (!CBB_add_bytes(&host_name, (const uint8_t *)s->tlsext_hostname, |
596 |
|
20 |
strlen(s->tlsext_hostname))) |
597 |
|
|
return 0; |
598 |
✗✓ |
20 |
if (!CBB_flush(cbb)) |
599 |
|
|
return 0; |
600 |
|
|
|
601 |
|
20 |
return 1; |
602 |
|
20 |
} |
603 |
|
|
|
604 |
|
|
int |
605 |
|
|
tlsext_sni_clienthello_parse(SSL *s, CBS *cbs, int *alert) |
606 |
|
|
{ |
607 |
|
48 |
CBS server_name_list, host_name; |
608 |
|
24 |
uint8_t name_type; |
609 |
|
|
|
610 |
✓✗ |
24 |
if (!CBS_get_u16_length_prefixed(cbs, &server_name_list)) |
611 |
|
|
goto err; |
612 |
|
|
|
613 |
|
|
/* |
614 |
|
|
* RFC 6066 section 3 forbids multiple host names with the same type. |
615 |
|
|
* Additionally, only one type (host_name) is specified. |
616 |
|
|
*/ |
617 |
✓✗ |
24 |
if (!CBS_get_u8(&server_name_list, &name_type)) |
618 |
|
|
goto err; |
619 |
✓✗ |
24 |
if (name_type != TLSEXT_NAMETYPE_host_name) |
620 |
|
|
goto err; |
621 |
|
|
|
622 |
✓✗ |
24 |
if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name)) |
623 |
|
|
goto err; |
624 |
✓✗✗✓
|
48 |
if (CBS_len(&host_name) == 0 || |
625 |
✓✗ |
24 |
CBS_len(&host_name) > TLSEXT_MAXLEN_host_name || |
626 |
|
24 |
CBS_contains_zero_byte(&host_name)) { |
627 |
|
|
*alert = TLS1_AD_UNRECOGNIZED_NAME; |
628 |
|
|
return 0; |
629 |
|
|
} |
630 |
|
|
|
631 |
✓✓ |
24 |
if (s->internal->hit) { |
632 |
✗✓ |
4 |
if (s->session->tlsext_hostname == NULL) { |
633 |
|
|
*alert = TLS1_AD_UNRECOGNIZED_NAME; |
634 |
|
|
return 0; |
635 |
|
|
} |
636 |
✓✗ |
4 |
if (!CBS_mem_equal(&host_name, s->session->tlsext_hostname, |
637 |
|
4 |
strlen(s->session->tlsext_hostname))) { |
638 |
|
4 |
*alert = TLS1_AD_UNRECOGNIZED_NAME; |
639 |
|
4 |
return 0; |
640 |
|
|
} |
641 |
|
|
} else { |
642 |
✓✗ |
20 |
if (s->session->tlsext_hostname != NULL) |
643 |
|
|
goto err; |
644 |
✗✓ |
20 |
if (!CBS_strdup(&host_name, &s->session->tlsext_hostname)) { |
645 |
|
|
*alert = TLS1_AD_INTERNAL_ERROR; |
646 |
|
|
return 0; |
647 |
|
|
} |
648 |
|
|
} |
649 |
|
|
|
650 |
✓✗ |
20 |
if (CBS_len(&server_name_list) != 0) |
651 |
|
|
goto err; |
652 |
✓✗ |
20 |
if (CBS_len(cbs) != 0) |
653 |
|
|
goto err; |
654 |
|
|
|
655 |
|
20 |
return 1; |
656 |
|
|
|
657 |
|
|
err: |
658 |
|
|
*alert = SSL_AD_DECODE_ERROR; |
659 |
|
|
return 0; |
660 |
|
24 |
} |
661 |
|
|
|
662 |
|
|
int |
663 |
|
|
tlsext_sni_serverhello_needs(SSL *s) |
664 |
|
|
{ |
665 |
|
544 |
return (s->session->tlsext_hostname != NULL); |
666 |
|
|
} |
667 |
|
|
|
668 |
|
|
int |
669 |
|
|
tlsext_sni_serverhello_build(SSL *s, CBB *cbb) |
670 |
|
|
{ |
671 |
|
40 |
return 1; |
672 |
|
|
} |
673 |
|
|
|
674 |
|
|
int |
675 |
|
|
tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert) |
676 |
|
|
{ |
677 |
✓✗✗✓
|
60 |
if (s->tlsext_hostname == NULL || CBS_len(cbs) != 0) { |
678 |
|
|
*alert = TLS1_AD_UNRECOGNIZED_NAME; |
679 |
|
|
return 0; |
680 |
|
|
} |
681 |
|
|
|
682 |
✗✓ |
20 |
if (s->internal->hit) { |
683 |
|
|
if (s->session->tlsext_hostname == NULL) { |
684 |
|
|
*alert = TLS1_AD_UNRECOGNIZED_NAME; |
685 |
|
|
return 0; |
686 |
|
|
} |
687 |
|
|
if (strcmp(s->tlsext_hostname, |
688 |
|
|
s->session->tlsext_hostname) != 0) { |
689 |
|
|
*alert = TLS1_AD_UNRECOGNIZED_NAME; |
690 |
|
|
return 0; |
691 |
|
|
} |
692 |
|
|
} else { |
693 |
✗✓ |
20 |
if (s->session->tlsext_hostname != NULL) { |
694 |
|
|
*alert = SSL_AD_DECODE_ERROR; |
695 |
|
|
return 0; |
696 |
|
|
} |
697 |
✗✓ |
40 |
if ((s->session->tlsext_hostname = |
698 |
|
40 |
strdup(s->tlsext_hostname)) == NULL) { |
699 |
|
|
*alert = TLS1_AD_INTERNAL_ERROR; |
700 |
|
|
return 0; |
701 |
|
|
} |
702 |
|
|
} |
703 |
|
|
|
704 |
|
20 |
return 1; |
705 |
|
20 |
} |
706 |
|
|
|
707 |
|
|
|
708 |
|
|
/* |
709 |
|
|
*Certificate Status Request - RFC 6066 section 8. |
710 |
|
|
*/ |
711 |
|
|
|
712 |
|
|
int |
713 |
|
|
tlsext_ocsp_clienthello_needs(SSL *s) |
714 |
|
|
{ |
715 |
✓✓ |
24687 |
return (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp && |
716 |
|
20 |
s->version != DTLS1_VERSION); |
717 |
|
|
} |
718 |
|
|
|
719 |
|
|
int |
720 |
|
|
tlsext_ocsp_clienthello_build(SSL *s, CBB *cbb) |
721 |
|
|
{ |
722 |
|
40 |
CBB respid_list, respid, exts; |
723 |
|
20 |
unsigned char *ext_data; |
724 |
|
|
size_t ext_len; |
725 |
|
|
int i; |
726 |
|
|
|
727 |
✗✓ |
20 |
if (!CBB_add_u8(cbb, TLSEXT_STATUSTYPE_ocsp)) |
728 |
|
|
return 0; |
729 |
✗✓ |
20 |
if (!CBB_add_u16_length_prefixed(cbb, &respid_list)) |
730 |
|
|
return 0; |
731 |
✗✓ |
40 |
for (i = 0; i < sk_OCSP_RESPID_num(s->internal->tlsext_ocsp_ids); i++) { |
732 |
|
|
unsigned char *respid_data; |
733 |
|
|
OCSP_RESPID *id; |
734 |
|
|
size_t id_len; |
735 |
|
|
|
736 |
|
|
if ((id = sk_OCSP_RESPID_value(s->internal->tlsext_ocsp_ids, |
737 |
|
|
i)) == NULL) |
738 |
|
|
return 0; |
739 |
|
|
if ((id_len = i2d_OCSP_RESPID(id, NULL)) == -1) |
740 |
|
|
return 0; |
741 |
|
|
if (!CBB_add_u16_length_prefixed(&respid_list, &respid)) |
742 |
|
|
return 0; |
743 |
|
|
if (!CBB_add_space(&respid, &respid_data, id_len)) |
744 |
|
|
return 0; |
745 |
|
|
if ((i2d_OCSP_RESPID(id, &respid_data)) != id_len) |
746 |
|
|
return 0; |
747 |
|
|
} |
748 |
✗✓ |
20 |
if (!CBB_add_u16_length_prefixed(cbb, &exts)) |
749 |
|
|
return 0; |
750 |
✗✓ |
40 |
if ((ext_len = i2d_X509_EXTENSIONS(s->internal->tlsext_ocsp_exts, |
751 |
|
20 |
NULL)) == -1) |
752 |
|
|
return 0; |
753 |
✗✓ |
20 |
if (!CBB_add_space(&exts, &ext_data, ext_len)) |
754 |
|
|
return 0; |
755 |
✗✓ |
20 |
if ((i2d_X509_EXTENSIONS(s->internal->tlsext_ocsp_exts, &ext_data) != |
756 |
|
|
ext_len)) |
757 |
|
|
return 0; |
758 |
✗✓ |
20 |
if (!CBB_flush(cbb)) |
759 |
|
|
return 0; |
760 |
|
20 |
return 1; |
761 |
|
20 |
} |
762 |
|
|
|
763 |
|
|
int |
764 |
|
|
tlsext_ocsp_clienthello_parse(SSL *s, CBS *cbs, int *alert) |
765 |
|
|
{ |
766 |
|
|
int failure = SSL_AD_DECODE_ERROR; |
767 |
|
40 |
CBS respid_list, respid, exts; |
768 |
|
20 |
const unsigned char *p; |
769 |
|
20 |
uint8_t status_type; |
770 |
|
|
int ret = 0; |
771 |
|
|
|
772 |
✓✗ |
20 |
if (!CBS_get_u8(cbs, &status_type)) |
773 |
|
|
goto err; |
774 |
✗✓ |
20 |
if (status_type != TLSEXT_STATUSTYPE_ocsp) { |
775 |
|
|
/* ignore unknown status types */ |
776 |
|
|
s->tlsext_status_type = -1; |
777 |
|
|
|
778 |
|
|
if (!CBS_skip(cbs, CBS_len(cbs))) { |
779 |
|
|
*alert = TLS1_AD_INTERNAL_ERROR; |
780 |
|
|
return 0; |
781 |
|
|
} |
782 |
|
|
return 1; |
783 |
|
|
} |
784 |
|
20 |
s->tlsext_status_type = status_type; |
785 |
✓✗ |
20 |
if (!CBS_get_u16_length_prefixed(cbs, &respid_list)) |
786 |
|
|
goto err; |
787 |
|
|
|
788 |
|
|
/* XXX */ |
789 |
|
20 |
sk_OCSP_RESPID_pop_free(s->internal->tlsext_ocsp_ids, OCSP_RESPID_free); |
790 |
|
20 |
s->internal->tlsext_ocsp_ids = NULL; |
791 |
✗✓ |
20 |
if (CBS_len(&respid_list) > 0) { |
792 |
|
|
s->internal->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); |
793 |
|
|
if (s->internal->tlsext_ocsp_ids == NULL) { |
794 |
|
|
failure = SSL_AD_INTERNAL_ERROR; |
795 |
|
|
goto err; |
796 |
|
|
} |
797 |
|
|
} |
798 |
|
|
|
799 |
✗✓ |
20 |
while (CBS_len(&respid_list) > 0) { |
800 |
|
|
OCSP_RESPID *id; |
801 |
|
|
|
802 |
|
|
if (!CBS_get_u16_length_prefixed(&respid_list, &respid)) |
803 |
|
|
goto err; |
804 |
|
|
p = CBS_data(&respid); |
805 |
|
|
if ((id = d2i_OCSP_RESPID(NULL, &p, CBS_len(&respid))) == NULL) |
806 |
|
|
goto err; |
807 |
|
|
if (!sk_OCSP_RESPID_push(s->internal->tlsext_ocsp_ids, id)) { |
808 |
|
|
failure = SSL_AD_INTERNAL_ERROR; |
809 |
|
|
OCSP_RESPID_free(id); |
810 |
|
|
goto err; |
811 |
|
|
} |
812 |
|
|
} |
813 |
|
|
|
814 |
|
|
/* Read in request_extensions */ |
815 |
✓✗ |
20 |
if (!CBS_get_u16_length_prefixed(cbs, &exts)) |
816 |
|
|
goto err; |
817 |
✗✓ |
20 |
if (CBS_len(&exts) > 0) { |
818 |
|
|
sk_X509_EXTENSION_pop_free(s->internal->tlsext_ocsp_exts, |
819 |
|
|
X509_EXTENSION_free); |
820 |
|
|
p = CBS_data(&exts); |
821 |
|
|
if ((s->internal->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL, |
822 |
|
|
&p, CBS_len(&exts))) == NULL) |
823 |
|
|
goto err; |
824 |
|
|
} |
825 |
|
|
|
826 |
|
|
/* should be nothing left */ |
827 |
✓✗ |
20 |
if (CBS_len(cbs) > 0) |
828 |
|
|
goto err; |
829 |
|
|
|
830 |
|
20 |
ret = 1; |
831 |
|
|
err: |
832 |
✗✓ |
20 |
if (ret == 0) |
833 |
|
|
*alert = failure; |
834 |
|
20 |
return ret; |
835 |
|
20 |
} |
836 |
|
|
|
837 |
|
|
int |
838 |
|
|
tlsext_ocsp_serverhello_needs(SSL *s) |
839 |
|
|
{ |
840 |
|
544 |
return s->internal->tlsext_status_expected; |
841 |
|
|
} |
842 |
|
|
|
843 |
|
|
int |
844 |
|
|
tlsext_ocsp_serverhello_build(SSL *s, CBB *cbb) |
845 |
|
|
{ |
846 |
|
8 |
return 1; |
847 |
|
|
} |
848 |
|
|
|
849 |
|
|
int |
850 |
|
|
tlsext_ocsp_serverhello_parse(SSL *s, CBS *cbs, int *alert) |
851 |
|
|
{ |
852 |
|
|
if (s->tlsext_status_type == -1) { |
853 |
|
|
*alert = TLS1_AD_UNSUPPORTED_EXTENSION; |
854 |
|
|
return 0; |
855 |
|
|
} |
856 |
|
|
/* Set flag to expect CertificateStatus message */ |
857 |
|
|
s->internal->tlsext_status_expected = 1; |
858 |
|
|
return 1; |
859 |
|
|
} |
860 |
|
|
|
861 |
|
|
/* |
862 |
|
|
* SessionTicket extension - RFC 5077 section 3.2 |
863 |
|
|
*/ |
864 |
|
|
int |
865 |
|
|
tlsext_sessionticket_clienthello_needs(SSL *s) |
866 |
|
|
{ |
867 |
|
|
/* |
868 |
|
|
* Send session ticket extension when enabled and not overridden. |
869 |
|
|
* |
870 |
|
|
* When renegotiating, send an empty session ticket to indicate support. |
871 |
|
|
*/ |
872 |
✓✓ |
16506 |
if ((SSL_get_options(s) & SSL_OP_NO_TICKET) != 0) |
873 |
|
20 |
return 0; |
874 |
|
|
|
875 |
✗✓ |
8233 |
if (s->internal->new_session) |
876 |
|
|
return 1; |
877 |
|
|
|
878 |
✓✓✓✓
|
8241 |
if (s->internal->tlsext_session_ticket != NULL && |
879 |
|
8 |
s->internal->tlsext_session_ticket->data == NULL) |
880 |
|
4 |
return 0; |
881 |
|
|
|
882 |
|
8229 |
return 1; |
883 |
|
8253 |
} |
884 |
|
|
|
885 |
|
|
int |
886 |
|
|
tlsext_sessionticket_clienthello_build(SSL *s, CBB *cbb) |
887 |
|
|
{ |
888 |
|
|
/* |
889 |
|
|
* Signal that we support session tickets by sending an empty |
890 |
|
|
* extension when renegotiating or no session found. |
891 |
|
|
*/ |
892 |
✓✗✓✓
|
24663 |
if (s->internal->new_session || s->session == NULL) |
893 |
|
4 |
return 1; |
894 |
|
|
|
895 |
✓✓ |
8217 |
if (s->session->tlsext_tick != NULL) { |
896 |
|
|
/* Attempt to resume with an existing session ticket */ |
897 |
✗✓ |
7046 |
if (!CBB_add_bytes(cbb, s->session->tlsext_tick, |
898 |
|
7046 |
s->session->tlsext_ticklen)) |
899 |
|
|
return 0; |
900 |
|
|
|
901 |
✓✓ |
1171 |
} else if (s->internal->tlsext_session_ticket != NULL) { |
902 |
|
|
/* |
903 |
|
|
* Attempt to resume with a custom provided session ticket set |
904 |
|
|
* by SSL_set_session_ticket_ext(). |
905 |
|
|
*/ |
906 |
✓✗ |
4 |
if (s->internal->tlsext_session_ticket->length > 0) { |
907 |
|
4 |
size_t ticklen = s->internal->tlsext_session_ticket->length; |
908 |
|
|
|
909 |
✗✓ |
4 |
if ((s->session->tlsext_tick = malloc(ticklen)) == NULL) |
910 |
|
|
return 0; |
911 |
|
8 |
memcpy(s->session->tlsext_tick, |
912 |
|
4 |
s->internal->tlsext_session_ticket->data, |
913 |
|
|
ticklen); |
914 |
|
4 |
s->session->tlsext_ticklen = ticklen; |
915 |
|
|
|
916 |
✗✓ |
8 |
if (!CBB_add_bytes(cbb, s->session->tlsext_tick, |
917 |
|
4 |
s->session->tlsext_ticklen)) |
918 |
|
|
return 0; |
919 |
✓✗ |
4 |
} |
920 |
|
|
} |
921 |
|
|
|
922 |
✗✓ |
8217 |
if (!CBB_flush(cbb)) |
923 |
|
|
return 0; |
924 |
|
|
|
925 |
|
8217 |
return 1; |
926 |
|
8221 |
} |
927 |
|
|
|
928 |
|
|
int |
929 |
|
|
tlsext_sessionticket_clienthello_parse(SSL *s, CBS *cbs, int *alert) |
930 |
|
|
{ |
931 |
✗✓ |
480 |
if (s->internal->tls_session_ticket_ext_cb) { |
932 |
|
|
if (!s->internal->tls_session_ticket_ext_cb(s, CBS_data(cbs), |
933 |
|
|
(int)CBS_len(cbs), |
934 |
|
|
s->internal->tls_session_ticket_ext_cb_arg)) { |
935 |
|
|
*alert = TLS1_AD_INTERNAL_ERROR; |
936 |
|
|
return 0; |
937 |
|
|
} |
938 |
|
|
} |
939 |
|
|
|
940 |
|
|
/* We need to signal that this was processed fully */ |
941 |
✗✓ |
240 |
if (!CBS_skip(cbs, CBS_len(cbs))) { |
942 |
|
|
*alert = TLS1_AD_INTERNAL_ERROR; |
943 |
|
|
return 0; |
944 |
|
|
} |
945 |
|
|
|
946 |
|
240 |
return 1; |
947 |
|
240 |
} |
948 |
|
|
|
949 |
|
|
int |
950 |
|
|
tlsext_sessionticket_serverhello_needs(SSL *s) |
951 |
|
|
{ |
952 |
✓✓ |
840 |
return (s->internal->tlsext_ticket_expected && |
953 |
|
244 |
!(SSL_get_options(s) & SSL_OP_NO_TICKET)); |
954 |
|
|
} |
955 |
|
|
|
956 |
|
|
int |
957 |
|
|
tlsext_sessionticket_serverhello_build(SSL *s, CBB *cbb) |
958 |
|
|
{ |
959 |
|
|
/* Empty ticket */ |
960 |
|
|
|
961 |
|
488 |
return 1; |
962 |
|
|
} |
963 |
|
|
|
964 |
|
|
int |
965 |
|
|
tlsext_sessionticket_serverhello_parse(SSL *s, CBS *cbs, int *alert) |
966 |
|
|
{ |
967 |
✗✓ |
2238 |
if (s->internal->tls_session_ticket_ext_cb) { |
968 |
|
|
if (!s->internal->tls_session_ticket_ext_cb(s, CBS_data(cbs), |
969 |
|
|
(int)CBS_len(cbs), |
970 |
|
|
s->internal->tls_session_ticket_ext_cb_arg)) { |
971 |
|
|
*alert = TLS1_AD_INTERNAL_ERROR; |
972 |
|
|
return 0; |
973 |
|
|
} |
974 |
|
|
} |
975 |
|
|
|
976 |
✓✗✗✓
|
2238 |
if ((SSL_get_options(s) & SSL_OP_NO_TICKET) != 0 || CBS_len(cbs) > 0) { |
977 |
|
|
*alert = TLS1_AD_UNSUPPORTED_EXTENSION; |
978 |
|
|
return 0; |
979 |
|
|
} |
980 |
|
|
|
981 |
|
1119 |
s->internal->tlsext_ticket_expected = 1; |
982 |
|
|
|
983 |
|
1119 |
return 1; |
984 |
|
1119 |
} |
985 |
|
|
|
986 |
|
|
/* |
987 |
|
|
* DTLS extension for SRTP key establishment - RFC 5764 |
988 |
|
|
*/ |
989 |
|
|
|
990 |
|
|
#ifndef OPENSSL_NO_SRTP |
991 |
|
|
|
992 |
|
|
int |
993 |
|
|
tlsext_srtp_clienthello_needs(SSL *s) |
994 |
|
|
{ |
995 |
✓✓ |
24763 |
return SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) != NULL; |
996 |
|
|
} |
997 |
|
|
|
998 |
|
|
int |
999 |
|
|
tlsext_srtp_clienthello_build(SSL *s, CBB *cbb) |
1000 |
|
|
{ |
1001 |
|
16 |
CBB profiles, mki; |
1002 |
|
|
int ct, i; |
1003 |
|
|
STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = NULL; |
1004 |
|
|
SRTP_PROTECTION_PROFILE *prof; |
1005 |
|
|
|
1006 |
✗✓ |
8 |
if ((clnt = SSL_get_srtp_profiles(s)) == NULL) { |
1007 |
|
|
SSLerror(s, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); |
1008 |
|
|
return 0; |
1009 |
|
|
} |
1010 |
|
|
|
1011 |
✗✓ |
8 |
if ((ct = sk_SRTP_PROTECTION_PROFILE_num(clnt)) < 1) { |
1012 |
|
|
SSLerror(s, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); |
1013 |
|
|
return 0; |
1014 |
|
|
} |
1015 |
|
|
|
1016 |
✗✓ |
8 |
if (!CBB_add_u16_length_prefixed(cbb, &profiles)) |
1017 |
|
|
return 0; |
1018 |
|
|
|
1019 |
✓✓ |
40 |
for (i = 0; i < ct; i++) { |
1020 |
✗✓ |
12 |
if ((prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i)) == NULL) |
1021 |
|
|
return 0; |
1022 |
✗✓ |
12 |
if (!CBB_add_u16(&profiles, prof->id)) |
1023 |
|
|
return 0; |
1024 |
|
|
} |
1025 |
|
|
|
1026 |
✗✓ |
8 |
if (!CBB_add_u8_length_prefixed(cbb, &mki)) |
1027 |
|
|
return 0; |
1028 |
|
|
|
1029 |
✗✓ |
8 |
if (!CBB_flush(cbb)) |
1030 |
|
|
return 0; |
1031 |
|
|
|
1032 |
|
8 |
return 1; |
1033 |
|
8 |
} |
1034 |
|
|
|
1035 |
|
|
int |
1036 |
|
|
tlsext_srtp_clienthello_parse(SSL *s, CBS *cbs, int *alert) |
1037 |
|
|
{ |
1038 |
|
32 |
SRTP_PROTECTION_PROFILE *cprof, *sprof; |
1039 |
|
|
STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = NULL, *srvr; |
1040 |
|
|
int i, j; |
1041 |
|
|
int ret; |
1042 |
|
16 |
uint16_t id; |
1043 |
|
16 |
CBS profiles, mki; |
1044 |
|
|
|
1045 |
|
|
ret = 0; |
1046 |
|
|
|
1047 |
✓✗ |
16 |
if (!CBS_get_u16_length_prefixed(cbs, &profiles)) |
1048 |
|
|
goto err; |
1049 |
✓✗✓✗
|
32 |
if (CBS_len(&profiles) == 0 || CBS_len(&profiles) % 2 != 0) |
1050 |
|
|
goto err; |
1051 |
|
|
|
1052 |
✓✗ |
16 |
if ((clnt = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) |
1053 |
|
|
goto err; |
1054 |
|
|
|
1055 |
✓✓ |
44 |
while (CBS_len(&profiles) > 0) { |
1056 |
✓✗ |
28 |
if (!CBS_get_u16(&profiles, &id)) |
1057 |
|
|
goto err; |
1058 |
|
|
|
1059 |
✓✓ |
28 |
if (!srtp_find_profile_by_num(id, &cprof)) { |
1060 |
✓✗ |
16 |
if (!sk_SRTP_PROTECTION_PROFILE_push(clnt, cprof)) |
1061 |
|
|
goto err; |
1062 |
|
|
} |
1063 |
|
|
} |
1064 |
|
|
|
1065 |
✓✗✗✓
|
32 |
if (!CBS_get_u8_length_prefixed(cbs, &mki) || CBS_len(&mki) != 0) { |
1066 |
|
|
SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE); |
1067 |
|
|
*alert = SSL_AD_DECODE_ERROR; |
1068 |
|
|
goto done; |
1069 |
|
|
} |
1070 |
✓✗ |
16 |
if (CBS_len(cbs) != 0) |
1071 |
|
|
goto err; |
1072 |
|
|
|
1073 |
|
|
/* |
1074 |
|
|
* Per RFC 5764 section 4.1.1 |
1075 |
|
|
* |
1076 |
|
|
* Find the server preferred profile using the client's list. |
1077 |
|
|
* |
1078 |
|
|
* The server MUST send a profile if it sends the use_srtp |
1079 |
|
|
* extension. If one is not found, it should fall back to the |
1080 |
|
|
* negotiated DTLS cipher suite or return a DTLS alert. |
1081 |
|
|
*/ |
1082 |
✓✗ |
16 |
if ((srvr = SSL_get_srtp_profiles(s)) == NULL) |
1083 |
|
|
goto err; |
1084 |
✓✓ |
56 |
for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(srvr); i++) { |
1085 |
✓✗ |
48 |
if ((sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i)) |
1086 |
|
24 |
== NULL) |
1087 |
|
|
goto err; |
1088 |
|
|
|
1089 |
✓✓ |
56 |
for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(clnt); j++) { |
1090 |
✓✗ |
32 |
if ((cprof = sk_SRTP_PROTECTION_PROFILE_value(clnt, j)) |
1091 |
|
16 |
== NULL) |
1092 |
|
|
goto err; |
1093 |
|
|
|
1094 |
✓✓ |
16 |
if (cprof->id == sprof->id) { |
1095 |
|
12 |
s->internal->srtp_profile = sprof; |
1096 |
|
|
ret = 1; |
1097 |
|
12 |
goto done; |
1098 |
|
|
} |
1099 |
|
|
} |
1100 |
|
|
} |
1101 |
|
|
|
1102 |
|
|
/* If we didn't find anything, fall back to the negotiated */ |
1103 |
|
|
ret = 1; |
1104 |
|
4 |
goto done; |
1105 |
|
|
|
1106 |
|
|
err: |
1107 |
|
|
SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); |
1108 |
|
|
*alert = SSL_AD_DECODE_ERROR; |
1109 |
|
|
|
1110 |
|
|
done: |
1111 |
|
16 |
sk_SRTP_PROTECTION_PROFILE_free(clnt); |
1112 |
|
16 |
return ret; |
1113 |
|
16 |
} |
1114 |
|
|
|
1115 |
|
|
int |
1116 |
|
|
tlsext_srtp_serverhello_needs(SSL *s) |
1117 |
|
|
{ |
1118 |
✓✓ |
936 |
return SSL_IS_DTLS(s) && SSL_get_selected_srtp_profile(s) != NULL; |
1119 |
|
|
} |
1120 |
|
|
|
1121 |
|
|
int |
1122 |
|
|
tlsext_srtp_serverhello_build(SSL *s, CBB *cbb) |
1123 |
|
|
{ |
1124 |
|
|
SRTP_PROTECTION_PROFILE *profile; |
1125 |
|
8 |
CBB srtp, mki; |
1126 |
|
|
|
1127 |
✗✓ |
4 |
if (!CBB_add_u16_length_prefixed(cbb, &srtp)) |
1128 |
|
|
return 0; |
1129 |
|
|
|
1130 |
✗✓ |
4 |
if ((profile = SSL_get_selected_srtp_profile(s)) == NULL) |
1131 |
|
|
return 0; |
1132 |
|
|
|
1133 |
✗✓ |
4 |
if (!CBB_add_u16(&srtp, profile->id)) |
1134 |
|
|
return 0; |
1135 |
|
|
|
1136 |
✗✓ |
4 |
if (!CBB_add_u8_length_prefixed(cbb, &mki)) |
1137 |
|
|
return 0; |
1138 |
|
|
|
1139 |
✗✓ |
4 |
if (!CBB_flush(cbb)) |
1140 |
|
|
return 0; |
1141 |
|
|
|
1142 |
|
4 |
return 1; |
1143 |
|
4 |
} |
1144 |
|
|
|
1145 |
|
|
int |
1146 |
|
|
tlsext_srtp_serverhello_parse(SSL *s, CBS *cbs, int *alert) |
1147 |
|
|
{ |
1148 |
|
|
STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; |
1149 |
|
|
SRTP_PROTECTION_PROFILE *prof; |
1150 |
|
|
int i; |
1151 |
|
24 |
uint16_t id; |
1152 |
|
12 |
CBS profile_ids, mki; |
1153 |
|
|
|
1154 |
✗✓ |
12 |
if (!CBS_get_u16_length_prefixed(cbs, &profile_ids)) { |
1155 |
|
|
SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); |
1156 |
|
|
goto err; |
1157 |
|
|
} |
1158 |
|
|
|
1159 |
✓✗✓✓
|
24 |
if (!CBS_get_u16(&profile_ids, &id) || CBS_len(&profile_ids) != 0) { |
1160 |
|
4 |
SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); |
1161 |
|
4 |
goto err; |
1162 |
|
|
} |
1163 |
|
|
|
1164 |
✓✗✗✓
|
16 |
if (!CBS_get_u8_length_prefixed(cbs, &mki) || CBS_len(&mki) != 0) { |
1165 |
|
|
SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE); |
1166 |
|
|
*alert = SSL_AD_ILLEGAL_PARAMETER; |
1167 |
|
|
return 0; |
1168 |
|
|
} |
1169 |
|
|
|
1170 |
✗✓ |
8 |
if ((clnt = SSL_get_srtp_profiles(s)) == NULL) { |
1171 |
|
|
SSLerror(s, SSL_R_NO_SRTP_PROFILES); |
1172 |
|
|
goto err; |
1173 |
|
|
} |
1174 |
|
|
|
1175 |
✓✓ |
32 |
for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { |
1176 |
✗✓ |
24 |
if ((prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i)) |
1177 |
|
12 |
== NULL) { |
1178 |
|
|
SSLerror(s, SSL_R_NO_SRTP_PROFILES); |
1179 |
|
|
goto err; |
1180 |
|
|
} |
1181 |
|
|
|
1182 |
✓✓ |
12 |
if (prof->id == id) { |
1183 |
|
4 |
s->internal->srtp_profile = prof; |
1184 |
|
4 |
return 1; |
1185 |
|
|
} |
1186 |
|
|
} |
1187 |
|
|
|
1188 |
|
4 |
SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); |
1189 |
|
|
err: |
1190 |
|
8 |
*alert = SSL_AD_DECODE_ERROR; |
1191 |
|
8 |
return 0; |
1192 |
|
12 |
} |
1193 |
|
|
|
1194 |
|
|
#endif /* OPENSSL_NO_SRTP */ |
1195 |
|
|
|
1196 |
|
|
struct tls_extension { |
1197 |
|
|
uint16_t type; |
1198 |
|
|
int (*clienthello_needs)(SSL *s); |
1199 |
|
|
int (*clienthello_build)(SSL *s, CBB *cbb); |
1200 |
|
|
int (*clienthello_parse)(SSL *s, CBS *cbs, int *alert); |
1201 |
|
|
int (*serverhello_needs)(SSL *s); |
1202 |
|
|
int (*serverhello_build)(SSL *s, CBB *cbb); |
1203 |
|
|
int (*serverhello_parse)(SSL *s, CBS *cbs, int *alert); |
1204 |
|
|
}; |
1205 |
|
|
|
1206 |
|
|
static struct tls_extension tls_extensions[] = { |
1207 |
|
|
{ |
1208 |
|
|
.type = TLSEXT_TYPE_server_name, |
1209 |
|
|
.clienthello_needs = tlsext_sni_clienthello_needs, |
1210 |
|
|
.clienthello_build = tlsext_sni_clienthello_build, |
1211 |
|
|
.clienthello_parse = tlsext_sni_clienthello_parse, |
1212 |
|
|
.serverhello_needs = tlsext_sni_serverhello_needs, |
1213 |
|
|
.serverhello_build = tlsext_sni_serverhello_build, |
1214 |
|
|
.serverhello_parse = tlsext_sni_serverhello_parse, |
1215 |
|
|
}, |
1216 |
|
|
{ |
1217 |
|
|
.type = TLSEXT_TYPE_renegotiate, |
1218 |
|
|
.clienthello_needs = tlsext_ri_clienthello_needs, |
1219 |
|
|
.clienthello_build = tlsext_ri_clienthello_build, |
1220 |
|
|
.clienthello_parse = tlsext_ri_clienthello_parse, |
1221 |
|
|
.serverhello_needs = tlsext_ri_serverhello_needs, |
1222 |
|
|
.serverhello_build = tlsext_ri_serverhello_build, |
1223 |
|
|
.serverhello_parse = tlsext_ri_serverhello_parse, |
1224 |
|
|
}, |
1225 |
|
|
{ |
1226 |
|
|
.type = TLSEXT_TYPE_status_request, |
1227 |
|
|
.clienthello_needs = tlsext_ocsp_clienthello_needs, |
1228 |
|
|
.clienthello_build = tlsext_ocsp_clienthello_build, |
1229 |
|
|
.clienthello_parse = tlsext_ocsp_clienthello_parse, |
1230 |
|
|
.serverhello_needs = tlsext_ocsp_serverhello_needs, |
1231 |
|
|
.serverhello_build = tlsext_ocsp_serverhello_build, |
1232 |
|
|
.serverhello_parse = tlsext_ocsp_serverhello_parse, |
1233 |
|
|
}, |
1234 |
|
|
{ |
1235 |
|
|
.type = TLSEXT_TYPE_ec_point_formats, |
1236 |
|
|
.clienthello_needs = tlsext_ecpf_clienthello_needs, |
1237 |
|
|
.clienthello_build = tlsext_ecpf_clienthello_build, |
1238 |
|
|
.clienthello_parse = tlsext_ecpf_clienthello_parse, |
1239 |
|
|
.serverhello_needs = tlsext_ecpf_serverhello_needs, |
1240 |
|
|
.serverhello_build = tlsext_ecpf_serverhello_build, |
1241 |
|
|
.serverhello_parse = tlsext_ecpf_serverhello_parse, |
1242 |
|
|
}, |
1243 |
|
|
{ |
1244 |
|
|
.type = TLSEXT_TYPE_elliptic_curves, |
1245 |
|
|
.clienthello_needs = tlsext_ec_clienthello_needs, |
1246 |
|
|
.clienthello_build = tlsext_ec_clienthello_build, |
1247 |
|
|
.clienthello_parse = tlsext_ec_clienthello_parse, |
1248 |
|
|
.serverhello_needs = tlsext_ec_serverhello_needs, |
1249 |
|
|
.serverhello_build = tlsext_ec_serverhello_build, |
1250 |
|
|
.serverhello_parse = tlsext_ec_serverhello_parse, |
1251 |
|
|
}, |
1252 |
|
|
{ |
1253 |
|
|
.type = TLSEXT_TYPE_session_ticket, |
1254 |
|
|
.clienthello_needs = tlsext_sessionticket_clienthello_needs, |
1255 |
|
|
.clienthello_build = tlsext_sessionticket_clienthello_build, |
1256 |
|
|
.clienthello_parse = tlsext_sessionticket_clienthello_parse, |
1257 |
|
|
.serverhello_needs = tlsext_sessionticket_serverhello_needs, |
1258 |
|
|
.serverhello_build = tlsext_sessionticket_serverhello_build, |
1259 |
|
|
.serverhello_parse = tlsext_sessionticket_serverhello_parse, |
1260 |
|
|
}, |
1261 |
|
|
{ |
1262 |
|
|
.type = TLSEXT_TYPE_signature_algorithms, |
1263 |
|
|
.clienthello_needs = tlsext_sigalgs_clienthello_needs, |
1264 |
|
|
.clienthello_build = tlsext_sigalgs_clienthello_build, |
1265 |
|
|
.clienthello_parse = tlsext_sigalgs_clienthello_parse, |
1266 |
|
|
.serverhello_needs = tlsext_sigalgs_serverhello_needs, |
1267 |
|
|
.serverhello_build = tlsext_sigalgs_serverhello_build, |
1268 |
|
|
.serverhello_parse = tlsext_sigalgs_serverhello_parse, |
1269 |
|
|
}, |
1270 |
|
|
{ |
1271 |
|
|
.type = TLSEXT_TYPE_application_layer_protocol_negotiation, |
1272 |
|
|
.clienthello_needs = tlsext_alpn_clienthello_needs, |
1273 |
|
|
.clienthello_build = tlsext_alpn_clienthello_build, |
1274 |
|
|
.clienthello_parse = tlsext_alpn_clienthello_parse, |
1275 |
|
|
.serverhello_needs = tlsext_alpn_serverhello_needs, |
1276 |
|
|
.serverhello_build = tlsext_alpn_serverhello_build, |
1277 |
|
|
.serverhello_parse = tlsext_alpn_serverhello_parse, |
1278 |
|
|
}, |
1279 |
|
|
#ifndef OPENSSL_NO_SRTP |
1280 |
|
|
{ |
1281 |
|
|
.type = TLSEXT_TYPE_use_srtp, |
1282 |
|
|
.clienthello_needs = tlsext_srtp_clienthello_needs, |
1283 |
|
|
.clienthello_build = tlsext_srtp_clienthello_build, |
1284 |
|
|
.clienthello_parse = tlsext_srtp_clienthello_parse, |
1285 |
|
|
.serverhello_needs = tlsext_srtp_serverhello_needs, |
1286 |
|
|
.serverhello_build = tlsext_srtp_serverhello_build, |
1287 |
|
|
.serverhello_parse = tlsext_srtp_serverhello_parse, |
1288 |
|
|
} |
1289 |
|
|
#endif /* OPENSSL_NO_SRTP */ |
1290 |
|
|
}; |
1291 |
|
|
|
1292 |
|
|
#define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) |
1293 |
|
|
|
1294 |
|
|
int |
1295 |
|
|
tlsext_clienthello_build(SSL *s, CBB *cbb) |
1296 |
|
|
{ |
1297 |
|
16442 |
CBB extensions, extension_data; |
1298 |
|
|
struct tls_extension *tlsext; |
1299 |
|
|
size_t i; |
1300 |
|
|
|
1301 |
✗✓ |
8221 |
if (!CBB_add_u16_length_prefixed(cbb, &extensions)) |
1302 |
|
|
return 0; |
1303 |
|
|
|
1304 |
✓✓ |
164420 |
for (i = 0; i < N_TLS_EXTENSIONS; i++) { |
1305 |
|
73989 |
tlsext = &tls_extensions[i]; |
1306 |
|
|
|
1307 |
✓✓ |
73989 |
if (!tlsext->clienthello_needs(s)) |
1308 |
|
|
continue; |
1309 |
|
|
|
1310 |
✗✓ |
32490 |
if (!CBB_add_u16(&extensions, tlsext->type)) |
1311 |
|
|
return 0; |
1312 |
✗✓ |
32490 |
if (!CBB_add_u16_length_prefixed(&extensions, &extension_data)) |
1313 |
|
|
return 0; |
1314 |
✗✓ |
32490 |
if (!tls_extensions[i].clienthello_build(s, &extension_data)) |
1315 |
|
|
return 0; |
1316 |
|
|
} |
1317 |
|
|
|
1318 |
✗✓ |
8221 |
if (!CBB_flush(cbb)) |
1319 |
|
|
return 0; |
1320 |
|
|
|
1321 |
|
8221 |
return 1; |
1322 |
|
8221 |
} |
1323 |
|
|
|
1324 |
|
|
int |
1325 |
|
|
tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert) |
1326 |
|
|
{ |
1327 |
|
|
struct tls_extension *tlsext; |
1328 |
|
|
size_t i; |
1329 |
|
|
|
1330 |
✓✗ |
8291 |
for (i = 0; i < N_TLS_EXTENSIONS; i++) { |
1331 |
|
3808 |
tlsext = &tls_extensions[i]; |
1332 |
|
|
|
1333 |
✓✓ |
3808 |
if (tlsext->type != type) |
1334 |
|
|
continue; |
1335 |
✓✓ |
675 |
if (!tlsext->clienthello_parse(s, cbs, alert)) |
1336 |
|
7 |
return 0; |
1337 |
✗✓ |
668 |
if (CBS_len(cbs) != 0) { |
1338 |
|
|
*alert = SSL_AD_DECODE_ERROR; |
1339 |
|
|
return 0; |
1340 |
|
|
} |
1341 |
|
|
|
1342 |
|
668 |
return 1; |
1343 |
|
|
} |
1344 |
|
|
|
1345 |
|
|
/* Not found. */ |
1346 |
|
|
return 2; |
1347 |
|
675 |
} |
1348 |
|
|
|
1349 |
|
|
int |
1350 |
|
|
tlsext_serverhello_build(SSL *s, CBB *cbb) |
1351 |
|
|
{ |
1352 |
|
528 |
CBB extensions, extension_data; |
1353 |
|
|
struct tls_extension *tlsext; |
1354 |
|
|
size_t i; |
1355 |
|
|
|
1356 |
✗✓ |
264 |
if (!CBB_add_u16_length_prefixed(cbb, &extensions)) |
1357 |
|
|
return 0; |
1358 |
|
|
|
1359 |
✓✓ |
5280 |
for (i = 0; i < N_TLS_EXTENSIONS; i++) { |
1360 |
|
2376 |
tlsext = &tls_extensions[i]; |
1361 |
|
|
|
1362 |
✓✓ |
2376 |
if (!tlsext->serverhello_needs(s)) |
1363 |
|
|
continue; |
1364 |
|
|
|
1365 |
✗✓ |
652 |
if (!CBB_add_u16(&extensions, tlsext->type)) |
1366 |
|
|
return 0; |
1367 |
✗✓ |
652 |
if (!CBB_add_u16_length_prefixed(&extensions, &extension_data)) |
1368 |
|
|
return 0; |
1369 |
✗✓ |
652 |
if (!tlsext->serverhello_build(s, &extension_data)) |
1370 |
|
|
return 0; |
1371 |
|
|
} |
1372 |
|
|
|
1373 |
✗✓ |
264 |
if (!CBB_flush(cbb)) |
1374 |
|
|
return 0; |
1375 |
|
|
|
1376 |
|
264 |
return 1; |
1377 |
|
264 |
} |
1378 |
|
|
|
1379 |
|
|
int |
1380 |
|
|
tlsext_serverhello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert) |
1381 |
|
|
{ |
1382 |
|
|
struct tls_extension *tlsext; |
1383 |
|
|
size_t i; |
1384 |
|
|
|
1385 |
✓✗ |
65028 |
for (i = 0; i < N_TLS_EXTENSIONS; i++) { |
1386 |
|
27344 |
tlsext = &tls_extensions[i]; |
1387 |
|
|
|
1388 |
✓✓ |
27344 |
if (tlsext->type != type) |
1389 |
|
|
continue; |
1390 |
✓✓ |
10340 |
if (!tlsext->serverhello_parse(s, cbs, alert)) |
1391 |
|
10 |
return 0; |
1392 |
✗✓ |
10330 |
if (CBS_len(cbs) != 0) { |
1393 |
|
|
*alert = SSL_AD_DECODE_ERROR; |
1394 |
|
|
return 0; |
1395 |
|
|
} |
1396 |
|
|
|
1397 |
|
10330 |
return 1; |
1398 |
|
|
} |
1399 |
|
|
|
1400 |
|
|
/* Not found. */ |
1401 |
|
|
return 2; |
1402 |
|
10340 |
} |