ssl_tlsext.c revision 1.7
1/* $OpenBSD: ssl_tlsext.c,v 1.7 2017/08/12 21:17:03 doug Exp $ */
2/*
3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include "ssl_locl.h"
20
21#include "bytestring.h"
22#include "ssl_tlsext.h"
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
134/*
135 * Supported Point Formats Extension - RFC 4492 section 5.1.2
136 */
137static int
138tlsext_ecpf_build(SSL *s, CBB *cbb)
139{
140	CBB ecpf;
141	size_t formats_len;
142	const uint8_t *formats;
143
144	tls1_get_formatlist(s, 0, &formats, &formats_len);
145
146	if (formats_len == 0) {
147		SSLerror(s, ERR_R_INTERNAL_ERROR);
148		return 0;
149	}
150
151	if (!CBB_add_u8_length_prefixed(cbb, &ecpf))
152		return 0;
153	if (!CBB_add_bytes(&ecpf, formats, formats_len))
154		return 0;
155	if (!CBB_flush(cbb))
156		return 0;
157
158	return 1;
159}
160
161static int
162tlsext_ecpf_parse(SSL *s, CBS *cbs, int *alert)
163{
164	CBS ecpf;
165
166	if (!CBS_get_u8_length_prefixed(cbs, &ecpf))
167		goto err;
168	if (CBS_len(&ecpf) == 0)
169		goto err;
170	if (CBS_len(cbs) != 0)
171		goto err;
172
173	/* Must contain uncompressed (0) */
174	if (!CBS_contains_zero_byte(&ecpf)) {
175		SSLerror(s, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
176		goto err;
177	}
178
179	if (!s->internal->hit) {
180		if (!CBS_stow(&ecpf, &(SSI(s)->tlsext_ecpointformatlist),
181		    &(SSI(s)->tlsext_ecpointformatlist_length)))
182			goto err;
183	}
184
185	return 1;
186
187 err:
188	*alert = TLS1_AD_INTERNAL_ERROR;
189	return 0;
190}
191
192int
193tlsext_ecpf_clienthello_needs(SSL *s)
194{
195	return ssl_has_ecc_ciphers(s);
196}
197
198int
199tlsext_ecpf_clienthello_build(SSL *s, CBB *cbb)
200{
201	return tlsext_ecpf_build(s, cbb);
202}
203
204int
205tlsext_ecpf_clienthello_parse(SSL *s, CBS *cbs, int *alert)
206{
207	return tlsext_ecpf_parse(s, cbs, alert);
208}
209
210int
211tlsext_ecpf_serverhello_needs(SSL *s)
212{
213	if (s->version == DTLS1_VERSION)
214		return 0;
215
216	return ssl_using_ecc_cipher(s);
217}
218
219int
220tlsext_ecpf_serverhello_build(SSL *s, CBB *cbb)
221{
222	return tlsext_ecpf_build(s, cbb);
223}
224
225int
226tlsext_ecpf_serverhello_parse(SSL *s, CBS *cbs, int *alert)
227{
228	return tlsext_ecpf_parse(s, cbs, alert);
229}
230
231/*
232 * Renegotiation Indication - RFC 5746.
233 */
234int
235tlsext_ri_clienthello_needs(SSL *s)
236{
237	return (s->internal->renegotiate);
238}
239
240int
241tlsext_ri_clienthello_build(SSL *s, CBB *cbb)
242{
243	CBB reneg;
244
245	if (!CBB_add_u8_length_prefixed(cbb, &reneg))
246		return 0;
247	if (!CBB_add_bytes(&reneg, S3I(s)->previous_client_finished,
248	    S3I(s)->previous_client_finished_len))
249		return 0;
250	if (!CBB_flush(cbb))
251		return 0;
252
253	return 1;
254}
255
256int
257tlsext_ri_clienthello_parse(SSL *s, CBS *cbs, int *alert)
258{
259	CBS reneg;
260
261	if (!CBS_get_u8_length_prefixed(cbs, &reneg))
262		goto err;
263	if (CBS_len(cbs) != 0)
264		goto err;
265
266	if (!CBS_mem_equal(&reneg, S3I(s)->previous_client_finished,
267	    S3I(s)->previous_client_finished_len)) {
268		SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH);
269		*alert = SSL_AD_HANDSHAKE_FAILURE;
270		return 0;
271	}
272
273	S3I(s)->renegotiate_seen = 1;
274	S3I(s)->send_connection_binding = 1;
275
276	return 1;
277
278 err:
279	SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR);
280	*alert = SSL_AD_DECODE_ERROR;
281	return 0;
282}
283
284int
285tlsext_ri_serverhello_needs(SSL *s)
286{
287	return (S3I(s)->send_connection_binding);
288}
289
290int
291tlsext_ri_serverhello_build(SSL *s, CBB *cbb)
292{
293	CBB reneg;
294
295	if (!CBB_add_u8_length_prefixed(cbb, &reneg))
296		return 0;
297	if (!CBB_add_bytes(&reneg, S3I(s)->previous_client_finished,
298	    S3I(s)->previous_client_finished_len))
299		return 0;
300	if (!CBB_add_bytes(&reneg, S3I(s)->previous_server_finished,
301	    S3I(s)->previous_server_finished_len))
302		return 0;
303	if (!CBB_flush(cbb))
304		return 0;
305
306	return 1;
307}
308
309int
310tlsext_ri_serverhello_parse(SSL *s, CBS *cbs, int *alert)
311{
312	CBS reneg, prev_client, prev_server;
313
314	/*
315	 * Ensure that the previous client and server values are both not
316	 * present, or that they are both present.
317	 */
318	if ((S3I(s)->previous_client_finished_len == 0 &&
319	    S3I(s)->previous_server_finished_len != 0) ||
320	    (S3I(s)->previous_client_finished_len != 0 &&
321	    S3I(s)->previous_server_finished_len == 0)) {
322		*alert = TLS1_AD_INTERNAL_ERROR;
323		return 0;
324	}
325
326	if (!CBS_get_u8_length_prefixed(cbs, &reneg))
327		goto err;
328	if (!CBS_get_bytes(&reneg, &prev_client,
329	    S3I(s)->previous_client_finished_len))
330		goto err;
331	if (!CBS_get_bytes(&reneg, &prev_server,
332	    S3I(s)->previous_server_finished_len))
333		goto err;
334	if (CBS_len(&reneg) != 0)
335		goto err;
336	if (CBS_len(cbs) != 0)
337		goto err;
338
339	if (!CBS_mem_equal(&prev_client, S3I(s)->previous_client_finished,
340	    S3I(s)->previous_client_finished_len)) {
341		SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH);
342		*alert = SSL_AD_HANDSHAKE_FAILURE;
343		return 0;
344	}
345	if (!CBS_mem_equal(&prev_server, S3I(s)->previous_server_finished,
346	    S3I(s)->previous_server_finished_len)) {
347		SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH);
348		*alert = SSL_AD_HANDSHAKE_FAILURE;
349		return 0;
350	}
351
352	S3I(s)->renegotiate_seen = 1;
353	S3I(s)->send_connection_binding = 1;
354
355	return 1;
356
357 err:
358	SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR);
359	*alert = SSL_AD_DECODE_ERROR;
360	return 0;
361}
362
363/*
364 * Server Name Indication - RFC 6066, section 3.
365 */
366int
367tlsext_sni_clienthello_needs(SSL *s)
368{
369	return (s->tlsext_hostname != NULL);
370}
371
372int
373tlsext_sni_clienthello_build(SSL *s, CBB *cbb)
374{
375	CBB server_name_list, host_name;
376
377	if (!CBB_add_u16_length_prefixed(cbb, &server_name_list))
378		return 0;
379	if (!CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name))
380		return 0;
381	if (!CBB_add_u16_length_prefixed(&server_name_list, &host_name))
382		return 0;
383	if (!CBB_add_bytes(&host_name, (const uint8_t *)s->tlsext_hostname,
384	    strlen(s->tlsext_hostname)))
385		return 0;
386	if (!CBB_flush(cbb))
387		return 0;
388
389	return 1;
390}
391
392int
393tlsext_sni_clienthello_parse(SSL *s, CBS *cbs, int *alert)
394{
395	CBS server_name_list, host_name;
396	uint8_t name_type;
397
398	if (!CBS_get_u16_length_prefixed(cbs, &server_name_list))
399		goto err;
400
401	/*
402	 * RFC 6066 section 3 forbids multiple host names with the same type.
403	 * Additionally, only one type (host_name) is specified.
404	 */
405	if (!CBS_get_u8(&server_name_list, &name_type))
406		goto err;
407	if (name_type != TLSEXT_NAMETYPE_host_name)
408		goto err;
409
410	if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name))
411		goto err;
412	if (CBS_len(&host_name) == 0 ||
413	    CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
414	    CBS_contains_zero_byte(&host_name)) {
415		*alert = TLS1_AD_UNRECOGNIZED_NAME;
416		return 0;
417	}
418
419	if (s->internal->hit) {
420		if (s->session->tlsext_hostname == NULL) {
421			*alert = TLS1_AD_UNRECOGNIZED_NAME;
422			return 0;
423		}
424		if (!CBS_mem_equal(&host_name, s->session->tlsext_hostname,
425		    strlen(s->session->tlsext_hostname))) {
426			*alert = TLS1_AD_UNRECOGNIZED_NAME;
427			return 0;
428		}
429	} else {
430		if (s->session->tlsext_hostname != NULL)
431			goto err;
432		if (!CBS_strdup(&host_name, &s->session->tlsext_hostname)) {
433			*alert = TLS1_AD_INTERNAL_ERROR;
434			return 0;
435		}
436	}
437
438	if (CBS_len(&server_name_list) != 0)
439		goto err;
440	if (CBS_len(cbs) != 0)
441		goto err;
442
443	return 1;
444
445 err:
446	*alert = SSL_AD_DECODE_ERROR;
447	return 0;
448}
449
450int
451tlsext_sni_serverhello_needs(SSL *s)
452{
453	return (s->session->tlsext_hostname != NULL);
454}
455
456int
457tlsext_sni_serverhello_build(SSL *s, CBB *cbb)
458{
459	return 1;
460}
461
462int
463tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert)
464{
465	if (s->tlsext_hostname == NULL || CBS_len(cbs) != 0) {
466		*alert = TLS1_AD_UNRECOGNIZED_NAME;
467		return 0;
468	}
469
470	if (s->internal->hit) {
471		if (s->session->tlsext_hostname == NULL) {
472			*alert = TLS1_AD_UNRECOGNIZED_NAME;
473			return 0;
474		}
475		if (strcmp(s->tlsext_hostname,
476		    s->session->tlsext_hostname) != 0) {
477			*alert = TLS1_AD_UNRECOGNIZED_NAME;
478			return 0;
479		}
480	} else {
481		if (s->session->tlsext_hostname != NULL) {
482			*alert = SSL_AD_DECODE_ERROR;
483			return 0;
484		}
485		if ((s->session->tlsext_hostname =
486		    strdup(s->tlsext_hostname)) == NULL) {
487			*alert = TLS1_AD_INTERNAL_ERROR;
488			return 0;
489		}
490	}
491
492	return 1;
493}
494
495/*
496 * SessionTicket extension - RFC 5077 section 3.2
497 */
498int
499tlsext_sessionticket_clienthello_needs(SSL *s)
500{
501	/*
502	 * Send session ticket extension when enabled and not overridden.
503	 *
504	 * When renegotiating, send an empty session ticket to indicate support.
505	 */
506	if ((SSL_get_options(s) & SSL_OP_NO_TICKET) != 0)
507		return 0;
508
509	if (s->internal->new_session)
510		return 1;
511
512	if (s->internal->tlsext_session_ticket != NULL &&
513	    s->internal->tlsext_session_ticket->data == NULL)
514		return 0;
515
516	return 1;
517}
518
519int
520tlsext_sessionticket_clienthello_build(SSL *s, CBB *cbb)
521{
522	/*
523	 * Signal that we support session tickets by sending an empty
524	 * extension when renegotiating or no session found.
525	 */
526	if (s->internal->new_session || s->session == NULL)
527		return 1;
528
529	if (s->session->tlsext_tick != NULL) {
530		/* Attempt to resume with an existing session ticket */
531		if (!CBB_add_bytes(cbb, s->session->tlsext_tick,
532		    s->session->tlsext_ticklen))
533			return 0;
534
535	} else if (s->internal->tlsext_session_ticket != NULL) {
536		/*
537		 * Attempt to resume with a custom provided session ticket set
538		 * by SSL_set_session_ticket_ext().
539		 */
540		if (s->internal->tlsext_session_ticket->length > 0) {
541			size_t ticklen = s->internal->tlsext_session_ticket->length;
542
543			if ((s->session->tlsext_tick = malloc(ticklen)) == NULL)
544				return 0;
545			memcpy(s->session->tlsext_tick,
546			    s->internal->tlsext_session_ticket->data,
547			    ticklen);
548			s->session->tlsext_ticklen = ticklen;
549
550			if (!CBB_add_bytes(cbb, s->session->tlsext_tick,
551			    s->session->tlsext_ticklen))
552				return 0;
553		}
554	}
555
556	if (!CBB_flush(cbb))
557		return 0;
558
559	return 1;
560}
561
562int
563tlsext_sessionticket_clienthello_parse(SSL *s, CBS *cbs, int *alert)
564{
565	if (s->internal->tls_session_ticket_ext_cb) {
566		if (!s->internal->tls_session_ticket_ext_cb(s, CBS_data(cbs),
567		    (int)CBS_len(cbs),
568		    s->internal->tls_session_ticket_ext_cb_arg)) {
569			*alert = TLS1_AD_INTERNAL_ERROR;
570			return 0;
571		}
572	}
573
574	/* We need to signal that this was processed fully */
575	if (!CBS_skip(cbs, CBS_len(cbs))) {
576		*alert = TLS1_AD_INTERNAL_ERROR;
577		return 0;
578	}
579
580	return 1;
581}
582
583int
584tlsext_sessionticket_serverhello_needs(SSL *s)
585{
586	return (s->internal->tlsext_ticket_expected &&
587	    !(SSL_get_options(s) & SSL_OP_NO_TICKET));
588}
589
590int
591tlsext_sessionticket_serverhello_build(SSL *s, CBB *cbb)
592{
593	/* Empty ticket */
594
595	return 1;
596}
597
598int
599tlsext_sessionticket_serverhello_parse(SSL *s, CBS *cbs, int *alert)
600{
601	if (s->internal->tls_session_ticket_ext_cb) {
602		if (!s->internal->tls_session_ticket_ext_cb(s, CBS_data(cbs),
603		    (int)CBS_len(cbs),
604		    s->internal->tls_session_ticket_ext_cb_arg)) {
605			*alert = TLS1_AD_INTERNAL_ERROR;
606			return 0;
607		}
608	}
609
610	if ((SSL_get_options(s) & SSL_OP_NO_TICKET) != 0 || CBS_len(cbs) > 0) {
611		*alert = TLS1_AD_UNSUPPORTED_EXTENSION;
612		return 0;
613	}
614
615	s->internal->tlsext_ticket_expected = 1;
616
617	return 1;
618}
619
620struct tls_extension {
621	uint16_t type;
622	int (*clienthello_needs)(SSL *s);
623	int (*clienthello_build)(SSL *s, CBB *cbb);
624	int (*clienthello_parse)(SSL *s, CBS *cbs, int *alert);
625	int (*serverhello_needs)(SSL *s);
626	int (*serverhello_build)(SSL *s, CBB *cbb);
627	int (*serverhello_parse)(SSL *s, CBS *cbs, int *alert);
628};
629
630static struct tls_extension tls_extensions[] = {
631	{
632		.type = TLSEXT_TYPE_server_name,
633		.clienthello_needs = tlsext_sni_clienthello_needs,
634		.clienthello_build = tlsext_sni_clienthello_build,
635		.clienthello_parse = tlsext_sni_clienthello_parse,
636		.serverhello_needs = tlsext_sni_serverhello_needs,
637		.serverhello_build = tlsext_sni_serverhello_build,
638		.serverhello_parse = tlsext_sni_serverhello_parse,
639	},
640	{
641		.type = TLSEXT_TYPE_renegotiate,
642		.clienthello_needs = tlsext_ri_clienthello_needs,
643		.clienthello_build = tlsext_ri_clienthello_build,
644		.clienthello_parse = tlsext_ri_clienthello_parse,
645		.serverhello_needs = tlsext_ri_serverhello_needs,
646		.serverhello_build = tlsext_ri_serverhello_build,
647		.serverhello_parse = tlsext_ri_serverhello_parse,
648	},
649	{
650		.type = TLSEXT_TYPE_ec_point_formats,
651		.clienthello_needs = tlsext_ecpf_clienthello_needs,
652		.clienthello_build = tlsext_ecpf_clienthello_build,
653		.clienthello_parse = tlsext_ecpf_clienthello_parse,
654		.serverhello_needs = tlsext_ecpf_serverhello_needs,
655		.serverhello_build = tlsext_ecpf_serverhello_build,
656		.serverhello_parse = tlsext_ecpf_serverhello_parse,
657	},
658	{
659		.type = TLSEXT_TYPE_elliptic_curves,
660		.clienthello_needs = tlsext_ec_clienthello_needs,
661		.clienthello_build = tlsext_ec_clienthello_build,
662		.clienthello_parse = tlsext_ec_clienthello_parse,
663		.serverhello_needs = tlsext_ec_serverhello_needs,
664		.serverhello_build = tlsext_ec_serverhello_build,
665		.serverhello_parse = tlsext_ec_serverhello_parse,
666	},
667	{
668		.type = TLSEXT_TYPE_session_ticket,
669		.clienthello_needs = tlsext_sessionticket_clienthello_needs,
670		.clienthello_build = tlsext_sessionticket_clienthello_build,
671		.clienthello_parse = tlsext_sessionticket_clienthello_parse,
672		.serverhello_needs = tlsext_sessionticket_serverhello_needs,
673		.serverhello_build = tlsext_sessionticket_serverhello_build,
674		.serverhello_parse = tlsext_sessionticket_serverhello_parse,
675	},
676};
677
678#define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions))
679
680int
681tlsext_clienthello_build(SSL *s, CBB *cbb)
682{
683	struct tls_extension *tlsext;
684	CBB extension_data;
685	size_t i;
686
687	memset(&extension_data, 0, sizeof(extension_data));
688
689	for (i = 0; i < N_TLS_EXTENSIONS; i++) {
690		tlsext = &tls_extensions[i];
691
692		if (!tlsext->clienthello_needs(s))
693			continue;
694
695		if (!CBB_add_u16(cbb, tlsext->type))
696			return 0;
697		if (!CBB_add_u16_length_prefixed(cbb, &extension_data))
698			return 0;
699		if (!tls_extensions[i].clienthello_build(s, &extension_data))
700			return 0;
701		if (!CBB_flush(cbb))
702			return 0;
703	}
704
705	return 1;
706}
707
708int
709tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert)
710{
711	struct tls_extension *tlsext;
712	size_t i;
713
714	for (i = 0; i < N_TLS_EXTENSIONS; i++) {
715		tlsext = &tls_extensions[i];
716
717		if (tlsext->type != type)
718			continue;
719		if (!tlsext->clienthello_parse(s, cbs, alert))
720			return 0;
721		if (CBS_len(cbs) != 0) {
722			*alert = SSL_AD_DECODE_ERROR;
723			return 0;
724		}
725
726		return 1;
727	}
728
729	/* Not found. */
730	return 2;
731}
732
733int
734tlsext_serverhello_build(SSL *s, CBB *cbb)
735{
736	struct tls_extension *tlsext;
737	CBB extension_data;
738	size_t i;
739
740	memset(&extension_data, 0, sizeof(extension_data));
741
742	for (i = 0; i < N_TLS_EXTENSIONS; i++) {
743		tlsext = &tls_extensions[i];
744
745		if (!tlsext->serverhello_needs(s))
746			continue;
747
748		if (!CBB_add_u16(cbb, tlsext->type))
749			return 0;
750		if (!CBB_add_u16_length_prefixed(cbb, &extension_data))
751			return 0;
752		if (!tlsext->serverhello_build(s, &extension_data))
753			return 0;
754		if (!CBB_flush(cbb))
755			return 0;
756	}
757
758	return 1;
759}
760
761int
762tlsext_serverhello_parse_one(SSL *s, CBS *cbs, uint16_t type, int *alert)
763{
764	struct tls_extension *tlsext;
765	size_t i;
766
767	for (i = 0; i < N_TLS_EXTENSIONS; i++) {
768		tlsext = &tls_extensions[i];
769
770		if (tlsext->type != type)
771			continue;
772		if (!tlsext->serverhello_parse(s, cbs, alert))
773			return 0;
774		if (CBS_len(cbs) != 0) {
775			*alert = SSL_AD_DECODE_ERROR;
776			return 0;
777		}
778
779		return 1;
780	}
781
782	/* Not found. */
783	return 2;
784}
785