... 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