Path: blob/master/test/jdk/java/security/SecureRandom/GetInstanceTest.java
41149 views
/*1* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 814103926* @library /test/lib27* @summary SecureRandom supports multiple getInstance method including28* getInstanceStrong() method. This test verifies a set of possible29* cases for getInstance with different SecureRandom mechanism30* supported in Java.31* @run main GetInstanceTest32*/33import java.security.NoSuchAlgorithmException;34import java.security.NoSuchProviderException;35import java.security.SecureRandom;36import java.security.SecureRandomParameters;37import java.security.DrbgParameters;38import static java.security.DrbgParameters.Capability.*;39import java.security.Security;40import java.util.Arrays;41import jdk.test.lib.Asserts;4243public class GetInstanceTest {4445private static final boolean PASS = true;46private static final String INVALID_ALGO = "INVALID";47private static final String SUN_PROVIDER = "SUN";48private static final String INVALID_PROVIDER = "INVALID";49private static final String STRONG_ALG_SEC_PROP50= "securerandom.strongAlgorithms";51private static final String DRBG_CONFIG = "securerandom.drbg.config";52private static final String DRBG_CONFIG_VALUE53= Security.getProperty(DRBG_CONFIG);5455public static void main(String[] args) throws Exception {5657boolean success = true;58// Only accepted failure is NoSuchAlgorithmException.59// For any other failure the test case will fail here.60SecureRandom sr = matchExc(() -> SecureRandom.getInstanceStrong(),61PASS, NoSuchAlgorithmException.class,62"PASS - Undefined security Property "63+ "'securerandom.strongAlgorithms'");64System.out.format("Current platform supports mechanism: '%s' through "65+ "provider: '%s' for the method getInstanceStrong().",66sr.getAlgorithm(), sr.getProvider().getName());6768// DRBG name should appear with "securerandom.strongAlgorithms"69// security property.70String origDRBGConfig = Security.getProperty(STRONG_ALG_SEC_PROP);71if (!origDRBGConfig.contains("DRBG")) {72throw new RuntimeException("DRBG is not associated with default "73+ "strong algorithm through security Property: "74+ "'securerandom.strongAlgorithms'.");75}76try {77Security.setProperty(STRONG_ALG_SEC_PROP, "DRBG:SUN");78sr = matchExc(() -> SecureRandom.getInstanceStrong(),79PASS, NoSuchAlgorithmException.class,80"PASS - Undefined security Property "81+ "'securerandom.strongAlgorithms'");82checkAttributes(sr, "DRBG");83} finally {84Security.setProperty(STRONG_ALG_SEC_PROP, origDRBGConfig);85}8687for (String mech : new String[]{88"SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG", INVALID_ALGO,}) {89System.out.printf("%nTest SecureRandom mechanism: '%s'", mech);90try {91if (isDRBG(mech)) {92Security.setProperty(DRBG_CONFIG, mech);93}94verifyInstance(mech);95} catch (Exception e) {96e.printStackTrace(System.out);97success = false;98} finally {99Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE);100}101}102if (!success) {103throw new RuntimeException("At least one test failed.");104}105}106107private static void verifyInstance(String mech) throws Exception {108109String srAlgo = isDRBG(mech) ? "DRBG" : mech;110111// Test for getInstance(algorithm) method.112// It should pass for all case other than invalid algorithm name.113// If it fails then the expected exception type should be114// NoSuchAlgorithmException. Any other Exception type occured will be115// treated as failure.116checkAttributes(117matchExc(() -> SecureRandom.getInstance(srAlgo), !(nsa(mech)),118NoSuchAlgorithmException.class,119String.format("PASS - It is expected to fail for"120+ " getInstance(algorithm) when algorithm: '%s'"121+ " is null or invalid.", mech)), mech);122// Test for getInstance(algorithm, provider) method.123checkAttributes(124matchExc(() -> SecureRandom.getInstance(srAlgo,125Security.getProvider(SUN_PROVIDER)),126!(nsa(mech)),127NoSuchAlgorithmException.class,128String.format("PASS - It is expected to fail for"129+ " getInstance(algorithm, provider) when"130+ " algorithm:'%s' is null or invalid.", mech)),131mech);132// Test for getInstance(algorithm, providerName) method.133checkAttributes(134matchExc(() -> SecureRandom.getInstance(srAlgo, SUN_PROVIDER),135!(nsa(mech)), NoSuchAlgorithmException.class,136String.format("PASS - It is expected to fail for "137+ "getInstance(algorithm, providerName) when "138+ "algorithm: '%s' is null or invalid.", mech)),139mech);140// Test for getInstance(algorithm, providerName) method.141checkAttributes(142matchExc(() -> SecureRandom.getInstance(143srAlgo, INVALID_PROVIDER),144!PASS, NoSuchProviderException.class,145String.format("PASS - It is expected to fail for "146+ "getInstance(algorithm, providerName) when "147+ "provider name: '%s' is invalid and "148+ "algorithm: '%s'", INVALID_PROVIDER, mech)),149mech);150151// Run the test for a set of SecureRandomParameters152for (SecureRandomParameters param : Arrays.asList(null,153DrbgParameters.instantiation(-1, NONE, null))) {154155System.out.printf("%nRunning DRBG param getInstance() methods "156+ "for algorithm: %s and DRBG param type: %s", mech,157(param != null) ? param.getClass().getName() : param);158159// Following Test are applicable for new DRBG methods only.160// Test for getInstance(algorithm, params) method.161// Tests are expected to pass for DRBG type with valid parameter162// If it fails the expected exception type is derived from163// getExcType(mech, param) method. If exception type is not164// expected then the test will be considered as failure.165checkAttributes(166matchExc(() -> SecureRandom.getInstance(srAlgo, param),167(isDRBG(mech)) && (isValidDRBGParam(param)),168getExcType(mech, param),169String.format("PASS - It is expected to fail "170+ "for getInstance(algorithm, params) "171+ "for algorithm: %s and parameter: %s",172mech, param)),173mech);174// Test for getInstance(algorithm, params, provider) method.175checkAttributes(176matchExc(() -> SecureRandom.getInstance(srAlgo, param,177Security.getProvider(SUN_PROVIDER)),178(isDRBG(mech)) && (isValidDRBGParam(param)),179getExcType(mech, param),180String.format("PASS - It is expected to fail "181+ "for getInstance(algorithm, params, "182+ "provider) for algorithm: %s and "183+ "parameter: %s", mech, param)),184mech);185// Test for getInstance(algorithm, params, providerName) method.186checkAttributes(187matchExc(() -> SecureRandom.getInstance(srAlgo, param,188SUN_PROVIDER),189(isDRBG(mech)) && (isValidDRBGParam(param)),190getExcType(mech, param),191String.format("PASS - It is expected to fail "192+ "for getInstance(algorithm, params, "193+ "providerName) for algorithm: %s and "194+ "parameter: %s", mech, param)), mech);195// getInstance(algorithm, params, providerName) when196// providerName is invalid197checkAttributes(198matchExc(() -> SecureRandom.getInstance(srAlgo, param,199INVALID_PROVIDER),200!PASS, ((param == null)201? IllegalArgumentException.class202: NoSuchProviderException.class),203String.format("PASS - It is expected to fail "204+ "for getInstance(algorithm, params, "205+ "providerName) when param is null or"206+ " provider: %s is invalid for "207+ "algorithm: '%s'", INVALID_PROVIDER,208mech)), mech);209// getInstance(algorithm, params, provider) when provider=null210checkAttributes(211matchExc(() -> SecureRandom.getInstance(srAlgo, param,212(String) null),213!PASS, IllegalArgumentException.class,214String.format("PASS - It is expected to fail "215+ "for getInstance(algorithm, params, "216+ "providerName) when provider name "217+ "is null")), mech);218// getInstance(algorithm, params, providerName) when219// providerName is empty.220checkAttributes(221matchExc(() -> SecureRandom.getInstance(222srAlgo, param, ""),223!PASS, IllegalArgumentException.class,224String.format("PASS - It is expected to fail "225+ "for getInstance(algorithm, params, "226+ "providerName) when provider name "227+ "is empty")), mech);228}229}230231private static boolean isValidDRBGParam(SecureRandomParameters param) {232return (param instanceof DrbgParameters.Instantiation);233}234235/**236* If the mechanism should occur NoSuchAlgorithmException.237*/238private static boolean nsa(String mech) {239return mech.equals(INVALID_ALGO);240}241242/**243* Verify if the mechanism is DRBG type.244* @param mech Mechanism name245* @return True if the mechanism name is DRBG type else False.246*/247private static boolean isDRBG(String mech) {248return mech.contains("_DRBG");249}250251/**252* Type of exception expected for a SecureRandom instance when exception253* occurred while calling getInstance method with a fixed set of parameter.254* @param mech Mechanism used to create a SecureRandom instance255* @param param Parameter to getInstance() method256* @return Exception type expected257*/258private static Class getExcType(String mech, SecureRandomParameters param) {259return ((isDRBG(mech) && !isValidDRBGParam(param)) || param == null)260? IllegalArgumentException.class261: NoSuchAlgorithmException.class;262}263264private interface RunnableCode {265266SecureRandom run() throws Exception;267}268269/**270* Execute a given code block and verify, if the exception type is expected.271* @param r Code block to run272* @param ex Expected exception type273* @param shouldPass If the code execution expected to pass without failure274* @param msg Message to log in case of expected failure275*/276private static SecureRandom matchExc(RunnableCode r, boolean shouldPass,277Class ex, String msg) {278SecureRandom sr = null;279try {280sr = r.run();281if (!shouldPass) {282throw new RuntimeException("Excecution should fail here.");283}284} catch (Exception e) {285System.out.printf("%nOccured exception: %s - Expected exception: %s"286+ " : ", e.getClass(), ex.getCanonicalName());287if (ex.isAssignableFrom(e.getClass())) {288System.out.printf("%n%s : Expected Exception: %s : ",289e.getClass(), msg);290} else if (shouldPass) {291throw new RuntimeException(e);292} else {293System.out.printf("%nIgnore the following exception: %s%n",294e.getMessage());295}296}297return sr;298}299300/**301* Check specific attributes of a SecureRandom instance.302*/303private static void checkAttributes(SecureRandom sr, String mech) {304if (sr == null) {305return;306}307Asserts.assertEquals(sr.getAlgorithm(), (isDRBG(mech) ? "DRBG" : mech));308Asserts.assertEquals(sr.getProvider().getName(), SUN_PROVIDER);309}310311}312313314