F-5905: enforce 1 < Y < p-1 range on DH public key in KeyFactory import

pull/237/head
Chris Conlon 2026-07-07 12:49:08 -06:00
parent ac82b660c4
commit 9094a1f274
2 changed files with 54 additions and 0 deletions

View File

@ -393,6 +393,16 @@ public class WolfCryptDHKeyFactory extends KeyFactorySpi {
"Public key value must be positive");
}
/* Validate public key is in range 1 < Y < p-1. Values of 1 or
* p-1 are degenerate and yield a weak shared secret. Mirrors native
* wc_DhCheckPubKey range check. */
if (keySpec.getY().compareTo(BigInteger.ONE) <= 0 ||
keySpec.getY().compareTo(
keySpec.getP().subtract(BigInteger.ONE)) >= 0) {
throw new InvalidKeySpecException(
"Public key out of valid range: must satisfy 1 < Y < p-1");
}
try {
/* Create DHParameterSpec from p and g */
DHParameterSpec paramSpec = new DHParameterSpec(

View File

@ -448,6 +448,50 @@ public class WolfCryptDHKeyFactoryTest {
}
}
@Test
public void testDHPublicKeySpecRangeValidation() throws Exception {
Assume.assumeTrue(FeatureDetect.DhEnabled());
Assume.assumeTrue(enabledKeySizes.contains(2048));
/* Generate reference key pair to obtain valid DH parameters (P, G)
* and a valid public value Y */
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "wolfJCE");
kpg.initialize(2048);
KeyPair kp = kpg.generateKeyPair();
DHPublicKey pubKey = (DHPublicKey) kp.getPublic();
DHParameterSpec params = pubKey.getParams();
BigInteger p = params.getP();
BigInteger g = params.getG();
KeyFactory kf = KeyFactory.getInstance("DH", "wolfJCE");
/* Y = 1 is degenerate and must be rejected */
try {
kf.generatePublic(new DHPublicKeySpec(BigInteger.ONE, p, g));
fail("Should reject DH public key Y = 1");
} catch (InvalidKeySpecException e) {
/* Expected */
}
/* Y = p-1 is degenerate and must be rejected */
try {
kf.generatePublic(
new DHPublicKeySpec(p.subtract(BigInteger.ONE), p, g));
fail("Should reject DH public key Y = p-1");
} catch (InvalidKeySpecException e) {
/* Expected */
}
/* Valid Y in range 1 < Y < p-1 is accepted */
PublicKey validKey = kf.generatePublic(
new DHPublicKeySpec(pubKey.getY(), p, g));
assertNotNull("Valid DH public key should be created", validKey);
assertTrue("Should be DHPublicKey", validKey instanceof DHPublicKey);
}
@Test
public void testDHPrivateKeySpecConversionWithoutSunJCE()
throws Exception {