Commit Diff


commit - 7e24437dc38dbdda776651fb1eda070fcae975d5
commit + 2b1224a85b6c0d5198786699a6e7c374a95fb8bd
blob - e931352fd7515a537ffd661a4137c9cede6b5003
blob + 634ee9df0363ae3b1d1b1808e7675eafaa27aec1
--- main.c
+++ main.c
@@ -1169,7 +1169,7 @@ dkim_key_text_parse(struct signature *sig, const char 
 	const char *end, *tagvend;
 	char pkraw[UINT16_MAX] = "", pkimp[UINT16_MAX];
 	size_t pkoff, linelen;
-	int h = 0, k = 0, n = 0, p = 0, s = 0, t = 0;
+	int h = 0, k = 0, n = 0, p = 0, s = 0, t = 0, first = 1;
 	BIO *bio;
 
 	key = osmtpd_ltok_skip_fws(key, 1);
@@ -1177,24 +1177,6 @@ dkim_key_text_parse(struct signature *sig, const char 
 	if ((end = osmtpd_ltok_skip_tag_list(key, 0)) == NULL)
 		return 0;
 
-	/*
-	 * RFC 6376 section 3.6.1, v=:
-	 * RECOMMENDED...This tag MUST be the first tag in the record.
-	 */
-	if (osmtpd_ltok_skip_tag_name(key, 0) - key == 1 &&
-	    key[0] == 'v') {
-		key = osmtpd_ltok_skip_tag_name(key, 0);
-		key = osmtpd_ltok_skip_fws(key, 1);
-		key++;	/* = */
-		key = osmtpd_ltok_skip_fws(key, 1);
-		end = osmtpd_ltok_skip_tag_value(key, 0);
-		if (end - key != 5 || strncmp(key, "DKIM1", 5) != 0)
-			return 0;
-		key += 5;
-		key = osmtpd_ltok_skip_fws(key, 1);
-		if (key[0] == ';')
-			key++;
-	}
 	while (key[0] != '\0') {
 		key = osmtpd_ltok_skip_fws(key, 1);
 		if ((end = osmtpd_ltok_skip_tag_name(key, 0)) == NULL)
@@ -1213,8 +1195,15 @@ dkim_key_text_parse(struct signature *sig, const char 
 			return 0;
 		switch (tagname) {
 		case 'v':
-			/* tagname in wrong position */
-			return 0;
+			/*
+			 * RFC 6376 section 3.6.1, v=:
+			 * RECOMMENDED...This tag MUST be the first tag in the
+			 * record.
+			 */
+			if (!first ||
+			    osmtpd_ltok_skip_key_v_tag_value(key, 0) != end)
+				return 0;
+			break;
 		case 'h':
 			if (h != 0)	/* Duplicate tag */
 				return 0;
@@ -1327,6 +1316,7 @@ dkim_key_text_parse(struct signature *sig, const char 
 			break;
 		}
 
+		first = 0;
 		key = osmtpd_ltok_skip_fws(key, 1);
 		if (key[0] == ';')
 			key++;