J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. |
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | * |
| 5 | * This code is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License version 2 only, as |
| 7 | * published by the Free Software Foundation. |
| 8 | * |
| 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 12 | * version 2 for more details (a copy is included in the LICENSE file that |
| 13 | * accompanied this code). |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License version |
| 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
| 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 18 | * |
| 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
| 21 | * have any questions. |
| 22 | */ |
| 23 | |
| 24 | /** |
| 25 | * @test |
| 26 | * @bug 4856966 |
| 27 | * @summary Verify that the RSA KeyPairGenerator works |
| 28 | * @author Andreas Sterbenz |
| 29 | * @library .. |
| 30 | */ |
| 31 | |
| 32 | import java.io.*; |
| 33 | import java.util.*; |
| 34 | import java.math.BigInteger; |
| 35 | |
| 36 | import java.security.*; |
| 37 | import java.security.interfaces.*; |
| 38 | import java.security.spec.*; |
| 39 | |
| 40 | public class TestKeyPairGenerator extends PKCS11Test { |
| 41 | |
| 42 | private static Provider provider; |
| 43 | |
| 44 | private static byte[] data; |
| 45 | |
| 46 | private static void testSignature(String algorithm, PrivateKey privateKey, PublicKey publicKey) throws Exception { |
| 47 | System.out.println("Testing " + algorithm + "..."); |
| 48 | Signature s = Signature.getInstance(algorithm, provider); |
| 49 | s.initSign(privateKey); |
| 50 | s.update(data); |
| 51 | byte[] sig = s.sign(); |
| 52 | s.initVerify(publicKey); |
| 53 | s.update(data); |
| 54 | boolean result = s.verify(sig); |
| 55 | if (result == false) { |
| 56 | throw new Exception("Verification failed"); |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | private static void test(PrivateKey privateKey, PublicKey publicKey) throws Exception { |
| 61 | testSignature("MD2withRSA", privateKey, publicKey); |
| 62 | testSignature("MD5withRSA", privateKey, publicKey); |
| 63 | testSignature("SHA1withRSA", privateKey, publicKey); |
| 64 | testSignature("SHA256withRSA", privateKey, publicKey); |
| 65 | RSAPublicKey rsaKey = (RSAPublicKey)publicKey; |
| 66 | if (rsaKey.getModulus().bitLength() > 512) { |
| 67 | // for SHA384 and SHA512 the data is too long for 512 bit keys |
| 68 | testSignature("SHA384withRSA", privateKey, publicKey); |
| 69 | testSignature("SHA512withRSA", privateKey, publicKey); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | // regression test for 4865198 |
| 74 | private static void testInvalidSignature(KeyPair kp1, KeyPair kp2) throws Exception { |
| 75 | System.out.println("Testing signature with incorrect key..."); |
| 76 | Signature sig = Signature.getInstance("MD5withRSA", provider); |
| 77 | sig.initSign(kp1.getPrivate()); |
| 78 | byte[] data = new byte[100]; |
| 79 | sig.update(data); |
| 80 | byte[] signature = sig.sign(); |
| 81 | sig.initVerify(kp1.getPublic()); |
| 82 | sig.update(data); |
| 83 | if (sig.verify(signature) == false) { |
| 84 | throw new Exception("verification failed"); |
| 85 | } |
| 86 | sig.initVerify(kp2.getPublic()); |
| 87 | sig.update(data); |
| 88 | // verify needs to return false and not throw an Exception |
| 89 | if (sig.verify(signature)) { |
| 90 | throw new Exception("verification unexpectedly succeeded"); |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | public static void main(String[] args) throws Exception { |
| 95 | main(new TestKeyPairGenerator()); |
| 96 | } |
| 97 | |
| 98 | public void main(Provider p) throws Exception { |
| 99 | long start = System.currentTimeMillis(); |
| 100 | provider = p; |
| 101 | data = new byte[2048]; |
| 102 | // keypair generation is very slow, test only a few short keys |
| 103 | int[] keyLengths = {512, 512, 1024}; |
| 104 | BigInteger[] pubExps = {null, BigInteger.valueOf(3), null}; |
| 105 | KeyPair[] keyPairs = new KeyPair[3]; |
| 106 | new Random().nextBytes(data); |
| 107 | KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", provider); |
| 108 | for (int i = 0; i < keyLengths.length; i++) { |
| 109 | int len = keyLengths[i]; |
| 110 | BigInteger exp = pubExps[i]; |
| 111 | System.out.println("Generating " + len + " bit keypair..."); |
| 112 | if (exp == null) { |
| 113 | kpg.initialize(len); |
| 114 | } else { |
| 115 | kpg.initialize(new RSAKeyGenParameterSpec(len, exp)); |
| 116 | } |
| 117 | KeyPair kp = kpg.generateKeyPair(); |
| 118 | keyPairs[i] = kp; |
| 119 | RSAPublicKey publicKey = (RSAPublicKey)kp.getPublic(); |
| 120 | System.out.println(publicKey); |
| 121 | RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey)kp.getPrivate(); |
| 122 | if (publicKey.getModulus().equals(privateKey.getModulus()) == false) { |
| 123 | throw new Exception("Moduli do not match"); |
| 124 | } |
| 125 | if (publicKey.getPublicExponent().equals(privateKey.getPublicExponent()) == false) { |
| 126 | throw new Exception("Exponents do not match"); |
| 127 | } |
| 128 | int keyLen = publicKey.getModulus().bitLength(); |
| 129 | if ((keyLen > len) || (keyLen < len - 1)) { |
| 130 | throw new Exception("Incorrect key length: " + keyLen); |
| 131 | } |
| 132 | if (exp != null) { |
| 133 | if (exp.equals(publicKey.getPublicExponent()) == false) { |
| 134 | throw new Exception("Incorrect exponent"); |
| 135 | } |
| 136 | } |
| 137 | test(privateKey, publicKey); |
| 138 | } |
| 139 | testInvalidSignature(keyPairs[0], keyPairs[1]); |
| 140 | testInvalidSignature(keyPairs[0], keyPairs[2]); |
| 141 | long stop = System.currentTimeMillis(); |
| 142 | System.out.println("All tests passed (" + (stop - start) + " ms)."); |
| 143 | } |
| 144 | } |