shithub: riscv

Download patch

ref: 3f2a206151367ccf516f931aa2413d72e1c9951f
parent: a9e533ad1ecc5b15c6f6ab4dcc1aa79fe8e5f98a
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Oct 30 21:49:25 EDT 2021

libsec: decode international domain names in certificat subject, fix overflow botch

this is for consistency, so all certificte subjects
will be returned in utf8.

--- a/sys/src/libsec/port/x509.c
+++ b/sys/src/libsec/port/x509.c
@@ -2247,17 +2247,36 @@
 static void
 copysubject(char *name, int nname, char *subject)
 {
-	char *e;
+	char *e, *at;
+	int i;
 
-	if(name == nil)
+	if(name == nil || nname < 1)
 		return;
 	memset(name, 0, nname);
 	if(subject == nil)
 		return;
-	strncpy(name, subject, nname-1);
-	e = strchr(name, ',');
-	if(e != nil)
+
+	if((e = strchr(subject, ',')) != nil)
 		*e = 0;	/* take just CN part of Distinguished Name */
+
+	i = 0;
+	if((at = strchr(subject, '@')) != nil){
+		i = ++at - subject;
+		if(i >= nname){
+			i = 0;
+			goto botch;
+		}
+		strncpy(name, subject, i);
+	}
+	if(strncmp(subject+i, "xn--", 4) != 0
+	|| idn2utf(subject+i, name+i, nname-i) < 0){
+botch:
+		strncpy(name+i, subject+i, nname-i);
+	}
+	name[nname-1] = 0;
+
+	if(e != nil)
+		*e = ',';
 }
 
 ECpub*
@@ -2615,11 +2634,13 @@
 	i = 0;
 	if((at = strchr(s, '@')) != nil){
 		i = ++at - s;
+		if(i >= sizeof(buf))
+			goto botch;
 		strncpy(buf, s, i);
 	}
 	if(utf2idn(s+i, buf+i, sizeof(buf)-i) >= 0)
 		s = buf;
-
+botch:
 	e = mkstring(s, IA5String);
 	e.tag.class = Context;
 	e.tag.num = at != nil ? 1 : 2; /* email : DNS */
@@ -2716,7 +2737,7 @@
 	char *alt, *e, buf[256];
 	int len;
 
-	if(name == nil || ext == nil)
+	if(name == nil || nname < 1 || ext == nil)
 		return;
 	if(decode(ext->data, ext->len, &eext) != ASN_OK)
 		return;
@@ -2786,6 +2807,8 @@
 		len = 0;
 		if((e = strchr(alt, '@')) != nil){
 			len = ++e - alt;
+			if(len >= sizeof(buf))
+				goto botch;
 			strncpy(buf, alt, len);
 		}
 		if(idn2utf(alt+len, buf+len, sizeof(buf)-len) >= 0){
@@ -2792,13 +2815,13 @@
 			free(alt);
 			alt = estrdup(buf);
 		}
-	
+
 		len = strlen(alt);
 		if(strncmp(name, alt, len) == 0 && strchr(",", name[len]) != nil){
 			free(alt);	/* same as the subject (utf) */
 			continue;
 		}
-
+botch:
 		if(name[0] != '\0')
 			strncat(name, ", ", nname-1);
 		strncat(name, alt, nname-1);