client confirm server hostname in cert
authorAndy Green <andy@warmcat.com>
Tue, 28 Jun 2016 12:25:46 +0000 (20:25 +0800)
committerAndy Green <andy@warmcat.com>
Tue, 28 Jun 2016 12:25:46 +0000 (20:25 +0800)
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
lib/private-libwebsockets.h
lib/ssl-client.c
lws_config.h.in

index e1612f4f22f465d3d6f1f11f960b2a6173266203..061fe0a8b23f22d4b6ab957bd39c4633beb54ab7 100644 (file)
@@ -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(
index e05bda627a607ce9d4125cbb8afd36ba67b46e33..35e6e6d2072c7e84c651fc10d63447a72747a55b 100644 (file)
@@ -221,6 +221,7 @@ static inline int compatible_close(int fd) { return close(fd); }
 #ifdef LWS_HAVE_OPENSSL_ECDH_H
 #include <openssl/ecdh.h>
 #endif
+#include <openssl/x509v3.h>
 #endif /* not USE_MBEDTLS */
 #endif /* not USE_POLARSSL */
 #endif /* not USE_WOLFSSL */
index df1c5e4ad665692243d4fb036adf8b547af6a1f7..62fc265c372513c16430a77291e59c3fc316cfe2 100644 (file)
@@ -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
index 87a0c6d2af352cfc39e8834e78a692696c01a9e2..1a353ee232724bc1d4dc77998152edc0bf08d8f3 100644 (file)
@@ -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