8044199: Tests for RSA keys and key specifications
authortyan
Wed, 09 Sep 2015 21:57:38 +0000
changeset 32509 142bd680022d
parent 32508 b669acfaeb65
child 32510 7530a468314c
8044199: Tests for RSA keys and key specifications Summary: added various tests for SunRsaSign provider Reviewed-by: valeriep
jdk/test/sun/security/rsa/KeySizeTest.java
jdk/test/sun/security/rsa/PrivateKeyEqualityTest.java
jdk/test/sun/security/rsa/SignatureTest.java
jdk/test/sun/security/rsa/SpecTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/rsa/KeySizeTest.java	Wed Sep 09 21:57:38 2015 +0000
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+
+/**
+ * @test
+ * @bug 8044199
+ * @summary test if the private and public key size are the same as what is set
+ * through KeyPairGenerator.
+ * @run main KeySizeTest 512 10
+ * @run main KeySizeTest 768 10
+ * @run main KeySizeTest 1024 10
+ * @run main KeySizeTest 2048 5
+ * @run main KeySizeTest 4096 1
+ */
+public class KeySizeTest {
+
+    /**
+     * ALGORITHM name, fixed as RSA.
+     */
+    private static final String KEYALG = "RSA";
+
+    /**
+     * JDK default RSA Provider.
+     */
+    private static final String PROVIDER_NAME = "SunRsaSign";
+
+    public static void main(String[] args) throws Exception {
+        int iKeyPairSize = Integer.parseInt(args[0]);
+        int maxLoopCnt = Integer.parseInt(args[1]);
+
+        int failCount = 0;
+        KeyPairGenerator keyPairGen
+                = KeyPairGenerator.getInstance(KEYALG, PROVIDER_NAME);
+        keyPairGen.initialize(iKeyPairSize);
+        // Generate RSA keypair
+        KeyPair keyPair = keyPairGen.generateKeyPair();
+
+        // Get priavte and public keys
+        PrivateKey privateKey = keyPair.getPrivate();
+        PublicKey publicKey = keyPair.getPublic();
+        try {
+            if (!sizeTest(keyPair)) {
+                failCount++;
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace(System.err);
+            failCount++;
+        }
+
+        for (int iCnt = 0; iCnt < maxLoopCnt; iCnt++) {
+
+            // Get keysize (modulus) of keys
+            KeyFactory keyFact = KeyFactory.getInstance(KEYALG, PROVIDER_NAME);
+
+            // Comparing binary length.
+            RSAPrivateKeySpec privateKeySpec
+                    = (RSAPrivateKeySpec) keyFact.getKeySpec(privateKey,
+                            RSAPrivateKeySpec.class);
+            int iPrivateKeySize = privateKeySpec.getModulus().bitLength();
+
+            RSAPublicKeySpec publicKeySpec
+                    = (RSAPublicKeySpec) keyFact.getKeySpec(publicKey,
+                            RSAPublicKeySpec.class);
+            int iPublicKeySize = publicKeySpec.getModulus().bitLength();
+
+            if ((iKeyPairSize != iPublicKeySize) || (iKeyPairSize != iPrivateKeySize)) {
+                System.err.println("iKeyPairSize : " + iKeyPairSize);
+                System.err.println("Generated a " + iPrivateKeySize
+                        + " bit RSA private key");
+                System.err.println("Generated a " + iPublicKeySize
+                        + " bit RSA public key");
+                failCount++;
+            }
+        }
+
+        if (failCount > 0) {
+            throw new RuntimeException("There are " + failCount + " tests failed.");
+        }
+    }
+
+    /**
+     * @param kpair test key pair.
+     * @return true if test passed. false if test failed.
+     */
+    private static boolean sizeTest(KeyPair kpair) {
+        RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate();
+        RSAPublicKey pub = (RSAPublicKey) kpair.getPublic();
+
+        // test the getModulus method
+        if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) {
+            if (!priv.getModulus().equals(pub.getModulus())) {
+                System.err.println("priv.getModulus() = " + priv.getModulus());
+                System.err.println("pub.getModulus() = " + pub.getModulus());
+                return false;
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/rsa/PrivateKeyEqualityTest.java	Wed Sep 09 21:57:38 2015 +0000
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateCrtKeySpec;
+
+/**
+ * @test
+ * @bug 8044199 4666485
+ * @summary Equality checking for RSAPrivateKey by SunRsaSign provider.
+ */
+public class PrivateKeyEqualityTest {
+    /**
+     * ALGORITHM name, fixed as RSA.
+     */
+    private static final String KEYALG = "RSA";
+
+    /**
+     * JDK default RSA Provider.
+     */
+    private static final String PROVIDER_NAME = "SunRsaSign";
+
+    public static void main(String[] args) throws NoSuchAlgorithmException,
+            NoSuchProviderException, InvalidKeySpecException {
+        // Generate the first key.
+        KeyPairGenerator generator
+                = KeyPairGenerator.getInstance(KEYALG, PROVIDER_NAME);
+        KeyPair keyPair = generator.generateKeyPair();
+        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
+        if (!(rsaPrivateKey instanceof RSAPrivateCrtKey)) {
+            System.err.println("rsaPrivateKey class : " + rsaPrivateKey.getClass().getName());
+            throw new RuntimeException("rsaPrivateKey is not a RSAPrivateCrtKey instance");
+        }
+
+        // Generate the second key.
+        KeyFactory factory = KeyFactory.getInstance(KEYALG, PROVIDER_NAME);
+        RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(
+                rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent());
+        RSAPrivateKey rsaPrivateKey2 = (RSAPrivateKey) factory.generatePrivate(
+                rsaPrivateKeySpec);
+
+        // Generate the third key.
+        PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(
+                rsaPrivateKey.getEncoded());
+        RSAPrivateKey rsaPrivateKey3 = (RSAPrivateKey) factory.generatePrivate(
+                encodedKeySpec);
+
+        // Check for equality.
+        if (rsaPrivateKey.equals(rsaPrivateKey2)) {
+            throw new RuntimeException("rsaPrivateKey should not equal to rsaPrivateKey2");
+        }
+        if (!rsaPrivateKey3.equals(rsaPrivateKey)) {
+            throw new RuntimeException("rsaPrivateKey3 should equal to rsaPrivateKey");
+        }
+        if (rsaPrivateKey3.equals(rsaPrivateKey2)) {
+            throw new RuntimeException("rsaPrivateKey3 should not equal to rsaPrivateKey2");
+        }
+        if (rsaPrivateKey2.equals(rsaPrivateKey3)) {
+            throw new RuntimeException("rsaPrivateKey2 should not equal to rsaPrivateKey3");
+        }
+
+        // Generate the fourth key.
+        RSAPrivateCrtKey rsaPrivateCrtKey =  (RSAPrivateCrtKey)rsaPrivateKey;
+        RSAPrivateCrtKeySpec rsaPrivateCrtKeySpec = new RSAPrivateCrtKeySpec(
+                rsaPrivateCrtKey.getModulus(),
+                rsaPrivateCrtKey.getPublicExponent(),
+                rsaPrivateCrtKey.getPrivateExponent(),
+                rsaPrivateCrtKey.getPrimeP(),
+                rsaPrivateCrtKey.getPrimeQ(),
+                rsaPrivateCrtKey.getPrimeExponentP(),
+                rsaPrivateCrtKey.getPrimeExponentQ(),
+                rsaPrivateCrtKey.getCrtCoefficient()
+            );
+        RSAPrivateCrtKey rsaPrivateKey4 = (RSAPrivateCrtKey) factory.generatePrivate(
+                rsaPrivateCrtKeySpec);
+        if (!rsaPrivateKey.equals(rsaPrivateKey4)) {
+            throw new RuntimeException("rsaPrivateKey should equal to rsaPrivateKey4");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/rsa/SignatureTest.java	Wed Sep 09 21:57:38 2015 +0000
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import static javax.crypto.Cipher.PRIVATE_KEY;
+import static javax.crypto.Cipher.PUBLIC_KEY;
+import jdk.testlibrary.RandomFactory;
+
+/**
+ * @test
+ * @bug 8044199
+ * @summary Create a signature for RSA and get its signed data. re-initiate
+ *          the signature with the public key. The signature can be verified
+ *          by acquired signed data.
+ * @key randomness
+ * @library ../../../lib/testlibrary
+ * @run main SignatureTest MD2withRSA 512
+ * @run main SignatureTest MD5withRSA 512
+ * @run main SignatureTest SHA1withRSA 512
+ * @run main SignatureTest SHA256withRSA 512
+ * @run main SignatureTest MD2withRSA 768
+ * @run main SignatureTest MD5withRSA 768
+ * @run main SignatureTest SHA1withRSA 768
+ * @run main SignatureTest SHA256withRSA 768
+ * @run main SignatureTest MD2withRSA 1024
+ * @run main SignatureTest MD5withRSA 1024
+ * @run main SignatureTest SHA1withRSA 1024
+ * @run main SignatureTest SHA256withRSA 1024
+ * @run main SignatureTest MD2withRSA 2048
+ * @run main SignatureTest MD5withRSA 2048
+ * @run main SignatureTest SHA1withRSA 2048
+ * @run main SignatureTest SHA256withRSA 2048
+ * @run main/timeout=240 SignatureTest MD2withRSA 4096
+ * @run main/timeout=240 SignatureTest MD5withRSA 4096
+ * @run main/timeout=240 SignatureTest SHA1withRSA 4096
+ * @run main/timeout=240 SignatureTest SHA256withRSA 4096
+ * @run main/timeout=240 SignatureTest MD2withRSA 5120
+ * @run main/timeout=240 SignatureTest MD5withRSA 5120
+ * @run main/timeout=240 SignatureTest SHA1withRSA 5120
+ * @run main/timeout=240 SignatureTest SHA256withRSA 5120
+ * @run main/timeout=240 SignatureTest MD2withRSA 6144
+ * @run main/timeout=240 SignatureTest MD5withRSA 6144
+ * @run main/timeout=240 SignatureTest SHA1withRSA 6144
+ * @run main/timeout=240 SignatureTest SHA256withRSA 6144
+ */
+public class SignatureTest {
+    /**
+     * ALGORITHM name, fixed as RSA.
+     */
+    private static final String KEYALG = "RSA";
+
+    /**
+     * JDK default RSA Provider.
+     */
+    private static final String PROVIDER = "SunRsaSign";
+
+    /**
+     * How much times signature updated.
+     */
+    private static final int UPDATE_TIMES_FIFTY = 50;
+
+    /**
+     * How much times signature initial updated.
+     */
+    private static final int UPDATE_TIMES_HUNDRED = 100;
+
+    public static void main(String[] args) throws Exception {
+        String testAlg = args[0];
+        int testSize = Integer.parseInt(args[1]);
+
+        byte[] data = new byte[100];
+        RandomFactory.getRandom().nextBytes(data);
+
+        // create a key pair
+        KeyPair kpair = generateKeys(KEYALG, testSize);
+        Key[] privs = manipulateKey(PRIVATE_KEY, kpair.getPrivate());
+        Key[] pubs = manipulateKey(PUBLIC_KEY, kpair.getPublic());
+        // For signature algorithm, create and verify a signature
+
+        Arrays.stream(privs).forEach(priv
+                -> Arrays.stream(pubs).forEach(pub -> {
+                    try {
+                        checkSignature(data, (PublicKey) pub, (PrivateKey) priv,
+                                testAlg);
+                    } catch (NoSuchAlgorithmException | InvalidKeyException
+                            | SignatureException | NoSuchProviderException ex) {
+                        throw new RuntimeException(ex);
+                    }
+                }
+                ));
+
+    }
+
+    private static KeyPair generateKeys(String keyalg, int size)
+            throws NoSuchAlgorithmException {
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalg);
+        kpg.initialize(size);
+        return kpg.generateKeyPair();
+    }
+
+    private static Key[] manipulateKey(int type, Key key)
+            throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
+        KeyFactory kf = KeyFactory.getInstance(KEYALG, PROVIDER);
+
+        switch (type) {
+            case PUBLIC_KEY:
+                try {
+                    kf.getKeySpec(key, RSAPrivateKeySpec.class);
+                    throw new RuntimeException("Expected InvalidKeySpecException "
+                            + "not thrown");
+                } catch (InvalidKeySpecException expected) {
+                }
+
+                return new Key[]{
+                    kf.generatePublic(kf.getKeySpec(key, RSAPublicKeySpec.class)),
+                    kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())),
+                    kf.generatePublic(new RSAPublicKeySpec(
+                    ((RSAPublicKey) key).getModulus(),
+                    ((RSAPublicKey) key).getPublicExponent()))
+                };
+            case PRIVATE_KEY:
+                try {
+                    kf.getKeySpec(key, RSAPublicKeySpec.class);
+                    throw new RuntimeException("Expected InvalidKeySpecException"
+                            + " not thrown");
+                } catch (InvalidKeySpecException expected) {
+                }
+                return new Key[]{
+                    kf.generatePrivate(kf.getKeySpec(key,
+                    RSAPrivateKeySpec.class)),
+                    kf.generatePrivate(new PKCS8EncodedKeySpec(
+                    key.getEncoded())),
+                    kf.generatePrivate(new RSAPrivateKeySpec(((RSAPrivateKey) key).getModulus(),
+                    ((RSAPrivateKey) key).getPrivateExponent()))
+                };
+        }
+        throw new RuntimeException("We shouldn't reach here");
+    }
+
+    private static void checkSignature(byte[] data, PublicKey pub,
+            PrivateKey priv, String sigalg) throws NoSuchAlgorithmException,
+            InvalidKeyException, SignatureException, NoSuchProviderException {
+        Signature sig = Signature.getInstance(sigalg, PROVIDER);
+        sig.initSign(priv);
+        for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
+            sig.update(data);
+        }
+        byte[] signedData = sig.sign();
+
+        // Make sure signature verifies with original data
+        sig.initVerify(pub);
+        for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
+            sig.update(data);
+        }
+        if (!sig.verify(signedData)) {
+            throw new RuntimeException("Failed to verify " + sigalg
+                    + " signature");
+        }
+
+        // Make sure signature does NOT verify when the original data
+        // has changed
+        sig.initVerify(pub);
+        for (int i = 0; i < UPDATE_TIMES_FIFTY; i++) {
+            sig.update(data);
+        }
+
+        if (sig.verify(signedData)) {
+            throw new RuntimeException("Failed to detect bad " + sigalg
+                    + " signature");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/rsa/SpecTest.java	Wed Sep 09 21:57:38 2015 +0000
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+/**
+ * @test
+ * @bug 8044199
+ * @summary Check same KeyPair's private key and public key have same modulus.
+ *  also check public key's public exponent equals to given spec's public
+ *  exponent.
+ * @run main SpecTest 512
+ * @run main SpecTest 768
+ * @run main SpecTest 1024
+ * @run main SpecTest 2048
+ * @run main/timeout=240 SpecTest 4096
+ * @run main/timeout=240 SpecTest 5120
+ */
+public class SpecTest {
+    /**
+     * ALGORITHM name, fixed as RSA.
+     */
+    private static final String KEYALG = "RSA";
+
+    /**
+     * JDK default RSA Provider.
+     */
+    private static final String PROVIDER = "SunRsaSign";
+
+    /**
+     *
+     * @param kpair test key pair
+     * @param pubExponent expected public exponent.
+     * @return true if test passed. false if test failed.
+     */
+    private static boolean specTest(KeyPair kpair, BigInteger pubExponent) {
+        boolean passed = true;
+        RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate();
+        RSAPublicKey pub = (RSAPublicKey) kpair.getPublic();
+
+        // test the getModulus method
+        if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) {
+            if (!priv.getModulus().equals(pub.getModulus())) {
+                System.err.println("priv.getModulus() = " + priv.getModulus());
+                System.err.println("pub.getModulus() = " + pub.getModulus());
+                passed = false;
+            }
+
+            if (!pubExponent.equals(pub.getPublicExponent())) {
+                System.err.println("pubExponent = " + pubExponent);
+                System.err.println("pub.getPublicExponent() = "
+                        + pub.getPublicExponent());
+                passed = false;
+            }
+        }
+        return passed;
+    }
+
+    public static void main(String[] args) {
+        int failCount = 0;
+
+        // Test key size.
+        int size = Integer.parseInt(args[0]);
+
+        try {
+            KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
+            kpg1.initialize(new RSAKeyGenParameterSpec(size,
+                    RSAKeyGenParameterSpec.F4));
+            if (!specTest(kpg1.generateKeyPair(),
+                    RSAKeyGenParameterSpec.F4)) {
+                failCount++;
+            }
+
+            KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
+            kpg2.initialize(new RSAKeyGenParameterSpec(size,
+                    RSAKeyGenParameterSpec.F0));
+            if (!specTest(kpg2.generateKeyPair(), RSAKeyGenParameterSpec.F0)) {
+                failCount++;
+            }
+        } catch (NoSuchAlgorithmException | NoSuchProviderException
+                | InvalidAlgorithmParameterException ex) {
+            ex.printStackTrace(System.err);
+            failCount++;
+        }
+
+        if (failCount != 0) {
+            throw new RuntimeException("There are " + failCount
+                    + " tests failed.");
+        }
+    }
+}