| /* | |
| * 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<String> aliases, Map<String,String> 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]; | |
| } | |
| } | |
| } | |
| } |