diff options
author | tb <> | 2021-06-28 15:35:14 +0000 |
---|---|---|
committer | tb <> | 2021-06-28 15:35:14 +0000 |
commit | de2554facf2b2abbf75cfd7110e03bfafca9a740 (patch) | |
tree | c0257daa63684c6253b0de3c2ffb4971d42ad429 /src | |
parent | 965b27267cd3ec2efbae469ff3190c696e822852 (diff) | |
download | openbsd-de2554facf2b2abbf75cfd7110e03bfafca9a740.tar.gz openbsd-de2554facf2b2abbf75cfd7110e03bfafca9a740.tar.bz2 openbsd-de2554facf2b2abbf75cfd7110e03bfafca9a740.zip |
Expand info callback support for TLSv1.3
During the TLSv1.3 handshake, update the legacy state and call the
info callback at the appropriate moment. This is done by mapping
the TLSv1.3 states to the states in the old state machine whenever
that is possible. The callbacks are called at the beginning and end
of the handshake, and just before the state machine advances.
This should fix a periodic warning in logs of tor relays about a
variable that wasn't set although it should have been.
input/ok jsing, ok inoguchi (early version)
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); |