... if built against a new enough version of OpenSSL

Suggested-by: Christian Heimes
---
 configure.in             |  3 +++
 src/network/ssl/socket.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/configure.in b/configure.in
index 58548fe..324fb2a 100644
--- a/configure.in
+++ b/configure.in
@@ -1134,6 +1134,9 @@ else
 fi
 
 AC_MSG_RESULT($cf_result)
+if test "$cf_result" = yes; then
+       AC_CHECK_FUNCS(X509_VERIFY_PARAM_set1_host)
+fi
 
 # ---- GNU TLS
 
diff --git a/src/network/ssl/socket.c b/src/network/ssl/socket.c
index 6af5e0d..9a2109b 100644
--- a/src/network/ssl/socket.c
+++ b/src/network/ssl/socket.c
@@ -7,6 +7,9 @@
 #ifdef CONFIG_OPENSSL
 #include <openssl/ssl.h>
 #include <openssl/x509v3.h>
+#ifdef HAVE_X509_VERIFY_PARAM_SET1_HOST
+#include <openssl/x509_vfy.h>
+#endif
 #define USE_OPENSSL
 #elif defined(CONFIG_NSS_COMPAT_OSSL)
 #include <nss_compat_ossl/nss_compat_ossl.h>
@@ -168,6 +171,30 @@ verify_certificates(struct socket *socket)
 
 #ifdef USE_OPENSSL
 
+#ifdef HAVE_X509_VERIFY_PARAM_SET1_HOST
+/* activate the OpenSSL-provided host name check */
+static int
+ossl_set_hostname(void *ssl, unsigned char *server_name)
+{
+       int ret = -1;
+
+       X509_VERIFY_PARAM *vpm = X509_VERIFY_PARAM_new();
+       if (vpm) {
+               if (X509_VERIFY_PARAM_set1_host(vpm, (char *) server_name, 0)
+                               && SSL_set1_param(ssl, vpm))
+               {
+                       /* successfully activated the OpenSSL host name check */
+                       ret = 0;
+               }
+
+               X509_VERIFY_PARAM_free(vpm);
+       }
+
+       return ret;
+}
+
+#else /* HAVE_X509_VERIFY_PARAM_SET1_HOST */
+
 /** Checks whether the host component of a URI matches a host name in
  * the server certificate.
  *
@@ -360,6 +387,7 @@ verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
        mem_free(host_in_uri);
        return matched;
 }
+#endif /* HAVE_X509_VERIFY_PARAM_SET1_HOST */
 
 #endif /* USE_OPENSSL */
 
@@ -400,6 +428,9 @@ ssl_connect(struct socket *socket)
        int ret;
        unsigned char *server_name;
        struct connection *conn = socket->conn;
+#ifdef USE_OPENSSL
+       int (*verify_callback_ptr)(int, X509_STORE_CTX *);
+#endif /* USE_OPENSSL */
 
        /* TODO: Recode server_name to UTF-8.  */
        server_name = get_uri_string(conn->proxied_uri, URI_HOST);
@@ -418,6 +449,23 @@ ssl_connect(struct socket *socket)
                return -1;
        }
 
+#ifdef USE_OPENSSL
+#ifdef HAVE_X509_VERIFY_PARAM_SET1_HOST
+       /* activate the OpenSSL-provided host name check */
+       if (ossl_set_hostname(socket->ssl, server_name)) {
+               mem_free_if(server_name);
+               socket->ops->done(socket, connection_state(S_SSL_ERROR));
+               return -1;
+       }
+
+       /* verify_callback() is not needed with X509_VERIFY_PARAM_set1_host() */
+       verify_callback_ptr = NULL;
+#else
+       /* use our own callback implementing the host name check */
+       verify_callback_ptr = verify_callback;
+#endif
+#endif /* USE_OPENSSL */
+
        mem_free_if(server_name);
 
        if (socket->no_tls)
@@ -429,7 +477,7 @@ ssl_connect(struct socket *socket)
        if (get_opt_bool("connection.ssl.cert_verify", NULL))
                SSL_set_verify(socket->ssl, SSL_VERIFY_PEER
                                          | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
-                              verify_callback);
+                              verify_callback_ptr);
 
        if (get_opt_bool("connection.ssl.client_cert.enable", NULL)) {
                unsigned char *client_cert;
-- 
2.4.3

-- 
http://lists.linuxfromscratch.org/listinfo/elinks-dev
Unsubscribe: See the above information page

Reply via email to