[15] RFR 8216012: Infinite loop in RSA KeyPairGenerator
Valerie Peng
valerie.peng at oracle.com
Sat Jan 11 00:29:41 UTC 2020
Hi Masanori Yano,
Your fix looks fine, I just made some minor update to the regression
test, e.g. add more debugging output, removing unnecessary code and
cases, etc.
I put your initial contribution at
http://cr.openjdk.java.net/~valeriep/8216012/webrev.00
I made some update and latest fix is at
http://cr.openjdk.java.net/~valeriep/8216012/webrev.01
Can you please take a look and let me know if you are ok with webrev.01?
If all are well, I will proceed to integrate it into JDK15.
Thanks,
Valerie
On 12/2/2019 4:40 PM, Valerie Peng wrote:
> Hi Masanori Yano,
>
> I can help sponsoring this fix. However, as it's a P4, it may be
> targeted to 15 depending on the available cycles.
>
> Are you a contributor for OpenJDK?
>
> If not, please see http://openjdk.java.net/contribute/ for the process.
>
> Thanks,
> Valerie
> On 10/8/2019 8:10 PM, yano-masanori at fujitsu.com wrote:
>> Hello.
>>
>> I would like to contribute for JDK-8216012.
>>
>> The cause of this problem is RSAKeyPairGenerator that doesn't check
>> the public exponent even though the algorithm of rsa key generation
>> can use only odd exponent number.
>>
>> To generate a KeyPair, the RSAKeyPairGenerator finds two random primes
>> P and Q, and calculate Phi = (P - 1) * (Q - 1). If Phi is not relative
>> prime to exponent, RSAKeyPairGenerator retry from the first.
>>
>> The value of Phi must be an even number because P and Q are odd numbers.
>> If exponent is an even number, the greatest common divisor cannot
>> be 1 because one of common divisors is 2 which is bigger than 1.
>> Therefore, generateKeyPair() method of RSAKeyPairGenerator cannot exit
>> the retrying loop.
>>
>> To solve this problem, I propose to check whether the public exponent
>> is even number.
>>
>> Please sponsor the following change.
>>
>> diff --git
>> a/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java
>> b/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java
>> ---
>> a/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java
>> +++
>> b/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java
>> @@ -96,6 +96,10 @@
>> throw new InvalidAlgorithmParameterException
>> ("Public exponent must be 3 or larger");
>> }
>> + if (!tmpPublicExponent.testBit(0)) {
>> + throw new InvalidAlgorithmParameterException
>> + ("Public exponent must be an odd number");
>> + }
>> if (tmpPublicExponent.bitLength() > tmpKeySize) {
>> throw new InvalidAlgorithmParameterException
>> ("Public exponent must be smaller than key
>> size");
>> diff --git
>> a/test/jdk/sun/security/rsa/TestKeyPairGeneratorExponent.java
>> b/test/jdk/sun/security/rsa/TestKeyPairGeneratorExponent.java
>> new file mode 100644
>> --- /dev/null
>> +++ b/test/jdk/sun/security/rsa/TestKeyPairGeneratorExponent.java
>> @@ -0,0 +1,65 @@
>> +import java.math.BigInteger;
>> +
>> +import java.security.*;
>> +import java.security.interfaces.*;
>> +import java.security.spec.*;
>> +
>> +/**
>> + * @test
>> + * @bug 8216012
>> + * @summary Tests the RSA public key exponent for KeyPairGenerator
>> + * @run main/timeout=60 TestKeyPairGeneratorExponent
>> + */
>> +public class TestKeyPairGeneratorExponent {
>> + private static int keyLen = 512;
>> +
>> + private static BigInteger[] validExponents = new BigInteger[] {
>> + RSAKeyGenParameterSpec.F0,
>> + RSAKeyGenParameterSpec.F4,
>> + // Since 512-bit exponent is larger than modulus, fails in
>> RSAPublicKeyImpl.checkExponentRange().
>> + BigInteger.ONE.shiftLeft(keyLen - 1).subtract(BigInteger.ONE)
>> + };
>> +
>> + private static BigInteger[] invalidExponents = new BigInteger[] {
>> + BigInteger.valueOf(-1),
>> + BigInteger.ZERO,
>> + BigInteger.ONE,
>> + // 8216012: An even number causes infinite loop.
>> + BigInteger.valueOf(4),
>> + BigInteger.ONE.shiftLeft(keyLen)
>> + };
>> +
>> + public static void testValidExponents(KeyPairGenerator kpg,
>> BigInteger exponent) {
>> + try {
>> + kpg.initialize(new RSAKeyGenParameterSpec(keyLen,
>> exponent));
>> + kpg.generateKeyPair();
>> + } catch(InvalidAlgorithmParameterException iape){
>> + throw new RuntimeException("Unexpected Exception: " +
>> iape);
>> + }
>> + }
>> +
>> + public static void testInvalidExponents(KeyPairGenerator kpg,
>> BigInteger exponent) {
>> + try {
>> + kpg.initialize(new RSAKeyGenParameterSpec(keyLen,
>> exponent));
>> + kpg.generateKeyPair();
>> + throw new RuntimeException("Expected
>> InvalidAlgorithmParameterException was not thrown.");
>> + } catch(InvalidAlgorithmParameterException iape){
>> + // Expected InvalidAlgorithmParameterException was
>> thrown.OK
>> + }
>> + }
>> +
>> + public static void main(String[] args) throws Exception {
>> + Provider provider = Security.getProvider("SunRsaSign");
>> + KeyPairGenerator kpg;
>> +
>> + for(BigInteger validExponent : validExponents) {
>> + kpg = KeyPairGenerator.getInstance("RSA", provider);
>> + testValidExponents(kpg, validExponent);
>> + }
>> +
>> + for(BigInteger invalidExponent : invalidExponents) {
>> + kpg = KeyPairGenerator.getInstance("RSA", provider);
>> + testInvalidExponents(kpg, invalidExponent);
>> + }
>> + }
>> +}
>>
>> Regards,
>> Masanori Yano
More information about the security-dev
mailing list