summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--fetch.c4
-rw-r--r--tls_compat.c27
-rw-r--r--tls_compat.h1
3 files changed, 32 insertions, 0 deletions
diff --git a/fetch.c b/fetch.c
index 5c3006c..a3aaec9 100644
--- a/fetch.c
+++ b/fetch.c
@@ -668,6 +668,10 @@ noslash:
 			fprintf(ttyout, "TLS handshake failure: %s\n", tls_error(tls));
 			goto cleanup_url_get;
 		}
+		if (tls_verify_hostname(tls, sslhost) != 0) {
+			fprintf(ttyout, "TLS hostname verification failed\n");
+			goto cleanup_url_get;
+		}
 		fin = funopen(tls, stdio_tls_read_wrapper,
 		    stdio_tls_write_wrapper, NULL, NULL);
 	} else {
diff --git a/tls_compat.c b/tls_compat.c
index 94b2528..3a0242d 100644
--- a/tls_compat.c
+++ b/tls_compat.c
@@ -44,6 +44,7 @@ tls_config_new(void)
 
 	SSL_CTX_set_options(ctx, SSL_OP_LEGACY_SERVER_CONNECT);
 	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
+	SSL_CTX_set_default_verify_paths(ctx);
 
 	return config;
 }
@@ -224,6 +225,32 @@ tls_handshake(tls_t ctx)
 }
 
 int
+tls_verify_hostname(tls_t ctx, const char *hostname)
+{
+	X509 *cert;
+	long verify_result;
+
+	if (global_tls_config == NULL || global_tls_config->noverifyname)
+		return 0;
+
+	verify_result = SSL_get_verify_result(ctx->ssl);
+	if (verify_result != X509_V_OK)
+		return -1;
+
+	cert = SSL_get_peer_certificate(ctx->ssl);
+	if (cert == NULL)
+		return -1;
+
+	if (X509_check_host(cert, hostname, 0, 0, NULL) != 1) {
+		X509_free(cert);
+		return -1;
+	}
+
+	X509_free(cert);
+	return 0;
+}
+
+int
 tls_read(tls_t ctx, void *buf, size_t buflen)
 {
 	return SSL_read(ctx->ssl, buf, buflen);
diff --git a/tls_compat.h b/tls_compat.h
index 3283fa4..2086a29 100644
--- a/tls_compat.h
+++ b/tls_compat.h
@@ -48,6 +48,7 @@ tls_t tls_client(void);
 int tls_configure(tls_t ctx, tls_config_t config);
 int tls_connect_socket(tls_t ctx, int s, const char *servername);
 int tls_handshake(tls_t ctx);
+int tls_verify_hostname(tls_t ctx, const char *hostname);
 int tls_read(tls_t ctx, void *buf, size_t buflen);
 int tls_write(tls_t ctx, const void *buf, size_t buflen);
 int tls_close(tls_t ctx);