This is an automated email from the ASF dual-hosted git repository.

chibenwa pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-jdkim.git

commit f23ca707c8d4abd45bb139c6871d76dc30a3fc15
Author: Benoit TELLIER <[email protected]>
AuthorDate: Fri Oct 30 08:37:24 2026 +0100

    [FIX] TagValue: decode b= and bh= as strict base64 once FWS is removed
    
    The MIME decoder silently skips characters outside the base64 alphabet
    and data after the padding, so junk could be inserted into b= of a
    valid signature. The b64PadFixPattern workaround only repaired one
    folding shape of the padding.
    
    b= and bh= now use the same decoder as p=: FWS is removed anywhere,
    then the value is decoded with the strict decoder.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../org/apache/james/jdkim/tagvalue/TagValue.java  |  7 +-----
 .../james/jdkim/SignatureRecordImplTest.java       | 25 ++++++++++++++++++++++
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/main/src/main/java/org/apache/james/jdkim/tagvalue/TagValue.java 
b/main/src/main/java/org/apache/james/jdkim/tagvalue/TagValue.java
index 400a06b..cf48ae4 100644
--- a/main/src/main/java/org/apache/james/jdkim/tagvalue/TagValue.java
+++ b/main/src/main/java/org/apache/james/jdkim/tagvalue/TagValue.java
@@ -45,7 +45,6 @@ public class TagValue {
     // Use possessive matching to avoid heavy stack usage
     private static final Pattern valuePattern = Pattern.compile("^(?:" + tval
             + "(?:(?:(?:\r\n)?[\t ])++" + tval + ")*+)?$");
-    private static final Pattern b64PadFixPattern = 
Pattern.compile("=(\r?\n\\s*)=$");
     private static final Pattern fwsPattern = Pattern.compile("[ \t\r\n]");
 
     // we may use a TreeMap because we may need to know original order.
@@ -224,11 +223,7 @@ public class TagValue {
     }
 
     protected byte[] decodeBase64TagValue(String key) {
-        // When a base64 string ends with a newline between two '=', 
java.util.Base64 fails.
-        String value = getValue(key).toString();
-        return Base64.getMimeDecoder().decode(
-                b64PadFixPattern.matcher(value).replaceAll("$1==")
-        );
+        return decodeBase64(getValue(key));
     }
 
     /**
diff --git 
a/main/src/test/java/org/apache/james/jdkim/SignatureRecordImplTest.java 
b/main/src/test/java/org/apache/james/jdkim/SignatureRecordImplTest.java
index a67cb1c..e75eb46 100644
--- a/main/src/test/java/org/apache/james/jdkim/SignatureRecordImplTest.java
+++ b/main/src/test/java/org/apache/james/jdkim/SignatureRecordImplTest.java
@@ -254,4 +254,29 @@ public class SignatureRecordImplTest {
             Locale.setDefault(saved);
         }
     }
+
+    @Test
+    public void 
signatureWithCharactersOutsideTheBase64AlphabetShouldNotDecode() {
+        SignatureRecordImpl record = new SignatureRecordImpl(
+                "v=1; a=rsa-sha256; d=example.com; s=s; h=from; bh=AA==; 
b=AAÿAA");
+
+        
assertThatThrownBy(record::getSignature).isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void bodyHashWithDataAfterThePaddingShouldNotDecode() {
+        SignatureRecordImpl record = new SignatureRecordImpl(
+                "v=1; a=rsa-sha256; d=example.com; s=s; h=from; bh= AA== === ; 
b=AA==");
+
+        
assertThatThrownBy(record::getBodyHash).isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void base64FoldedBetweenThePaddingCharactersShouldDecode() {
+        SignatureRecordImpl record = new SignatureRecordImpl(
+                "v=1; a=rsa-sha256; d=example.com; s=s; h=from; 
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU\r\n =; b=AA= =");
+
+        assertThat(record.getBodyHash()).hasSize(32);
+        assertThat(record.getSignature()).containsExactly(0);
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to