/* * Copyright (c) 2021, 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 8260274 * @run main/othervm TestDefaultRandom APG 1 * @run main/othervm TestDefaultRandom APG 2 * @run main/othervm TestDefaultRandom KPG 1 * @run main/othervm TestDefaultRandom KPG 2 * @run main/othervm TestDefaultRandom CIP 1 * @run main/othervm TestDefaultRandom CIP 2 * @run main/othervm TestDefaultRandom CIP 3 * @run main/othervm TestDefaultRandom CIP 4 * @run main/othervm TestDefaultRandom KA 1 * @run main/othervm TestDefaultRandom KA 2 * @run main/othervm TestDefaultRandom KG 1 * @run main/othervm TestDefaultRandom KG 2 * @summary Ensure the default SecureRandom impl is used as the javadoc * spec stated when none supplied. */ import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; import java.security.*; import java.security.cert.Certificate; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAGenParameterSpec; import java.security.spec.RSAKeyGenParameterSpec; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.IvParameterSpec; public class TestDefaultRandom { public static void main(String[] argv) throws Exception { if (argv.length != 2) { throw new RuntimeException("Error: missing test parameters"); } switch (argv[0]) { case "APG" -> check(AlgorithmParameterGenerator.getInstance("DSA"), argv[1]); case "KPG" -> check(KeyPairGenerator.getInstance("RSA"), argv[1]); case "CIP" -> check(Cipher.getInstance("AES/CBC/NoPadding"), argv[1]); case "KA" -> check(KeyAgreement.getInstance("DH"), argv[1]); case "KG" -> check(KeyGenerator.getInstance("AES"), argv[1]); default -> throw new RuntimeException ("Error: unsupported test type"); } } private static void check(Object obj, String testNum) { if (obj == null) throw new NullPointerException(); SampleProvider prov = new SampleProvider(); Security.insertProviderAt(prov, 1); int b4Cnt = SampleProvider.count; System.out.println("before, count = " + b4Cnt); // Note that the arguments may not be valid, they just need to be // non-null to trigger the call for checking if the default // SecureRandom impl is used try { if (obj instanceof AlgorithmParameterGenerator) { AlgorithmParameterGenerator apg = (AlgorithmParameterGenerator) obj; switch (testNum) { case "1" -> apg.init(123); case "2" -> apg.init((AlgorithmParameterSpec) null); default -> throw new RuntimeException ("Error: invalid test#"); } } else if (obj instanceof KeyPairGenerator) { KeyPairGenerator kpg = (KeyPairGenerator) obj; switch (testNum) { case "1" -> kpg.initialize(123); case "2" -> kpg.initialize((AlgorithmParameterSpec) null); default -> throw new RuntimeException ("Error: invalid test#"); } } else if (obj instanceof Cipher) { Cipher c = (Cipher) obj; switch (testNum) { case "1" -> c.init(Cipher.ENCRYPT_MODE, (Key) null); case "2" -> c.init(Cipher.ENCRYPT_MODE, (Key) null, (AlgorithmParameterSpec) null); case "3" -> c.init(Cipher.ENCRYPT_MODE, (Key) null, (AlgorithmParameters) null); case "4" -> c.init(Cipher.ENCRYPT_MODE, (Certificate)null); default -> throw new RuntimeException ("Error: invalid test#"); } } else if (obj instanceof KeyAgreement) { KeyAgreement ka = (KeyAgreement) obj; switch (testNum) { case "1" -> ka.init((Key) null); case "2" -> ka.init((Key) null, (AlgorithmParameterSpec) null); default -> throw new RuntimeException ("Error: invalid test#"); } } else if (obj instanceof KeyGenerator) { KeyGenerator kg = (KeyGenerator) obj; switch (testNum) { case "1" -> kg.init(123); case "2" -> kg.init((AlgorithmParameterSpec) null); default -> throw new RuntimeException ("Error: invalid test#"); } } else { throw new RuntimeException("Error: Unsupported type"); } } catch (GeneralSecurityException | InvalidParameterException e) { // expected; ignore } System.out.println("after, count = " + SampleProvider.count); if (SampleProvider.count == b4Cnt) { throw new RuntimeException("Test Failed"); } } private static class SampleProvider extends Provider { static int count = 0; static String SR_ALGO = "Custom"; SampleProvider() { super("Sample", "1.0", "test provider with custom SR impl"); putService(new SampleService(this, "SecureRandom", SR_ALGO, "SampleSecureRandom.class" /* stub class name */, null, null)); } private static class SampleService extends Service { SampleService(Provider p, String type, String alg, String cn, List aliases, Map attrs) { super(p, type, alg, cn, aliases, attrs); } @Override public Object newInstance(Object param) throws NoSuchAlgorithmException { String alg = getAlgorithm(); String type = getType(); if (type.equals("SecureRandom") && alg.equals(SR_ALGO)) { SampleProvider.count++; return new CustomSR(); } else { // should never happen throw new NoSuchAlgorithmException("No support for " + alg); } } } private static class CustomSR extends SecureRandomSpi { @Override protected void engineSetSeed(byte[] seed) { } @Override protected void engineNextBytes(byte[] bytes) { } @Override protected byte[] engineGenerateSeed(int numBytes) { return new byte[numBytes]; } } } }