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 bbab5245fd67a9750429516fd7c5933a76bc1be7 Author: Benoit TELLIER <[email protected]> AuthorDate: Fri Oct 30 08:37:58 2026 +0100 [FIX] PublicKeyRecordImpl: only build RSA public keys getPublicKey() asked KeyFactory for whatever algorithm k= named and cast the result to RSAPublicKey, so a record with k=EC, XDH, Ed25519 or DSA threw ClassCastException. k= other than rsa is now rejected with IllegalStateException and the RSA KeyFactory is always used. Co-Authored-By: Claude Opus 5.5 <[email protected]> --- .../apache/james/jdkim/tagvalue/PublicKeyRecordImpl.java | 13 ++++++++----- .../java/org/apache/james/jdkim/PublicKeyRecordTest.java | 12 ++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/main/src/main/java/org/apache/james/jdkim/tagvalue/PublicKeyRecordImpl.java b/main/src/main/java/org/apache/james/jdkim/tagvalue/PublicKeyRecordImpl.java index 8366fbc..c5cb7b8 100644 --- a/main/src/main/java/org/apache/james/jdkim/tagvalue/PublicKeyRecordImpl.java +++ b/main/src/main/java/org/apache/james/jdkim/tagvalue/PublicKeyRecordImpl.java @@ -176,13 +176,16 @@ public class PublicKeyRecordImpl extends TagValue implements PublicKeyRecord { */ public PublicKey getPublicKey() { try { + // only rsa-* signatures are implemented: never let DNS data pick the KeyFactory + if (!"rsa".equalsIgnoreCase(getValue("k").toString())) + throw new IllegalStateException("Unsupported key type: " + getValue("k")); byte[] key = decodeBase64(getValue("p")); - KeyFactory keyFactory; - keyFactory = KeyFactory.getInstance(getValue("k").toString()); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(key); - RSAPublicKey rsaKey; - rsaKey = (RSAPublicKey) keyFactory.generatePublic(pubSpec); - return rsaKey; + PublicKey publicKey = keyFactory.generatePublic(pubSpec); + if (!(publicKey instanceof RSAPublicKey)) + throw new IllegalStateException("Not an RSA key: " + publicKey.getAlgorithm()); + return publicKey; } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("Unknown algorithm: " + e.getMessage()); diff --git a/main/src/test/java/org/apache/james/jdkim/PublicKeyRecordTest.java b/main/src/test/java/org/apache/james/jdkim/PublicKeyRecordTest.java index 2ce3666..db5b1aa 100644 --- a/main/src/test/java/org/apache/james/jdkim/PublicKeyRecordTest.java +++ b/main/src/test/java/org/apache/james/jdkim/PublicKeyRecordTest.java @@ -19,6 +19,7 @@ package org.apache.james.jdkim; +import java.security.KeyPairGenerator; import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.Base64; import org.apache.james.jdkim.api.PublicKeyRecord; @@ -276,4 +277,15 @@ public class PublicKeyRecordTest { assertEquals(TestKeys.publicKey, new PublicKeyRecordImpl("v=DKIM1; k=rsa; p=" + folded).getPublicKey()); } + + @Test + public void nonRsaKeyShouldThrowIllegalStateException() throws Exception { + String ec = Base64.getEncoder().encodeToString( + KeyPairGenerator.getInstance("EC").generateKeyPair().getPublic().getEncoded()); + + assertThatThrownBy(new PublicKeyRecordImpl("v=DKIM1; k=EC; p=" + ec)::getPublicKey) + .isInstanceOf(IllegalStateException.class); + assertThatThrownBy(new PublicKeyRecordImpl("v=DKIM1; k=rsa; p=" + ec)::getPublicKey) + .isInstanceOf(IllegalStateException.class); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
