diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/tls13_handshake.c | 190 | ||||
-rw-r--r-- | src/lib/libssl/tls13_internal.h | 4 |
2 files changed, 187 insertions, 7 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 | } | ||
diff --git a/src/lib/libssl/tls13_internal.h b/src/lib/libssl/tls13_internal.h index 973661acc9..30ef7dd931 100644 --- a/src/lib/libssl/tls13_internal.h +++ b/src/lib/libssl/tls13_internal.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_internal.h,v 1.89 2021/03/21 18:36:34 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_internal.h,v 1.90 2021/06/28 15:35:14 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2018 Bob Beck <beck@openbsd.org> |
4 | * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> | 4 | * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> |
@@ -81,6 +81,8 @@ __BEGIN_HIDDEN_DECLS | |||
81 | 81 | ||
82 | #define TLS13_INFO_HANDSHAKE_STARTED SSL_CB_HANDSHAKE_START | 82 | #define TLS13_INFO_HANDSHAKE_STARTED SSL_CB_HANDSHAKE_START |
83 | #define TLS13_INFO_HANDSHAKE_COMPLETED SSL_CB_HANDSHAKE_DONE | 83 | #define TLS13_INFO_HANDSHAKE_COMPLETED SSL_CB_HANDSHAKE_DONE |
84 | #define TLS13_INFO_ACCEPT_LOOP SSL_CB_ACCEPT_LOOP | ||
85 | #define TLS13_INFO_CONNECT_LOOP SSL_CB_CONNECT_LOOP | ||
84 | 86 | ||
85 | typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg); | 87 | typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg); |
86 | typedef ssize_t (*tls13_phh_recv_cb)(void *_cb_arg, CBS *_cbs); | 88 | typedef ssize_t (*tls13_phh_recv_cb)(void *_cb_arg, CBS *_cbs); |