/* * Copyright (c) 2003, 2020, 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 8146293 * @summary Verify that the RSA KeyPairGenerator works * @library /lib * @build jdk.test.lib.SigTestUtil * @run main TestKeyPairGenerator * @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.*; import jdk.test.lib.SigTestUtil; import static jdk.test.lib.SigTestUtil.SignatureType; public class TestKeyPairGenerator { private static Provider provider; private static byte[] data; private static void testSignature(SignatureType type, String mdAlg, PrivateKey privateKey, PublicKey publicKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { System.out.println("Testing against " + mdAlg + "..."); String sigAlg = SigTestUtil.generateSigAlg(type, mdAlg); Signature s = Signature.getInstance(sigAlg, 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 RuntimeException("Verification failed"); } } private static void test(PrivateKey privateKey, PublicKey publicKey) throws Exception { int testSize = ((RSAPublicKey)publicKey).getModulus().bitLength(); System.out.println("modulus size = " + testSize); Iterable md_alg_pkcs15 = SigTestUtil.getDigestAlgorithms(SignatureType.RSA, testSize); md_alg_pkcs15.forEach(mdAlg -> { try { testSignature(SignatureType.RSA, mdAlg, privateKey, publicKey); } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException ex) { throw new RuntimeException(ex); } } ); } // 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)."); } }