# HG changeset patch # User tyan # Date 1441835858 0 # Node ID 142bd680022df519fba8946efff2d4fdcf6bcd32 # Parent b669acfaeb657bf7e2235682a907bfa15dea6ae2 8044199: Tests for RSA keys and key specifications Summary: added various tests for SunRsaSign provider Reviewed-by: valeriep diff -r b669acfaeb65 -r 142bd680022d jdk/test/sun/security/rsa/KeySizeTest.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; + } +} diff -r b669acfaeb65 -r 142bd680022d jdk/test/sun/security/rsa/PrivateKeyEqualityTest.java --- /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"); + } + } +} diff -r b669acfaeb65 -r 142bd680022d jdk/test/sun/security/rsa/SignatureTest.java --- /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"); + } + } +} diff -r b669acfaeb65 -r 142bd680022d jdk/test/sun/security/rsa/SpecTest.java --- /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."); + } + } +}