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 3e357ce8b65d545852d22625ceb8243ff4987f79 Author: Benoit TELLIER <[email protected]> AuthorDate: Fri Oct 30 08:34:57 2026 +0100 [FIX] DKIMVerifier: report an undecodable bh= as a PermFail bh= was first decoded in verify(CompoundBodyHasher), outside any per-signature guard: a value the base64 decoder rejects made the whole verify() call throw IllegalArgumentException and lost the results of the other signatures. It is now decoded with b=, where a decoding error is recorded as an invalid signature record. Co-Authored-By: Claude Opus 5.5 <[email protected]> --- .../java/org/apache/james/jdkim/DKIMVerifier.java | 2 ++ .../org/apache/james/jdkim/DKIMVerifierTest.java | 23 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/main/src/main/java/org/apache/james/jdkim/DKIMVerifier.java b/main/src/main/java/org/apache/james/jdkim/DKIMVerifier.java index 441f998..086ccd1 100644 --- a/main/src/main/java/org/apache/james/jdkim/DKIMVerifier.java +++ b/main/src/main/java/org/apache/james/jdkim/DKIMVerifier.java @@ -312,6 +312,8 @@ public class DKIMVerifier { List<CharSequence> signedHeadersList = signatureRecord.getHeaders(); try { + // decoded now so that verify(CompoundBodyHasher) cannot fail on it + signatureRecord.getBodyHash(); byte[] decoded = signatureRecord.getSignature(); signatureVerify(messageHeaders, signatureRecord, decoded, publicKeyRecord, signedHeadersList); diff --git a/main/src/test/java/org/apache/james/jdkim/DKIMVerifierTest.java b/main/src/test/java/org/apache/james/jdkim/DKIMVerifierTest.java index e385ffc..9667926 100644 --- a/main/src/test/java/org/apache/james/jdkim/DKIMVerifierTest.java +++ b/main/src/test/java/org/apache/james/jdkim/DKIMVerifierTest.java @@ -19,6 +19,9 @@ package org.apache.james.jdkim; +import org.apache.james.jdkim.impl.Message; +import java.util.Base64; +import java.security.Signature; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -149,4 +152,24 @@ public class DKIMVerifierTest { assertThat(verifier.getResults().stream().filter(r -> r.getResultType() == Result.Type.PERMERROR)).hasSize(190); } + @Test + public void verifyShouldFailWithPermFailOnUndecodableBodyHash() throws Exception { + String tags = " b=; v=1; a=rsa-sha256; d=example.com; s=sel; h=from; bh=ab=c"; + String headers = "From: [email protected]\r\n"; + SignatureRecordImpl record = new SignatureRecordImpl(tags); + Signature signer = Signature.getInstance("SHA256withRSA"); + signer.initSign(TestKeys.privateKey); + DKIMCommon.signatureCheck(new Message(new ByteArrayInputStream((headers + "\r\n").getBytes(StandardCharsets.US_ASCII))), + record, record.getHeaders(), signer); + String b = Base64.getEncoder().encodeToString(signer.sign()); + String mail = "DKIM-Signature:" + tags.replace("b=;", "b=" + b + ";") + "\r\n" + headers + "\r\nbody\r\n"; + + DKIMVerifier verifier = new DKIMVerifier(new MockPublicKeyRecordRetriever( + "v=DKIM1; k=rsa; p=" + Base64.getEncoder().encodeToString(TestKeys.publicKey.getEncoded()), "sel", "example.com")); + + assertThatThrownBy(() -> verifier.verify(new ByteArrayInputStream(mail.getBytes(StandardCharsets.US_ASCII)))) + .isInstanceOf(PermFailException.class); + assertThat(verifier.hasAnyValidSignature()).isFalse(); + assertThat(verifier.getResults()).hasSize(1); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
