From ee2b5b2ff9fe21de7bcfeb0461e0e84b1e2dfd8b Mon Sep 17 00:00:00 2001 From: Mohammad Nejati Date: Wed, 12 Feb 2025 08:42:45 +0000 Subject: [PATCH] Replace SSL_set1_host with asio::ssl::host_name_verification `SSL_set1_host` fails when host is an IP address --- .../http_client_async_ssl_system_executor.cpp | 9 +----- .../async-ssl/http_client_async_ssl.cpp | 9 +----- .../http_client_awaitable_ssl.cpp | 7 +---- .../client/coro-ssl/http_client_coro_ssl.cpp | 7 +---- .../client/sync-ssl/http_client_sync_ssl.cpp | 7 +---- ...ocket_client_async_ssl_system_executor.cpp | 27 +++++++++-------- .../async-ssl/websocket_client_async_ssl.cpp | 29 +++++++++---------- .../coro-ssl/websocket_client_coro_ssl.cpp | 6 +--- .../sync-ssl/websocket_client_sync_ssl.cpp | 7 +---- 9 files changed, 34 insertions(+), 74 deletions(-) diff --git a/example/http/client/async-ssl-system-executor/http_client_async_ssl_system_executor.cpp b/example/http/client/async-ssl-system-executor/http_client_async_ssl_system_executor.cpp index 85888f85..45e7a7d9 100644 --- a/example/http/client/async-ssl-system-executor/http_client_async_ssl_system_executor.cpp +++ b/example/http/client/async-ssl-system-executor/http_client_async_ssl_system_executor.cpp @@ -85,14 +85,7 @@ public: } // Set the expected hostname in the peer certificate for verification - if(! SSL_set1_host(stream_.native_handle(), host)) - { - beast::error_code ec{ - static_cast(::ERR_get_error()), - net::error::get_ssl_category()}; - std::cerr << ec.message() << "\n"; - return; - } + stream_.set_verify_callback(ssl::host_name_verification(host)); // Set up an HTTP GET request message req_.version(version); diff --git a/example/http/client/async-ssl/http_client_async_ssl.cpp b/example/http/client/async-ssl/http_client_async_ssl.cpp index 69d96ce4..58c8104b 100644 --- a/example/http/client/async-ssl/http_client_async_ssl.cpp +++ b/example/http/client/async-ssl/http_client_async_ssl.cpp @@ -77,14 +77,7 @@ public: } // Set the expected hostname in the peer certificate for verification - if(! SSL_set1_host(stream_.native_handle(), host)) - { - beast::error_code ec{ - static_cast(::ERR_get_error()), - net::error::get_ssl_category()}; - std::cerr << ec.message() << "\n"; - return; - } + stream_.set_verify_callback(ssl::host_name_verification(host)); // Set up an HTTP GET request message req_.version(version); diff --git a/example/http/client/awaitable-ssl/http_client_awaitable_ssl.cpp b/example/http/client/awaitable-ssl/http_client_awaitable_ssl.cpp index 739926c6..fc2fddb6 100644 --- a/example/http/client/awaitable-ssl/http_client_awaitable_ssl.cpp +++ b/example/http/client/awaitable-ssl/http_client_awaitable_ssl.cpp @@ -59,12 +59,7 @@ do_session( } // Set the expected hostname in the peer certificate for verification - if(! SSL_set1_host(stream.native_handle(), host.c_str())) - { - throw beast::system_error( - static_cast(::ERR_get_error()), - net::error::get_ssl_category()); - } + stream.set_verify_callback(ssl::host_name_verification(host)); // Look up the domain name auto const results = co_await resolver.async_resolve(host, port); diff --git a/example/http/client/coro-ssl/http_client_coro_ssl.cpp b/example/http/client/coro-ssl/http_client_coro_ssl.cpp index 08d2e46d..74f5c2a6 100644 --- a/example/http/client/coro-ssl/http_client_coro_ssl.cpp +++ b/example/http/client/coro-ssl/http_client_coro_ssl.cpp @@ -66,12 +66,7 @@ do_session( } // Set the expected hostname in the peer certificate for verification - if(! SSL_set1_host(stream.native_handle(), host.c_str())) - { - ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); - std::cerr << ec.message() << "\n"; - return; - } + stream.set_verify_callback(ssl::host_name_verification(host)); // Look up the domain name auto const results = resolver.async_resolve(host, port, yield[ec]); diff --git a/example/http/client/sync-ssl/http_client_sync_ssl.cpp b/example/http/client/sync-ssl/http_client_sync_ssl.cpp index e634c0fa..7cb768c7 100644 --- a/example/http/client/sync-ssl/http_client_sync_ssl.cpp +++ b/example/http/client/sync-ssl/http_client_sync_ssl.cpp @@ -75,12 +75,7 @@ int main(int argc, char** argv) } // Set the expected hostname in the peer certificate for verification - if(! SSL_set1_host(stream.native_handle(), host)) - { - throw beast::system_error( - static_cast(::ERR_get_error()), - net::error::get_ssl_category()); - } + stream.set_verify_callback(ssl::host_name_verification(host)); // Look up the domain name auto const results = resolver.resolve(host, port); diff --git a/example/websocket/client/async-ssl-system-executor/websocket_client_async_ssl_system_executor.cpp b/example/websocket/client/async-ssl-system-executor/websocket_client_async_ssl_system_executor.cpp index 3b93e8c1..627bb997 100644 --- a/example/websocket/client/async-ssl-system-executor/websocket_client_async_ssl_system_executor.cpp +++ b/example/websocket/client/async-ssl-system-executor/websocket_client_async_ssl_system_executor.cpp @@ -74,6 +74,19 @@ public: char const* port, char const* text) { + // Set SNI Hostname (many hosts need this to handshake successfully) + if(! SSL_set_tlsext_host_name(ws_.next_layer().native_handle(), host)) + { + beast::error_code ec{ + static_cast(::ERR_get_error()), + net::error::get_ssl_category()}; + std::cerr << ec.message() << "\n"; + return; + } + + // Set the expected hostname in the peer certificate for verification + ws_.next_layer().set_verify_callback(ssl::host_name_verification(host)); + // Save these for later host_ = host; text_ = text; @@ -115,20 +128,6 @@ public: // Set a timeout on the operation beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30)); - // Set SNI Hostname (many hosts need this to handshake successfully) - if(! SSL_set_tlsext_host_name(ws_.next_layer().native_handle(), host_.c_str())) - { - ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); - return fail(ec, "connect"); - } - - // Set the expected hostname in the peer certificate for verification - if(! SSL_set1_host(ws_.next_layer().native_handle(), host_.c_str())) - { - ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); - return fail(ec, "connect"); - } - // Update the host_ string. This will provide the value of the // Host HTTP header during the WebSocket handshake. // See https://tools.ietf.org/html/rfc7230#section-5.4 diff --git a/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp b/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp index 3dde0e50..22525c2b 100644 --- a/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp +++ b/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp @@ -66,6 +66,19 @@ public: char const* port, char const* text) { + // Set SNI Hostname (many hosts need this to handshake successfully) + if(! SSL_set_tlsext_host_name(ws_.next_layer().native_handle(), host)) + { + beast::error_code ec{ + static_cast(::ERR_get_error()), + net::error::get_ssl_category()}; + std::cerr << ec.message() << "\n"; + return; + } + + // Set the expected hostname in the peer certificate for verification + ws_.next_layer().set_verify_callback(ssl::host_name_verification(host)); + // Save these for later host_ = host; text_ = text; @@ -106,21 +119,7 @@ public: // Set a timeout on the operation beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30)); - - // Set SNI Hostname (many hosts need this to handshake successfully) - if(! SSL_set_tlsext_host_name(ws_.next_layer().native_handle(), host_.c_str())) - { - ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); - return fail(ec, "connect"); - } - - // Set the expected hostname in the peer certificate for verification - if(! SSL_set1_host(ws_.next_layer().native_handle(), host_.c_str())) - { - ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); - return fail(ec, "connect"); - } - + // Update the host_ string. This will provide the value of the // Host HTTP header during the WebSocket handshake. // See https://tools.ietf.org/html/rfc7230#section-5.4 diff --git a/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp b/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp index 19783a76..b2530927 100644 --- a/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp +++ b/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp @@ -78,11 +78,7 @@ do_session( } // Set the expected hostname in the peer certificate for verification - if(! SSL_set1_host(ws.next_layer().native_handle(), host.c_str())) - { - ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); - return fail(ec, "connect"); - } + ws.next_layer().set_verify_callback(ssl::host_name_verification(host)); // Update the host string. This will provide the value of the // Host HTTP header during the WebSocket handshake. diff --git a/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp b/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp index 30b88a39..ce8de674 100644 --- a/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp +++ b/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp @@ -81,12 +81,7 @@ int main(int argc, char** argv) } // Set the expected hostname in the peer certificate for verification - if(! SSL_set1_host(ws.next_layer().native_handle(), host.c_str())) - { - throw beast::system_error( - static_cast(::ERR_get_error()), - net::error::get_ssl_category()); - } + ws.next_layer().set_verify_callback(ssl::host_name_verification(host)); // Update the host_ string. This will provide the value of the // Host HTTP header during the WebSocket handshake.