Dear cgit maintainers,

I have cherry-picked a patch from upstream[1] which allows cgit to build
with both OpenSSL 3.x[2] and OpenSSL 4.0[3].

The FTBFS was caused by the vendored Git's imap-send.c using functions
removed in OpenSSL 4.0. The upstream patch rewrites those functions to use
a public API which has been available since OpenSSL 1.1.

I have attached the patch to this message. Please let me know if you need
anything else.

Best wishes,
Max

[1]:
https://github.com/git/git/commit/74137b733e59faaf3f3c6428af34c3798ce92757
[2]:
https://launchpad.net/~maxgmr/+archive/ubuntu/plusone/+sourcepub/18493847/+listing-archive-extra
[3]:
https://launchpad.net/~maxgmr/+archive/ubuntu/openssl4-transition/+sourcepub/18493848/+listing-archive-extra
Description: Make imap-send OpenSSL 4.0 compatible
 imap-send currently uses functions which will be removed with OpenSSL
 4.0. This patch rewrites those functions to use a public API which has
 been available since OpenSSL 1.1.
Author: Junio C Hamano <[email protected]>
Origin: upstream, https://github.com/git/git/commit/74137b733e59faaf3f3c6428af34c3798ce92757
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/cgit/+bug/2154842
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1137601
Forwarded: not-needed
Last-Update: 2026-06-25
---
--- a/git/imap-send.c
+++ b/git/imap-send.c
@@ -219,8 +219,14 @@
 
 #else
 
-static int host_matches(const char *host, const char *pattern)
+static int host_matches(const char *host, const ASN1_STRING *asn1_str)
 {
+	const char *pattern = (const char *)ASN1_STRING_get0_data(asn1_str);
+
+	/* embedded NUL characters may open a security hole */
+	if (memchr(pattern, '\0', ASN1_STRING_length(asn1_str)))
+	    return 0;
+
 	if (pattern[0] == '*' && pattern[1] == '.') {
 		pattern += 2;
 		if (!(host = strchr(host, '.')))
@@ -233,9 +239,13 @@
 
 static int verify_hostname(X509 *cert, const char *hostname)
 {
-	int len;
+#if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
+	const X509_NAME *subj;
+#else
 	X509_NAME *subj;
-	char cname[1000];
+#endif
+	const X509_NAME_ENTRY *cname_entry;
+	const ASN1_STRING *cname;
 	int i, found;
 	STACK_OF(GENERAL_NAME) *subj_alt_names;
 
@@ -244,10 +254,11 @@
 	if ((subj_alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL))) {
 		int num_subj_alt_names = sk_GENERAL_NAME_num(subj_alt_names);
 		for (i = 0; !found && i < num_subj_alt_names; i++) {
+			int ntype;
 			GENERAL_NAME *subj_alt_name = sk_GENERAL_NAME_value(subj_alt_names, i);
-			if (subj_alt_name->type == GEN_DNS &&
-			    strlen((const char *)subj_alt_name->d.ia5->data) == (size_t)subj_alt_name->d.ia5->length &&
-			    host_matches(hostname, (const char *)(subj_alt_name->d.ia5->data)))
+			ASN1_STRING *subj_alt_str = GENERAL_NAME_get0_value(subj_alt_name, &ntype);
+
+			if (ntype == GEN_DNS && host_matches(hostname, subj_alt_str))
 				found = 1;
 		}
 		sk_GENERAL_NAME_pop_free(subj_alt_names, GENERAL_NAME_free);
@@ -258,12 +269,14 @@
 	/* try the common name */
 	if (!(subj = X509_get_subject_name(cert)))
 		return error("cannot get certificate subject");
-	if ((len = X509_NAME_get_text_by_NID(subj, NID_commonName, cname, sizeof(cname))) < 0)
+	if ((i = X509_NAME_get_index_by_NID(subj, NID_commonName, -1)) < 0 ||
+	    (cname_entry = X509_NAME_get_entry(subj, i)) == NULL ||
+	    (cname = X509_NAME_ENTRY_get_data(cname_entry)) == NULL)
 		return error("cannot get certificate common name");
-	if (strlen(cname) == (size_t)len && host_matches(hostname, cname))
+	if (host_matches(hostname, cname))
 		return 0;
 	return error("certificate owner '%s' does not match hostname '%s'",
-		     cname, hostname);
+		     ASN1_STRING_get0_data(cname), hostname);
 }
 
 static int ssl_socket_connect(struct imap_socket *sock,

Reply via email to