From f60bcfb3ef5218bc92dd4e5ea9d64d9456236bdb Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 18 Aug 2017 15:23:44 -0400 Subject: [PATCH] Make SSL_state_string_long work for TLS 1.3. SSL_state_string_long and SSL_state_string are often used for debugging purposes. The latter's 6-letter codes are absurd, but SSL_state_string_long is plausible. So we don't lose this when converging state machines or switching to TLS 1.3, add this to TLS 1.3. Bug: 128 Change-Id: Iec6529a4d9eddcf08bc9610137b4ccf9ea2681a6 Reviewed-on: https://boringssl-review.googlesource.com/19524 Commit-Queue: Steven Valdez Reviewed-by: Steven Valdez CQ-Verified: CQ bot account: commit-bot@chromium.org --- ssl/internal.h | 5 +++++ ssl/ssl_stat.cc | 4 ++++ ssl/tls13_client.cc | 41 +++++++++++++++++++++++++++++++++++++++++ ssl/tls13_server.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ tool/client.cc | 22 ++++++++++++++++++++++ tool/server.cc | 22 ++++++++++++++++++++++ 6 files changed, 139 insertions(+) diff --git a/ssl/internal.h b/ssl/internal.h index ea883e53..40e4e4e5 100644 --- a/ssl/internal.h +++ b/ssl/internal.h @@ -1336,6 +1336,11 @@ int tls13_handshake(SSL_HANDSHAKE *hs, int *out_early_return); enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs); enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs); +/* The following functions return human-readable representations of the TLS 1.3 + * handshake states for debugging. */ +const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs); +const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs); + /* tls13_post_handshake processes a post-handshake message. It returns one on * success and zero on failure. */ int tls13_post_handshake(SSL *ssl, const SSLMessage &msg); diff --git a/ssl/ssl_stat.cc b/ssl/ssl_stat.cc index 56e4f2bc..31cce4dc 100644 --- a/ssl/ssl_stat.cc +++ b/ssl/ssl_stat.cc @@ -195,6 +195,10 @@ const char *SSL_state_string_long(const SSL *ssl) { case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: return "DTLS1 read hello verify request A"; + case SSL_ST_TLS13: + return ssl->server ? tls13_server_handshake_state(ssl->s3->hs) + : tls13_client_handshake_state(ssl->s3->hs); + default: return "unknown state"; } diff --git a/ssl/tls13_client.cc b/ssl/tls13_client.cc index 98e70a7f..6608404b 100644 --- a/ssl/tls13_client.cc +++ b/ssl/tls13_client.cc @@ -733,6 +733,10 @@ enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs) { break; } + if (hs->state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_CONNECT_LOOP, 1); + } + if (ret != ssl_hs_ok) { return ret; } @@ -741,6 +745,43 @@ enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs) { return ssl_hs_ok; } +const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs) { + enum client_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_read_hello_retry_request: + return "TLS 1.3 client read_hello_retry_request"; + case state_send_second_client_hello: + return "TLS 1.3 client send_second_client_hello"; + case state_read_server_hello: + return "TLS 1.3 client read_server_hello"; + case state_process_change_cipher_spec: + return "TLS 1.3 client process_change_cipher_spec"; + case state_read_encrypted_extensions: + return "TLS 1.3 client read_encrypted_extensions"; + case state_read_certificate_request: + return "TLS 1.3 client read_certificate_request"; + case state_read_server_certificate: + return "TLS 1.3 client read_server_certificate"; + case state_read_server_certificate_verify: + return "TLS 1.3 client read_server_certificate_verify"; + case state_read_server_finished: + return "TLS 1.3 client read_server_finished"; + case state_send_end_of_early_data: + return "TLS 1.3 client send_end_of_early_data"; + case state_send_client_certificate: + return "TLS 1.3 client send_client_certificate"; + case state_send_client_certificate_verify: + return "TLS 1.3 client send_client_certificate_verify"; + case state_complete_second_flight: + return "TLS 1.3 client complete_second_flight"; + case state_done: + return "TLS 1.3 client done"; + } + + return "TLS 1.3 client unknown"; +} + int tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg) { UniquePtr session(SSL_SESSION_dup(ssl->s3->established_session, SSL_SESSION_INCLUDE_NONAUTH)); diff --git a/ssl/tls13_server.cc b/ssl/tls13_server.cc index a3ed8a7f..894fa87d 100644 --- a/ssl/tls13_server.cc +++ b/ssl/tls13_server.cc @@ -922,6 +922,10 @@ enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) { break; } + if (hs->state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1); + } + if (ret != ssl_hs_ok) { return ret; } @@ -930,4 +934,45 @@ enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) { return ssl_hs_ok; } +const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs) { + enum server_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_select_parameters: + return "TLS 1.3 server select_parameters"; + case state_select_session: + return "TLS 1.3 server select_session"; + case state_send_hello_retry_request: + return "TLS 1.3 server send_hello_retry_request"; + case state_read_second_client_hello: + return "TLS 1.3 server read_second_client_hello"; + case state_send_server_hello: + return "TLS 1.3 server send_server_hello"; + case state_send_server_certificate_verify: + return "TLS 1.3 server send_server_certificate_verify"; + case state_send_server_finished: + return "TLS 1.3 server send_server_finished"; + case state_read_second_client_flight: + return "TLS 1.3 server read_second_client_flight"; + case state_process_change_cipher_spec: + return "TLS 1.3 server process_change_cipher_spec"; + case state_process_end_of_early_data: + return "TLS 1.3 server process_end_of_early_data"; + case state_read_client_certificate: + return "TLS 1.3 server read_client_certificate"; + case state_read_client_certificate_verify: + return "TLS 1.3 server read_client_certificate_verify"; + case state_read_channel_id: + return "TLS 1.3 server read_channel_id"; + case state_read_client_finished: + return "TLS 1.3 server read_client_finished"; + case state_send_new_session_ticket: + return "TLS 1.3 server send_new_session_ticket"; + case state_done: + return "TLS 1.3 server done"; + } + + return "TLS 1.3 server unknown"; +} + } // namespace bssl diff --git a/tool/client.cc b/tool/client.cc index 138a0962..a5254b21 100644 --- a/tool/client.cc +++ b/tool/client.cc @@ -138,6 +138,10 @@ static const struct argument kArguments[] = { "-renegotiate-freely", kBooleanArgument, "Allow renegotiations from the peer.", }, + { + "-debug", kBooleanArgument, + "Print debug information about the handshake", + }, { "", kOptionalArgument, "", }, @@ -325,6 +329,20 @@ static bool GetTLS13Variant(tls13_variant_t *out, const std::string &in) { return false; } +static void InfoCallback(const SSL *ssl, int type, int value) { + switch (type) { + case SSL_CB_HANDSHAKE_START: + fprintf(stderr, "Handshake started.\n"); + break; + case SSL_CB_HANDSHAKE_DONE: + fprintf(stderr, "Handshake done.\n"); + break; + case SSL_CB_CONNECT_LOOP: + fprintf(stderr, "Handshake progress: %s\n", SSL_state_string_long(ssl)); + break; + } +} + bool Client(const std::vector &args) { if (!InitSocketLibrary()) { return false; @@ -505,6 +523,10 @@ bool Client(const std::vector &args) { SSL_CTX_set_ed25519_enabled(ctx.get(), 1); } + if (args_map.count("-debug") != 0) { + SSL_CTX_set_info_callback(ctx.get(), InfoCallback); + } + if (args_map.count("-test-resumption") != 0) { if (args_map.count("-session-in") != 0) { fprintf(stderr, diff --git a/tool/server.cc b/tool/server.cc index 3b125ad1..4cc183b1 100644 --- a/tool/server.cc +++ b/tool/server.cc @@ -70,6 +70,10 @@ static const struct argument kArguments[] = { { "-tls13-variant", kBooleanArgument, "Enable TLS 1.3 variants", }, + { + "-debug", kBooleanArgument, + "Print debug information about the handshake", + }, { "", kOptionalArgument, "", }, @@ -142,6 +146,20 @@ static bssl::UniquePtr MakeSelfSignedCert(EVP_PKEY *evp_pkey, return x509; } +static void InfoCallback(const SSL *ssl, int type, int value) { + switch (type) { + case SSL_CB_HANDSHAKE_START: + fprintf(stderr, "Handshake started.\n"); + break; + case SSL_CB_HANDSHAKE_DONE: + fprintf(stderr, "Handshake done.\n"); + break; + case SSL_CB_ACCEPT_LOOP: + fprintf(stderr, "Handshake progress: %s\n", SSL_state_string_long(ssl)); + break; + } +} + bool Server(const std::vector &args) { if (!InitSocketLibrary()) { return false; @@ -241,6 +259,10 @@ bool Server(const std::vector &args) { SSL_CTX_set_tls13_variant(ctx.get(), tls13_experiment); } + if (args_map.count("-debug") != 0) { + SSL_CTX_set_info_callback(ctx.get(), InfoCallback); + } + Listener listener; if (!listener.Init(args_map["-accept"])) { return false;