commit 7b5f58a1c93f99ef3eaa840b4443ca0a4120a512 Author: Nick Mathewson nickm@torproject.org Date: Fri Jun 26 11:18:38 2020 -0400
Carry TLS error strings forward to controller when reporting them.
Now instead of saying "DONE, DONE" or "MISC, MISC" or "TLS_ERROR, TLS_ERROR", we can finally give a nice sensible "TLS_ERROR, wrong version number" which should help debug a great deal.
Closes ticket 32622. --- src/core/or/connection_or.c | 14 ++++++++++---- src/lib/tls/tortls.h | 1 + src/lib/tls/tortls_nss.c | 13 +++++++++++++ src/lib/tls/tortls_openssl.c | 20 ++++++++++++++++++++ src/lib/tls/tortls_st.h | 3 +++ 5 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/src/core/or/connection_or.c b/src/core/or/connection_or.c index 4cb83f45a..b88d1b6af 100644 --- a/src/core/or/connection_or.c +++ b/src/core/or/connection_or.c @@ -745,10 +745,16 @@ connection_or_about_to_close(or_connection_t *or_conn) int reason = tls_error_to_orconn_end_reason(or_conn->tls_error); connection_or_event_status(or_conn, OR_CONN_EVENT_FAILED, reason); - if (!authdir_mode_tests_reachability(options)) - control_event_bootstrap_prob_or( - orconn_end_reason_to_control_string(reason), - reason, or_conn); + if (!authdir_mode_tests_reachability(options)) { + const char *warning = NULL; + if (reason == END_OR_CONN_REASON_TLS_ERROR && or_conn->tls) { + warning = tor_tls_get_last_error_msg(or_conn->tls); + } + if (warning == NULL) { + warning = orconn_end_reason_to_control_string(reason); + } + control_event_bootstrap_prob_or(warning, reason, or_conn); + } } } } else if (conn->hold_open_until_flushed) { diff --git a/src/lib/tls/tortls.h b/src/lib/tls/tortls.h index e8dbbf527..517cdc17d 100644 --- a/src/lib/tls/tortls.h +++ b/src/lib/tls/tortls.h @@ -81,6 +81,7 @@ void tor_tls_free_all(void); void tor_tls_init(void); void tls_log_errors(tor_tls_t *tls, int severity, int domain, const char *doing); +const char *tor_tls_get_last_error_msg(const tor_tls_t *tls); int tor_tls_context_init(unsigned flags, crypto_pk_t *client_identity, crypto_pk_t *server_identity, diff --git a/src/lib/tls/tortls_nss.c b/src/lib/tls/tortls_nss.c index 62e826211..a9ec731c0 100644 --- a/src/lib/tls/tortls_nss.c +++ b/src/lib/tls/tortls_nss.c @@ -369,6 +369,8 @@ tls_log_errors(tor_tls_t *tls, int severity, int domain,
(void)tls; PRErrorCode code = PORT_GetError(); + if (tls) + tls->last_error = code;
const char *addr = tls ? tls->address : NULL; const char *string = PORT_ErrorToString(code); @@ -391,6 +393,17 @@ tls_log_errors(tor_tls_t *tls, int severity, int domain, with, addr); } } +const char * +tor_tls_get_last_error_msg(const tor_tls_t *tls) +{ + IF_BUG_ONCE(!tls) { + return NULL; + } + if (tls->last_error == 0) { + return NULL; + } + return PORT_ErrorToString((PRErrorCode)tls->last_error); +}
tor_tls_t * tor_tls_new(tor_socket_t sock, int is_server) diff --git a/src/lib/tls/tortls_openssl.c b/src/lib/tls/tortls_openssl.c index 68d6e2aa5..226971414 100644 --- a/src/lib/tls/tortls_openssl.c +++ b/src/lib/tls/tortls_openssl.c @@ -245,10 +245,30 @@ tls_log_errors(tor_tls_t *tls, int severity, int domain, const char *doing) unsigned long err;
while ((err = ERR_get_error()) != 0) { + if (tls) + tls->last_error = err; tor_tls_log_one_error(tls, err, severity, domain, doing); } }
+/** + * Return a string representing more detail about the last error received + * on TLS. + * + * May return null if no error was found. + **/ +const char * +tor_tls_get_last_error_msg(const tor_tls_t *tls) +{ + IF_BUG_ONCE(!tls) { + return NULL; + } + if (tls->last_error == 0) { + return NULL; + } + return (const char*)ERR_reason_error_string(tls->last_error); +} + #define CATCH_SYSCALL 1 #define CATCH_ZERO 2
diff --git a/src/lib/tls/tortls_st.h b/src/lib/tls/tortls_st.h index 925896d49..34abe52ee 100644 --- a/src/lib/tls/tortls_st.h +++ b/src/lib/tls/tortls_st.h @@ -67,6 +67,8 @@ struct tor_tls_t { */ unsigned long last_write_count; unsigned long last_read_count; + /** Most recent error value from ERR_get_error(). */ + unsigned long last_error; /** If set, a callback to invoke whenever the client tries to renegotiate * the handshake. */ void (*negotiated_callback)(tor_tls_t *tls, void *arg); @@ -77,6 +79,7 @@ struct tor_tls_t { /** Last values retried from tor_get_prfiledesc_byte_counts(). */ uint64_t last_write_count; uint64_t last_read_count; + long last_error; #endif };
tor-commits@lists.torproject.org