| /* |
| * Copyright (c) 2003, 2012, 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. |
| */ |
| |
| /** |
| * @test |
| * @bug 4853305 4865198 4888410 4963723 |
| * @summary Verify that the RSA KeyPairGenerator works |
| * @author Andreas Sterbenz |
| * @key randomness |
| */ |
| |
| import java.io.*; |
| import java.util.*; |
| import java.math.BigInteger; |
| |
| import java.security.*; |
| import java.security.interfaces.*; |
| import java.security.spec.*; |
| |
| public class TestKeyPairGenerator { |
| |
| private static Provider provider; |
| |
| private static byte[] data; |
| |
| private static void testSignature(String algorithm, PrivateKey privateKey, PublicKey publicKey) throws Exception { |
| System.out.println("Testing " + algorithm + "..."); |
| Signature s = Signature.getInstance(algorithm, provider); |
| s.initSign(privateKey); |
| s.update(data); |
| byte[] sig = s.sign(); |
| s.initVerify(publicKey); |
| s.update(data); |
| boolean result = s.verify(sig); |
| if (result == false) { |
| throw new Exception("Verification failed"); |
| } |
| } |
| |
| private static void test(PrivateKey privateKey, PublicKey publicKey) throws Exception { |
| testSignature("MD2withRSA", privateKey, publicKey); |
| testSignature("MD5withRSA", privateKey, publicKey); |
| testSignature("SHA1withRSA", privateKey, publicKey); |
| testSignature("SHA224withRSA", privateKey, publicKey); |
| testSignature("SHA256withRSA", privateKey, publicKey); |
| RSAPublicKey rsaKey = (RSAPublicKey)publicKey; |
| if (rsaKey.getModulus().bitLength() > 512) { |
| // for SHA384 and SHA512 the data is too long for 512 bit keys |
| testSignature("SHA384withRSA", privateKey, publicKey); |
| testSignature("SHA512withRSA", privateKey, publicKey); |
| } |
| } |
| |
| // regression test for 4865198 |
| private static void testInvalidSignature(KeyPair kp1, KeyPair kp2) throws Exception { |
| System.out.println("Testing signature with incorrect key..."); |
| Signature sig = Signature.getInstance("MD5withRSA", provider); |
| sig.initSign(kp1.getPrivate()); |
| byte[] data = new byte[100]; |
| sig.update(data); |
| byte[] signature = sig.sign(); |
| sig.initVerify(kp1.getPublic()); |
| sig.update(data); |
| if (sig.verify(signature) == false) { |
| throw new Exception("verification failed"); |
| } |
| sig.initVerify(kp2.getPublic()); |
| sig.update(data); |
| // verify needs to return false and not throw an Exception |
| try { |
| if (sig.verify(signature)) { |
| throw new Exception("verification unexpectedly succeeded"); |
| } |
| } catch (SignatureException se) { |
| // Yet another kind of failure, OK. |
| } |
| } |
| |
| public static void main(String[] args) throws Exception { |
| long start = System.currentTimeMillis(); |
| provider = Security.getProvider("SunRsaSign"); |
| data = new byte[2048]; |
| // keypair generation is very slow, test only a few short keys |
| int[] keyLengths = {512, 512, 1024}; |
| BigInteger[] pubExps = {null, BigInteger.valueOf(3), null}; |
| KeyPair[] keyPairs = new KeyPair[3]; |
| new Random().nextBytes(data); |
| KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", provider); |
| for (int i = 0; i < keyLengths.length; i++) { |
| int len = keyLengths[i]; |
| BigInteger exp = pubExps[i]; |
| System.out.println("Generating " + len + " bit keypair..."); |
| if (exp == null) { |
| kpg.initialize(len); |
| } else { |
| kpg.initialize(new RSAKeyGenParameterSpec(len, exp)); |
| } |
| KeyPair kp = kpg.generateKeyPair(); |
| keyPairs[i] = kp; |
| RSAPublicKey publicKey = (RSAPublicKey)kp.getPublic(); |
| System.out.println(publicKey); |
| RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey)kp.getPrivate(); |
| if (publicKey.getModulus().equals(privateKey.getModulus()) == false) { |
| throw new Exception("Moduli do not match"); |
| } |
| if (publicKey.getPublicExponent().equals(privateKey.getPublicExponent()) == false) { |
| throw new Exception("Exponents do not match"); |
| } |
| int keyLen = publicKey.getModulus().bitLength(); |
| if ((keyLen > len) || (keyLen < len - 1)) { |
| throw new Exception("Incorrect key length: " + keyLen); |
| } |
| if (exp != null) { |
| if (exp.equals(publicKey.getPublicExponent()) == false) { |
| throw new Exception("Incorrect exponent"); |
| } |
| } |
| test(privateKey, publicKey); |
| } |
| testInvalidSignature(keyPairs[0], keyPairs[1]); |
| testInvalidSignature(keyPairs[0], keyPairs[2]); |
| testInvalidSignature(keyPairs[2], keyPairs[0]); |
| long stop = System.currentTimeMillis(); |
| System.out.println("All tests passed (" + (stop - start) + " ms)."); |
| } |
| } |