Skip to content

Commit

Permalink
tls/ossl: Added new error codes to TLS api
Browse files Browse the repository at this point in the history
Added a number of error codes to report different connection error
conditions encountered with OpenSSL:

* ERROR_WRONG_VERSION_NUMBER - this error is reported when an invalid
  version number is encountered (this is distinctive to an unsupported
  version number).  This error routinely occurs when attempting to
  connect to a TLS enabled endpoint using a non-TLS connection

* ERROR_HTTP_REQUEST - Similar to ERROR_WRONG_VERSION_NUMBER, however
  this will be reported if the start of the packet begins with an HTTP
  verb such as GET or POST

* ERROR_HTTPS_PROXY_REQUEST - Similar to the above but the verb
  encountered starts with 'CONNE'

Added method that can be used to override the OpenSSL message with one
that may be more helpful to users.

Signed-off-by: Michael Boquard <[email protected]>
  • Loading branch information
michael-redpanda authored and ballard26 committed Jan 10, 2025
1 parent bb1c5fd commit c9352b7
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
3 changes: 3 additions & 0 deletions include/seastar/net/tls.hh
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,9 @@ namespace tls {
extern const int ERROR_NO_CIPHER_SUITES;
extern const int ERROR_DECRYPTION_FAILED;
extern const int ERROR_MAC_VERIFY_FAILED;
extern const int ERROR_WRONG_VERSION_NUMBER;
extern const int ERROR_HTTP_REQUEST;
extern const int ERROR_HTTPS_PROXY_REQUEST;
}
}

Expand Down
54 changes: 43 additions & 11 deletions src/net/ossl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,16 @@ struct is_error_code_enum<seastar::ossl_errc> : true_type {};
}

template<>
struct fmt::formatter<seastar::ossl_errc> : public fmt::formatter<std::string_view> {
auto format(seastar::ossl_errc error, fmt::format_context& ctx) const -> decltype(ctx.out()) {
constexpr size_t error_buf_size = 256;
// Buffer passed to ERR_error_string must be at least 256 bytes large
// https://www.openssl.org/docs/man3.0/man3/ERR_error_string_n.html
std::array<char, error_buf_size> buf{};
ERR_error_string_n(
static_cast<unsigned long>(error), buf.data(), buf.size());
// ERR_error_string_n does include the terminating null character
return fmt::format_to(ctx.out(), "{}", buf.data());
}
struct fmt::formatter<seastar::ossl_errc> :
public fmt::formatter<std::string_view> {
/**
* Some OpenSSL errors are hard to parse. This method can be used to provide
* an alternative, more readable, error message.
*/
static std::optional<seastar::sstring>
alternate_message(seastar::ossl_errc error);

auto format(seastar::ossl_errc error, fmt::format_context& ctx) const -> decltype(ctx.out());
};

namespace seastar {
Expand Down Expand Up @@ -2077,3 +2076,36 @@ const int seastar::tls::ERROR_DECRYPTION_FAILED = ERR_PACK(
ERR_LIB_SSL, 0, SSL_R_DECRYPTION_FAILED);
const int seastar::tls::ERROR_MAC_VERIFY_FAILED = ERR_PACK(
ERR_LIB_SSL, 0, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
const int seastar::tls::ERROR_WRONG_VERSION_NUMBER = ERR_PACK(
ERR_LIB_SSL, 0, SSL_R_WRONG_VERSION_NUMBER);
const int seastar::tls::ERROR_HTTP_REQUEST = ERR_PACK(
ERR_LIB_SSL, 0, SSL_R_HTTP_REQUEST);
const int seastar::tls::ERROR_HTTPS_PROXY_REQUEST = ERR_PACK(
ERR_LIB_SSL, 0, SSL_R_HTTPS_PROXY_REQUEST);

std::optional<seastar::sstring> fmt::formatter<seastar::ossl_errc>::alternate_message(seastar::ossl_errc error) {
switch(static_cast<int>(error)) {
case seastar::tls::ERROR_WRONG_VERSION_NUMBER:
return "Wrong SSL Version number: ensure client is configured to use TLS";
case seastar::tls::ERROR_HTTP_REQUEST:
return "Received HTTP request on HTTPS server";
case seastar::tls::ERROR_HTTPS_PROXY_REQUEST:
return "Received HTTPS proxy request";
}

return std::nullopt;
}

auto fmt::formatter<seastar::ossl_errc>::format(seastar::ossl_errc error, fmt::format_context& ctx) const -> decltype(ctx.out()) {
if (auto alternate = alternate_message(error); alternate.has_value()) {
return fmt::format_to(ctx.out(), "{}", alternate.value());
}
constexpr size_t error_buf_size = 256;
// Buffer passed to ERR_error_string must be at least 256 bytes large
// https://www.openssl.org/docs/man3.0/man3/ERR_error_string_n.html
std::array<char, error_buf_size> buf{};
ERR_error_string_n(
static_cast<unsigned long>(error), buf.data(), buf.size());
// ERR_error_string_n does include the terminating null character
return fmt::format_to(ctx.out(), "{}", buf.data());
}
3 changes: 3 additions & 0 deletions src/net/tls.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1397,3 +1397,6 @@ const int seastar::tls::ERROR_UNSUPPORTED_VERSION = GNUTLS_E_UNSUPPORTED_VERSION
const int seastar::tls::ERROR_NO_CIPHER_SUITES = GNUTLS_E_NO_CIPHER_SUITES;
const int seastar::tls::ERROR_DECRYPTION_FAILED = GNUTLS_E_DECRYPTION_FAILED;
const int seastar::tls::ERROR_MAC_VERIFY_FAILED = GNUTLS_E_MAC_VERIFY_FAILED;
const int seastar::tls::ERROR_WRONG_VERSION_NUMBER = GNUTLS_E_UNEXPECTED_PACKET;
const int seastar::tls::ERROR_HTTP_REQUEST = GNUTLS_E_UNEXPECTED_PACKET;
const int seastar::tls::ERROR_HTTPS_PROXY_REQUEST = GNUTLS_E_UNEXPECTED_PACKET;

0 comments on commit c9352b7

Please sign in to comment.