Path: blob/master/test/jdk/java/security/SecureRandom/SerializedSeedTest.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 When random number is generated through the a SecureRandom instance28* as well from it's serialized instance in the same time then the29* generated random numbers should be different when one or both are30* reseeded.31* @run main/othervm -Djava.security.egd=file:/dev/urandom SerializedSeedTest32*/33import java.io.ByteArrayOutputStream;34import java.io.IOException;35import java.io.ObjectInputStream;36import java.io.ObjectOutputStream;37import java.io.ByteArrayInputStream;38import java.security.NoSuchAlgorithmException;39import java.security.SecureRandom;40import java.security.Security;41import jdk.test.lib.Asserts;4243public class SerializedSeedTest {4445private static final byte[] SEED = "seed".getBytes();46private static final String DRBG_CONFIG = "securerandom.drbg.config";47private static final String DRBG_CONFIG_VALUE48= Security.getProperty(DRBG_CONFIG);4950public static void main(String[] args) {51boolean success = true;5253for (String mech : new String[]{54"SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) {55System.out.printf(56"%nRunning test for SecureRandom mechanism: '%s'", mech);57try {58// Serialize without seed and compare generated random numbers59// produced through original and serialized instances.60SecureRandom orig = getSRInstance(mech);61SecureRandom copy = deserializedCopy(orig);62System.out.printf("%nSerialize without seed. Generated random"63+ " numbers should be different.");64check(orig, copy, false, mech);6566// Serialize after default seed and compare generated random67// numbers produced through original and serialized instances.68orig = getSRInstance(mech);69orig.nextInt(); // Default seeded70copy = deserializedCopy(orig);71System.out.printf("%nSerialize after default seed. Generated"72+ " random numbers should be same till 20-bytes.");73check(orig, copy, !isDRBG(mech), mech);7475// Serialize after explicit seed and compare generated random76// numbers produced through original and serialized instances.77orig = getSRInstance(mech);78orig.setSeed(SEED); // Explicitly seeded79copy = deserializedCopy(orig);80System.out.printf("%nSerialize after explicit seed. Generated "81+ "random numbers should be same till 20-bytes.");82check(orig, copy, !isDRBG(mech), mech);8384// Serialize without seed but original is explicitly seeded85// before generating any random number. Then compare generated86// random numbers produced through original and serialized87// instances.88orig = getSRInstance(mech);89copy = deserializedCopy(orig);90orig.setSeed(SEED); // Explicitly seeded91System.out.printf("%nSerialize without seed. When original is "92+ "explicitly seeded before generating random numbers,"93+ " Generated random numbers should be different.");94check(orig, copy, false, mech);9596// Serialize after default seed but original is explicitly97// seeded before generating any random number. Then compare98// generated random numbers produced through original and99// serialized instances.100orig = getSRInstance(mech);101orig.nextInt(); // Default seeded102copy = deserializedCopy(orig);103orig.setSeed(SEED); // Explicitly seeded104System.out.printf("%nSerialize after default seed but original "105+ "is explicitly seeded before generating random number"106+ ". Generated random numbers should be different.");107check(orig, copy, false, mech);108109// Serialize after explicit seed but original is explicitly110// seeded again before generating random number. Then compare111// generated random numbers produced through original and112// serialized instances.113orig = getSRInstance(mech);114orig.setSeed(SEED); // Explicitly seeded115copy = deserializedCopy(orig);116orig.setSeed(SEED); // Explicitly seeded117System.out.printf("%nSerialize after explicit seed but "118+ "original is explicitly seeded again before "119+ "generating random number. Generated random "120+ "numbers should be different.");121check(orig, copy, false, mech);122123} catch (Exception e) {124e.printStackTrace(System.out);125success = false;126} finally {127Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE);128}129System.out.printf("%n------Completed Test for %s------", mech);130}131132if (!success) {133throw new RuntimeException("At least one test failed.");134}135}136137/**138* Find if the mechanism is a DRBG mechanism.139* @param mech Mechanism name140* @return True for DRBG mechanism else False141*/142private static boolean isDRBG(String mech) {143return mech.contains("_DRBG");144}145146/**147* Verify the similarity of random numbers generated though both original148* as well as deserialized instance.149*/150private static void check(SecureRandom orig, SecureRandom copy,151boolean equal, String mech) {152int o = orig.nextInt();153int c = copy.nextInt();154System.out.printf("%nRandom number generated for mechanism: '%s' "155+ "from original instance as: '%s' and from serialized "156+ "instance as: '%s'", mech, o, c);157if (equal) {158Asserts.assertEquals(o, c, mech);159} else {160Asserts.assertNotEquals(o, c, mech);161}162}163164/**165* Get a copy of SecureRandom instance through deserialization.166* @param orig Original SecureRandom instance167* @return Deserialized SecureRandom instance168* @throws IOException169* @throws ClassNotFoundException170*/171private static SecureRandom deserializedCopy(SecureRandom orig)172throws IOException, ClassNotFoundException {173return deserialize(serialize(orig));174}175176/**177* Deserialize the SecureRandom object.178*/179private static SecureRandom deserialize(byte[] serialized)180throws IOException, ClassNotFoundException {181SecureRandom sr = null;182try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized);183ObjectInputStream ois = new ObjectInputStream(bis)) {184sr = (SecureRandom) ois.readObject();185}186return sr;187}188189/**190* Serialize the given SecureRandom object.191*/192private static byte[] serialize(SecureRandom sr) throws IOException {193try (ByteArrayOutputStream bos = new ByteArrayOutputStream();194ObjectOutputStream oos = new ObjectOutputStream(bos)) {195oos.writeObject(sr);196return bos.toByteArray();197}198}199200/**201* Create a SecureRandom instance for a given mechanism.202*/203private static SecureRandom getSRInstance(String mech)204throws NoSuchAlgorithmException {205if (!isDRBG(mech)) {206return SecureRandom.getInstance(mech);207} else {208Security.setProperty(DRBG_CONFIG, mech);209return SecureRandom.getInstance("DRBG");210}211}212213}214215216