aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/epee/include/net/net_helper.h2
-rw-r--r--contrib/epee/include/net/net_ssl.h14
-rw-r--r--contrib/epee/src/net_ssl.cpp15
3 files changed, 26 insertions, 5 deletions
diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h
index a9bfd6baa..66a307c97 100644
--- a/contrib/epee/include/net/net_helper.h
+++ b/contrib/epee/include/net/net_helper.h
@@ -174,7 +174,7 @@ namespace net_utils
// SSL Options
if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
{
- if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client))
+ if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, addr))
{
if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
{
diff --git a/contrib/epee/include/net/net_ssl.h b/contrib/epee/include/net/net_ssl.h
index f36755013..ba6e2ee6d 100644
--- a/contrib/epee/include/net/net_ssl.h
+++ b/contrib/epee/include/net/net_ssl.h
@@ -108,9 +108,21 @@ namespace net_utils
then the handshake will not fail when peer verification fails. The
assumption is that a re-connect will be attempted, so a warning is
logged instead of failure.
+
+ \note It is strongly encouraged that clients using `system_ca`
+ verification provide a non-empty `host` for rfc2818 verification.
+
+ \param socket Used in SSL handshake and verification
+ \param type Client or server
+ \param host This parameter is only used when
+ `type == client && !host.empty()`. The value is sent to the server for
+ situations where multiple hostnames are being handled by a server. If
+ `verification == system_ca` the client also does a rfc2818 check to
+ ensure that the server certificate is to the provided hostname.
+
\return True if the SSL handshake completes with peer verification
settings. */
- bool handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket, boost::asio::ssl::stream_base::handshake_type type) const;
+ bool handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket, boost::asio::ssl::stream_base::handshake_type type, const std::string& host = {}) const;
};
// https://security.stackexchange.com/questions/34780/checking-client-hello-for-https-classification
diff --git a/contrib/epee/src/net_ssl.cpp b/contrib/epee/src/net_ssl.cpp
index cf8fa68ee..fbc809043 100644
--- a/contrib/epee/src/net_ssl.cpp
+++ b/contrib/epee/src/net_ssl.cpp
@@ -311,7 +311,7 @@ bool ssl_options_t::has_fingerprint(boost::asio::ssl::verify_context &ctx) const
return false;
}
-bool ssl_options_t::handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket, boost::asio::ssl::stream_base::handshake_type type) const
+bool ssl_options_t::handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket, boost::asio::ssl::stream_base::handshake_type type, const std::string& host) const
{
socket.next_layer().set_option(boost::asio::ip::tcp::no_delay(true));
@@ -330,11 +330,20 @@ bool ssl_options_t::handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::soc
else
{
socket.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);
- socket.set_verify_callback([&](bool preverified, boost::asio::ssl::verify_context &ctx)
+
+ // in case server is doing "virtual" domains, set hostname
+ SSL* const ssl_ctx = socket.native_handle();
+ if (type == boost::asio::ssl::stream_base::client && !host.empty() && ssl_ctx)
+ SSL_set_tlsext_host_name(ssl_ctx, host.c_str());
+
+ socket.set_verify_callback([&](const bool preverified, boost::asio::ssl::verify_context &ctx)
{
// preverified means it passed system or user CA check. System CA is never loaded
// when fingerprints are whitelisted.
- if (!preverified && !has_fingerprint(ctx))
+ const bool verified = preverified &&
+ (verification != ssl_verification_t::system_ca || host.empty() || boost::asio::ssl::rfc2818_verification(host)(preverified, ctx));
+
+ if (!verified && !has_fingerprint(ctx))
{
// autodetect will reconnect without SSL - warn and keep connection encrypted
if (support != ssl_support_t::e_ssl_support_autodetect)