A tokio_boring::HandshakeError wraps a boring::ssl::HandshakeError with a different stream type. However, the latter exposes either an ErrorStack (if the failure was in setup) or an ssl::Error (if the failure was actually during the handshake), while the former provides no way to get at either besides the code() and as_io_error() accessors (and stringification). This is frustrating for us (Signal), where we'd like to log errors but only if we can guarantee they don't have user data in them; as is, we can only log the code() when using a tokio handshake, which often omits the actual reason a handshake failed.