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