From 948ce4f0f85a4e5734e997b22b26454cdfe4d336 Mon Sep 17 00:00:00 2001 From: megaposer Date: Mon, 21 Dec 2015 11:56:37 +0100 Subject: [PATCH 1/2] Add TLS extension SNI for boost asio based http_client - adds the TLS server name indication extension during handshake (ClientHello) - enabled by default as most virtual host environments require it nowadays - note: setting the extension could potentially fail (i.e. if TLS would be disabled on the stream altogether), but other SSL stream options are not "guarded" either --- CONTRIBUTORS.txt | 3 +++ Release/include/cpprest/http_client.h | 21 ++++++++++++++++++++ Release/src/http/client/http_client_asio.cpp | 9 +++++++++ 3 files changed, 33 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index e53f210625..230d1fb14e 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -35,4 +35,7 @@ Gery Vessere (gery@vessere.com) Cisco Systems Gergely Lukacsy (glukacsy) +Ocedo GmbH +Henning Pfeiffer (megaposer) + thomasschaub diff --git a/Release/include/cpprest/http_client.h b/Release/include/cpprest/http_client.h index 86e314feca..7823a6b1c1 100644 --- a/Release/include/cpprest/http_client.h +++ b/Release/include/cpprest/http_client.h @@ -101,6 +101,7 @@ class http_client_config , m_set_user_nativehandle_options([](native_handle)->void{}) #if !defined(_WIN32) && !defined(__cplusplus_winrt) , m_ssl_context_callback([](boost::asio::ssl::context&)->void{}) + , m_tlsext_host_name(true) #endif #if defined(_WIN32) && !defined(__cplusplus_winrt) , m_buffer_request(false) @@ -347,6 +348,25 @@ class http_client_config { return m_ssl_context_callback; } + + /// + /// Gets the TLS server name indication (SNI) property. + /// + /// True if TLS server name indication is enabled, false otherwise. + bool tlsext_host_name() const + { + return m_tlsext_host_name; + } + + /// + /// Sets the TLS server name indication (SNI) property. + /// + /// False to disable the TLS (ClientHello) extension for server name indication, true otherwise. + /// Note: This setting is required in most virtual hosting scenarios. + void set_tlsext_host_name(bool tlsext_host_name) + { + m_tlsext_host_name = tlsext_host_name; + } #endif private: @@ -372,6 +392,7 @@ class http_client_config #if !defined(_WIN32) && !defined(__cplusplus_winrt) std::function m_ssl_context_callback; + bool m_tlsext_host_name; #endif #if defined(_WIN32) && !defined(__cplusplus_winrt) bool m_buffer_request; diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index bff2ff4843..ed4a448d3a 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -136,6 +136,7 @@ class asio_connection template void async_handshake(boost::asio::ssl::stream_base::handshake_type type, const http_client_config &config, + const utility::string_t &host_name, const HandshakeHandler &handshake_handler, const CertificateHandler &cert_handler) { @@ -152,6 +153,13 @@ class asio_connection { m_ssl_stream->set_verify_mode(boost::asio::ssl::context::verify_none); } + + // Check to set host name for Server Name Indication (SNI) + if (config.tlsext_host_name()) + { + SSL_set_tlsext_host_name(m_ssl_stream->native_handle(), const_cast(host_name.data())); + } + m_ssl_stream->async_handshake(type, handshake_handler); } @@ -561,6 +569,7 @@ class asio_context : public request_context, public std::enable_shared_from_this const auto weakCtx = std::weak_ptr(shared_from_this()); m_connection->async_handshake(boost::asio::ssl::stream_base::client, m_http_client->client_config(), + m_http_client->base_uri().host(), boost::bind(&asio_context::handle_handshake, shared_from_this(), boost::asio::placeholders::error), // Use a weak_ptr since the verify_callback is stored until the connection is destroyed. From 57c2e9e10d239648e8dfbfa52b55cdad6054102c Mon Sep 17 00:00:00 2001 From: megaposer Date: Mon, 4 Jan 2016 08:49:08 +0100 Subject: [PATCH 2/2] Rename methods and variable names / incorrporate feedback from #39 review --- Release/include/cpprest/http_client.h | 20 ++++++++++---------- Release/src/http/client/http_client_asio.cpp | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Release/include/cpprest/http_client.h b/Release/include/cpprest/http_client.h index 7823a6b1c1..1e0ce8b73f 100644 --- a/Release/include/cpprest/http_client.h +++ b/Release/include/cpprest/http_client.h @@ -101,7 +101,7 @@ class http_client_config , m_set_user_nativehandle_options([](native_handle)->void{}) #if !defined(_WIN32) && !defined(__cplusplus_winrt) , m_ssl_context_callback([](boost::asio::ssl::context&)->void{}) - , m_tlsext_host_name(true) + , m_tlsext_sni_enabled(true) #endif #if defined(_WIN32) && !defined(__cplusplus_winrt) , m_buffer_request(false) @@ -350,22 +350,22 @@ class http_client_config } /// - /// Gets the TLS server name indication (SNI) property. + /// Gets the TLS extension server name indication (SNI) status. /// /// True if TLS server name indication is enabled, false otherwise. - bool tlsext_host_name() const + bool is_tlsext_sni_enabled() const { - return m_tlsext_host_name; + return m_tlsext_sni_enabled; } /// - /// Sets the TLS server name indication (SNI) property. + /// Sets the TLS extension server name indication (SNI) status. /// - /// False to disable the TLS (ClientHello) extension for server name indication, true otherwise. - /// Note: This setting is required in most virtual hosting scenarios. - void set_tlsext_host_name(bool tlsext_host_name) + /// False to disable the TLS (ClientHello) extension for server name indication, true otherwise. + /// Note: This setting is enabled by default as it is required in most virtual hosting scenarios. + void set_tlsext_sni_enabled(bool tlsext_sni_enabled) { - m_tlsext_host_name = tlsext_host_name; + m_tlsext_sni_enabled = tlsext_sni_enabled; } #endif @@ -392,7 +392,7 @@ class http_client_config #if !defined(_WIN32) && !defined(__cplusplus_winrt) std::function m_ssl_context_callback; - bool m_tlsext_host_name; + bool m_tlsext_sni_enabled; #endif #if defined(_WIN32) && !defined(__cplusplus_winrt) bool m_buffer_request; diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index ed4a448d3a..9a4b5314f0 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -155,7 +155,7 @@ class asio_connection } // Check to set host name for Server Name Indication (SNI) - if (config.tlsext_host_name()) + if (config.is_tlsext_sni_enabled()) { SSL_set_tlsext_host_name(m_ssl_stream->native_handle(), const_cast(host_name.data())); }