From 3382efe5d68b04ad61fb37cf9047b7260c25d0e9 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 28 Jun 2016 20:25:46 +0800 Subject: [PATCH] client confirm server hostname in cert Openssl v1.0.2 and above have support for checking the hostname the client side connected to against the hostname on the cert the server presented. This enables that feature if the necessary API is available in the openssl version, meaning the connection will fail at ssl negotiation if the cert isn't for the requested server It's very easy to test, add a fake entry to /etc/hosts for the server IP with a different name, using that will fail at ssl but using the correct dns name matching the certificate will work. --- CMakeLists.txt | 1 + lib/private-libwebsockets.h | 1 + lib/ssl-client.c | 17 +++++++++++++++-- lws_config.h.in | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e1612f4f..061fe0a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -865,6 +865,7 @@ endforeach() set (temp ${CMAKE_REQUIRED_LIBRARIES}) set(CMAKE_REQUIRED_LIBRARIES ${LIB_LIST}) CHECK_FUNCTION_EXISTS(SSL_CTX_set1_param LWS_HAVE_SSL_CTX_set1_param) +CHECK_FUNCTION_EXISTS(X509_VERIFY_PARAM_set1_host LWS_HAVE_X509_VERIFY_PARAM_set1_host) set(CMAKE_REQUIRED_LIBRARIES ${temp}) # Generate the lws_config.h that includes all the public compilation settings. configure_file( diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index e05bda62..35e6e6d2 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -221,6 +221,7 @@ static inline int compatible_close(int fd) { return close(fd); } #ifdef LWS_HAVE_OPENSSL_ECDH_H #include #endif +#include #endif /* not USE_MBEDTLS */ #endif /* not USE_POLARSSL */ #endif /* not USE_WOLFSSL */ diff --git a/lib/ssl-client.c b/lib/ssl-client.c index df1c5e4a..62fc265c 100644 --- a/lib/ssl-client.c +++ b/lib/ssl-client.c @@ -38,11 +38,24 @@ lws_ssl_client_bio_create(struct lws *wsi) #if defined(LWS_USE_MBEDTLS) #else struct lws_context *context = wsi->context; -#if defined(CYASSL_SNI_HOST_NAME) || defined(WOLFSSL_SNI_HOST_NAME) || defined(SSL_CTRL_SET_TLSEXT_HOSTNAME) const char *hostname = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST); -#endif + X509_VERIFY_PARAM *param; + + (void)hostname; + (void)param; wsi->ssl = SSL_new(wsi->vhost->ssl_client_ctx); + +#if defined LWS_HAVE_X509_VERIFY_PARAM_set1_host + param = SSL_get0_param(wsi->ssl); + /* Enable automatic hostname checks */ + X509_VERIFY_PARAM_set_hostflags(param, + X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); + X509_VERIFY_PARAM_set1_host(param, hostname, 0); + /* Configure a non-zero callback if desired */ + SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, 0); +#endif + #ifndef USE_WOLFSSL SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); #endif diff --git a/lws_config.h.in b/lws_config.h.in index 87a0c6d2..1a353ee2 100644 --- a/lws_config.h.in +++ b/lws_config.h.in @@ -82,6 +82,7 @@ /* SSL server using ECDH certificate */ #cmakedefine LWS_SSL_SERVER_WITH_ECDH_CERT #cmakedefine LWS_HAVE_SSL_CTX_set1_param +#cmakedefine LWS_HAVE_X509_VERIFY_PARAM_set1_host /* CGI apis */ #cmakedefine LWS_WITH_CGI