diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/tls13_handshake.c | 190 |
1 files changed, 184 insertions, 6 deletions
diff --git a/src/lib/libssl/tls13_handshake.c b/src/lib/libssl/tls13_handshake.c index c18a2dfe06..578cea338f 100644 --- a/src/lib/libssl/tls13_handshake.c +++ b/src/lib/libssl/tls13_handshake.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls13_handshake.c,v 1.65 2021/03/21 18:36:34 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_handshake.c,v 1.66 2021/06/28 15:35:14 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org> |
| 4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> |
| @@ -48,6 +48,9 @@ static int tls13_handshake_send_action(struct tls13_ctx *ctx, | |||
| 48 | static int tls13_handshake_recv_action(struct tls13_ctx *ctx, | 48 | static int tls13_handshake_recv_action(struct tls13_ctx *ctx, |
| 49 | const struct tls13_handshake_action *action); | 49 | const struct tls13_handshake_action *action); |
| 50 | 50 | ||
| 51 | static int tls13_handshake_set_legacy_state(struct tls13_ctx *ctx); | ||
| 52 | static int tls13_handshake_legacy_info_callback(struct tls13_ctx *ctx); | ||
| 53 | |||
| 51 | static const struct tls13_handshake_action state_machine[] = { | 54 | static const struct tls13_handshake_action state_machine[] = { |
| 52 | [CLIENT_HELLO] = { | 55 | [CLIENT_HELLO] = { |
| 53 | .handshake_type = TLS13_MT_CLIENT_HELLO, | 56 | .handshake_type = TLS13_MT_CLIENT_HELLO, |
| @@ -344,9 +347,20 @@ tls13_handshake_perform(struct tls13_ctx *ctx) | |||
| 344 | int ret; | 347 | int ret; |
| 345 | 348 | ||
| 346 | if (!ctx->handshake_started) { | 349 | if (!ctx->handshake_started) { |
| 350 | /* | ||
| 351 | * Set legacy state to connect/accept and call info callback | ||
| 352 | * to signal that the handshake started. | ||
| 353 | */ | ||
| 354 | if (!tls13_handshake_set_legacy_state(ctx)) | ||
| 355 | return TLS13_IO_FAILURE; | ||
| 356 | if (!tls13_handshake_legacy_info_callback(ctx)) | ||
| 357 | return TLS13_IO_FAILURE; | ||
| 358 | |||
| 347 | ctx->handshake_started = 1; | 359 | ctx->handshake_started = 1; |
| 348 | if (ctx->info_cb != NULL) | 360 | |
| 349 | ctx->info_cb(ctx, TLS13_INFO_HANDSHAKE_STARTED, 1); | 361 | /* Set legacy state for initial ClientHello read or write. */ |
| 362 | if (!tls13_handshake_set_legacy_state(ctx)) | ||
| 363 | return TLS13_IO_FAILURE; | ||
| 350 | } | 364 | } |
| 351 | 365 | ||
| 352 | for (;;) { | 366 | for (;;) { |
| @@ -356,9 +370,12 @@ tls13_handshake_perform(struct tls13_ctx *ctx) | |||
| 356 | if (action->handshake_complete) { | 370 | if (action->handshake_complete) { |
| 357 | ctx->handshake_completed = 1; | 371 | ctx->handshake_completed = 1; |
| 358 | tls13_record_layer_handshake_completed(ctx->rl); | 372 | tls13_record_layer_handshake_completed(ctx->rl); |
| 359 | if (ctx->info_cb != NULL) | 373 | |
| 360 | ctx->info_cb(ctx, | 374 | if (!tls13_handshake_set_legacy_state(ctx)) |
| 361 | TLS13_INFO_HANDSHAKE_COMPLETED, 1); | 375 | return TLS13_IO_FAILURE; |
| 376 | if (!tls13_handshake_legacy_info_callback(ctx)) | ||
| 377 | return TLS13_IO_FAILURE; | ||
| 378 | |||
| 362 | return TLS13_IO_SUCCESS; | 379 | return TLS13_IO_SUCCESS; |
| 363 | } | 380 | } |
| 364 | 381 | ||
| @@ -385,8 +402,14 @@ tls13_handshake_perform(struct tls13_ctx *ctx) | |||
| 385 | return ret; | 402 | return ret; |
| 386 | } | 403 | } |
| 387 | 404 | ||
| 405 | if (!tls13_handshake_legacy_info_callback(ctx)) | ||
| 406 | return TLS13_IO_FAILURE; | ||
| 407 | |||
| 388 | if (!tls13_handshake_advance_state_machine(ctx)) | 408 | if (!tls13_handshake_advance_state_machine(ctx)) |
| 389 | return TLS13_IO_FAILURE; | 409 | return TLS13_IO_FAILURE; |
| 410 | |||
| 411 | if (!tls13_handshake_set_legacy_state(ctx)) | ||
| 412 | return TLS13_IO_FAILURE; | ||
| 390 | } | 413 | } |
| 391 | } | 414 | } |
| 392 | 415 | ||
| @@ -517,3 +540,158 @@ tls13_handshake_recv_action(struct tls13_ctx *ctx, | |||
| 517 | 540 | ||
| 518 | return ret; | 541 | return ret; |
| 519 | } | 542 | } |
| 543 | |||
| 544 | struct tls13_handshake_legacy_state { | ||
| 545 | int recv; | ||
| 546 | int send; | ||
| 547 | }; | ||
| 548 | |||
| 549 | static const struct tls13_handshake_legacy_state legacy_states[] = { | ||
| 550 | [CLIENT_HELLO] = { | ||
| 551 | .recv = SSL3_ST_SR_CLNT_HELLO_A, | ||
| 552 | .send = SSL3_ST_CW_CLNT_HELLO_A, | ||
| 553 | }, | ||
| 554 | [SERVER_HELLO_RETRY_REQUEST] = { | ||
| 555 | .recv = SSL3_ST_CR_SRVR_HELLO_A, | ||
| 556 | .send = SSL3_ST_SW_SRVR_HELLO_A, | ||
| 557 | }, | ||
| 558 | [CLIENT_HELLO_RETRY] = { | ||
| 559 | .recv = SSL3_ST_SR_CLNT_HELLO_A, | ||
| 560 | .send = SSL3_ST_CW_CLNT_HELLO_A, | ||
| 561 | }, | ||
| 562 | [SERVER_HELLO] = { | ||
| 563 | .recv = SSL3_ST_CR_SRVR_HELLO_A, | ||
| 564 | .send = SSL3_ST_SW_SRVR_HELLO_A, | ||
| 565 | }, | ||
| 566 | [SERVER_ENCRYPTED_EXTENSIONS] = { | ||
| 567 | .send = 0, | ||
| 568 | .recv = 0, | ||
| 569 | }, | ||
| 570 | [SERVER_CERTIFICATE_REQUEST] = { | ||
| 571 | .recv = SSL3_ST_CR_CERT_REQ_A, | ||
| 572 | .send = SSL3_ST_SW_CERT_REQ_A, | ||
| 573 | }, | ||
| 574 | [SERVER_CERTIFICATE] = { | ||
| 575 | .recv = SSL3_ST_CR_CERT_A, | ||
| 576 | .send = SSL3_ST_SW_CERT_A, | ||
| 577 | }, | ||
| 578 | [SERVER_CERTIFICATE_VERIFY] = { | ||
| 579 | .send = 0, | ||
| 580 | .recv = 0, | ||
| 581 | }, | ||
| 582 | [SERVER_FINISHED] = { | ||
| 583 | .recv = SSL3_ST_CR_FINISHED_A, | ||
| 584 | .send = SSL3_ST_SW_FINISHED_A, | ||
| 585 | }, | ||
| 586 | [CLIENT_END_OF_EARLY_DATA] = { | ||
| 587 | .send = 0, | ||
| 588 | .recv = 0, | ||
| 589 | }, | ||
| 590 | [CLIENT_CERTIFICATE] = { | ||
| 591 | .recv = SSL3_ST_SR_CERT_VRFY_A, | ||
| 592 | .send = SSL3_ST_CW_CERT_VRFY_B, | ||
| 593 | }, | ||
| 594 | [CLIENT_CERTIFICATE_VERIFY] = { | ||
| 595 | .send = 0, | ||
| 596 | .recv = 0, | ||
| 597 | }, | ||
| 598 | [CLIENT_FINISHED] = { | ||
| 599 | .recv = SSL3_ST_SR_FINISHED_A, | ||
| 600 | .send = SSL3_ST_CW_FINISHED_A, | ||
| 601 | }, | ||
| 602 | [APPLICATION_DATA] = { | ||
| 603 | .recv = 0, | ||
| 604 | .send = 0, | ||
| 605 | }, | ||
| 606 | }; | ||
| 607 | |||
| 608 | CTASSERT(sizeof(state_machine) / sizeof(state_machine[0]) == | ||
| 609 | sizeof(legacy_states) / sizeof(legacy_states[0])); | ||
| 610 | |||
| 611 | static int | ||
| 612 | tls13_handshake_legacy_state(struct tls13_ctx *ctx, int *out_state) | ||
| 613 | { | ||
| 614 | const struct tls13_handshake_action *action; | ||
| 615 | enum tls13_message_type mt; | ||
| 616 | |||
| 617 | *out_state = 0; | ||
| 618 | |||
| 619 | if (!ctx->handshake_started) { | ||
| 620 | if (ctx->mode == TLS13_HS_CLIENT) | ||
| 621 | *out_state = SSL_ST_CONNECT; | ||
| 622 | else | ||
| 623 | *out_state = SSL_ST_ACCEPT; | ||
| 624 | |||
| 625 | return 1; | ||
| 626 | } | ||
| 627 | |||
| 628 | if (ctx->handshake_completed) { | ||
| 629 | *out_state = SSL_ST_OK; | ||
| 630 | return 1; | ||
| 631 | } | ||
| 632 | |||
| 633 | if ((mt = tls13_handshake_active_state(ctx)) == INVALID) | ||
| 634 | return 0; | ||
| 635 | |||
| 636 | if ((action = tls13_handshake_active_action(ctx)) == NULL) | ||
| 637 | return 0; | ||
| 638 | |||
| 639 | if (ctx->mode == action->sender) | ||
| 640 | *out_state = legacy_states[mt].send; | ||
| 641 | else | ||
| 642 | *out_state = legacy_states[mt].recv; | ||
| 643 | |||
| 644 | return 1; | ||
| 645 | } | ||
| 646 | |||
| 647 | static int | ||
| 648 | tls13_handshake_info_position(struct tls13_ctx *ctx) | ||
| 649 | { | ||
| 650 | if (!ctx->handshake_started) | ||
| 651 | return TLS13_INFO_HANDSHAKE_STARTED; | ||
| 652 | |||
| 653 | if (ctx->handshake_completed) | ||
| 654 | return TLS13_INFO_HANDSHAKE_COMPLETED; | ||
| 655 | |||
| 656 | if (ctx->mode == TLS13_HS_CLIENT) | ||
| 657 | return TLS13_INFO_CONNECT_LOOP; | ||
| 658 | else | ||
| 659 | return TLS13_INFO_ACCEPT_LOOP; | ||
| 660 | } | ||
| 661 | |||
| 662 | static int | ||
| 663 | tls13_handshake_legacy_info_callback(struct tls13_ctx *ctx) | ||
| 664 | { | ||
| 665 | int state, where; | ||
| 666 | |||
| 667 | if (!tls13_handshake_legacy_state(ctx, &state)) | ||
| 668 | return 0; | ||
| 669 | |||
| 670 | /* Do nothing if there's no corresponding legacy state. */ | ||
| 671 | if (state == 0) | ||
| 672 | return 1; | ||
| 673 | |||
| 674 | if (ctx->info_cb != NULL) { | ||
| 675 | where = tls13_handshake_info_position(ctx); | ||
| 676 | ctx->info_cb(ctx, where, 1); | ||
| 677 | } | ||
| 678 | |||
| 679 | return 1; | ||
| 680 | } | ||
| 681 | |||
| 682 | static int | ||
| 683 | tls13_handshake_set_legacy_state(struct tls13_ctx *ctx) | ||
| 684 | { | ||
| 685 | int state; | ||
| 686 | |||
| 687 | if (!tls13_handshake_legacy_state(ctx, &state)) | ||
| 688 | return 0; | ||
| 689 | |||
| 690 | /* Do nothing if there's no corresponding legacy state. */ | ||
| 691 | if (state == 0) | ||
| 692 | return 1; | ||
| 693 | |||
| 694 | ctx->hs->state = state; | ||
| 695 | |||
| 696 | return 1; | ||
| 697 | } | ||
