From 51734088efba05e7404c303136447844255aa3b1 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Thu, 4 Mar 2021 12:17:24 +0100 Subject: [PATCH] Print handshake errors in a better way We completely ignore the ErrorStack value if it is an X509 verification failure. --- boring/src/ssl/error.rs | 63 ++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/boring/src/ssl/error.rs b/boring/src/ssl/error.rs index 91bdbb4e..674e221c 100644 --- a/boring/src/ssl/error.rs +++ b/boring/src/ssl/error.rs @@ -4,6 +4,7 @@ use std::error; use std::error::Error as StdError; use std::fmt; use std::io; +use std::path::Path; use error::ErrorStack; use ssl::MidHandshakeSslStream; @@ -150,29 +151,63 @@ impl StdError for HandshakeError { } } -impl fmt::Display for HandshakeError { +impl fmt::Display for HandshakeError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - HandshakeError::SetupFailure(ref e) => write!(f, "stream setup failed: {}", e)?, - HandshakeError::Failure(ref s) => { - write!(f, "the handshake failed: {}", s.error())?; - let verify = s.ssl().verify_result(); - if verify != X509VerifyResult::OK { - write!(f, ": {}", verify)?; - } + HandshakeError::SetupFailure(ref e) => { + write!(f, "TLS stream setup failed:\n\n{}", e) } + HandshakeError::Failure(ref s) => fmt_mid_handshake_error(s, f, "TLS handshake failed"), HandshakeError::WouldBlock(ref s) => { - write!(f, "the handshake was interrupted: {}", s.error())?; - let verify = s.ssl().verify_result(); - if verify != X509VerifyResult::OK { - write!(f, ": {}", verify)?; - } + fmt_mid_handshake_error(s, f, "TLS handshake interrupted") } } - Ok(()) } } +fn fmt_mid_handshake_error( + s: &MidHandshakeSslStream, + f: &mut fmt::Formatter, + prefix: &str, +) -> fmt::Result { + match s.ssl().verify_result() { + X509VerifyResult::OK => write!(f, "{}", prefix)?, + verify => write!(f, "{}: cert verification failed - {}", prefix, verify)?, + } + + if let Some(error) = s.error().io_error() { + return write!(f, " ({})", error); + } + + if let Some(error) = s.error().ssl_error() { + let errors = error.errors(); + + if errors.is_empty() { + return Ok(()); + } + + f.write_str(":\n")?; + + for error in errors { + let path = error.file(); + let file = Path::new(path) + .file_name() + .and_then(|name| name.to_str()) + .unwrap_or(path); + + write!( + f, + "\n{} [{}] ({}:{})", + error.reason().unwrap_or("unknown error"), + error.code(), + file, + error.line() + )?; + } + } + Ok(()) +} + impl From for HandshakeError { fn from(e: ErrorStack) -> HandshakeError { HandshakeError::SetupFailure(e)