Commit Diff


commit - 801e13dfab0e60304cf2cd5935da0ea1e2e4811f
commit + b8704f50a377e7e7131d069d52264ca531f9cef4
blob - 24fa6b361beeed3ee51ed7efb55514422a3d965c
blob + 3df8bf8d867635836e5bdd796a9ede1b468400c5
--- main.c
+++ main.c
@@ -67,6 +67,9 @@ struct signature {
 	char *b;
 	size_t bsz;
 	const char *bheader;
+	size_t bheadersz;
+#define HEADER_B_MAX_LEN        8
+	char bheaderclean[HEADER_B_MAX_LEN + 1];
 	/* Make sure padding bits for base64 decoding fit */
 	char bh[EVP_MAX_MD_SIZE + (3 - (EVP_MAX_MD_SIZE % 3))];
 	size_t bhsz;
@@ -591,20 +594,20 @@ void
 dkim_signature_parse_b(struct signature *sig, const char *start, const char *end)
 {
 	int decodesz;
+	size_t i, j;
 
 	if (sig->b != NULL) {
 		dkim_signature_state(sig, DKIM_PERMERROR, "Duplicate b tag");
 		return;
 	}
 	sig->bheader = start;
-	if ((sig->b = malloc((((end - start) / 4) + 1) * 3)) == NULL) {
-		dkim_err(sig->header->msg, "malloc");
-		return;
-	}
+	sig->bheadersz = end - start;
+	if ((sig->b = malloc(((sig->bheadersz / 4) + 1) * 3)) == NULL)
+		osmtpd_err(1, "malloc");
 	/* EVP_DecodeBlock doesn't handle internal whitespace */
 	EVP_DecodeInit(ectx);
-	if (EVP_DecodeUpdate(ectx, sig->b, &decodesz, start,
-	    (int)(end - start)) == -1) {
+	if (EVP_DecodeUpdate(ectx, sig->b, &decodesz, sig->bheader,
+	    (int) sig->bheadersz) == -1) {
 		dkim_signature_state(sig, DKIM_PERMERROR, "Invalid b tag");
 		return;
 	}
@@ -615,6 +618,13 @@ dkim_signature_parse_b(struct signature *sig, const ch
 		return;
 	}
 	sig->bsz += decodesz;
+	for (i = 0, j = 0;
+	     i < sig->bheadersz && j < HEADER_B_MAX_LEN; i++) {
+		if (isalnum(sig->bheader[i]) || sig->bheader[i] == '/'
+		    || sig->bheader[i] == '+' || sig->bheader[i] == '=')
+			sig->bheaderclean[j++] = sig->bheader[i];
+	}
+	sig->bheaderclean[j] = '\0';
 }
 
 void
@@ -1638,6 +1648,13 @@ dkim_message_verify(struct message *msg)
 				goto fail;
 			}
 		}
+		if (sig->bheaderclean[0] != '\0') {
+			if ((aroff = dkim_ar_cat(&line, &linelen, aroff,
+			    " header.b=%s", sig->bheaderclean)) == -1) {
+				dkim_err(msg, "malloc");
+				goto fail;
+			}
+		}
 	}
 	if (!found) {
 		aroff = dkim_ar_cat(&line, &linelen, aroff, "; dkim=none");