diff --git a/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java b/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java index 8106ceaf644..ca2119ca7f9 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java @@ -33,12 +33,13 @@ import java.util.Objects; import static java.security.DrbgParameters.Capability.*; /** - * The abstract base class for all DRBGs. + * The abstract base class for all DRBGs. It is used as {@link DRBG#impl}. *

- * This class creates 5 new abstract methods. 3 are defined by the SP800-90A: + * This class has 5 abstract methods. 3 are defined by SP800-90A: *

    *
  1. {@link #generateAlgorithm(byte[], byte[])} - *
  2. {@link #reseedAlgorithm(byte[], byte[])} (might not be supported) + *
  3. {@link #reseedAlgorithm(byte[], byte[])} (In fact this is not an + * abstract method, but any DRBG supporting reseeding must override it.) *
  4. {@link #instantiateAlgorithm(byte[])} *
* and 2 for implementation purpose: @@ -46,18 +47,19 @@ import static java.security.DrbgParameters.Capability.*; *
  • {@link #initEngine()} *
  • {@link #chooseAlgorithmAndStrength} * - * All existing {@link SecureRandomSpi} methods are implemented based on the - * methods above as final. The initialization process is divided into 2 phases: - * configuration is eagerly called to set up parameters, and instantiation - * is lazily called only when nextBytes or reseed is called. + * Although this class is not a child class of {@link SecureRandomSpi}, it + * implements all abstract methods there as final. + *

    + * The initialization process of a DRBG is divided into 2 phases: + * {@link #configure configuration} is eagerly called to set up parameters, + * and {@link #instantiateIfNecessary instantiation} is lazily called only + * when nextBytes or reseed is called. *

    * SecureRandom methods like reseed and nextBytes are not thread-safe. * An implementation is required to protect shared access to instantiate states - * (instantiated, nonce) and DRBG states (v, c, key, reseedCounter). + * (instantiated, nonce) and DRBG states (v, c, key, reseedCounter, etc). */ -public abstract class AbstractDrbg extends SecureRandomSpi { - - private static final long serialVersionUID = 9L; +public abstract class AbstractDrbg { /** * This field is not null if {@code -Djava.security.debug=securerandom} is @@ -69,7 +71,7 @@ public abstract class AbstractDrbg extends SecureRandomSpi { // Common working status - private transient boolean instantiated = false; + private boolean instantiated = false; /** * Reseed counter of a DRBG instance. A mechanism should increment it @@ -78,7 +80,7 @@ public abstract class AbstractDrbg extends SecureRandomSpi { * * Volatile, will be used in a double checked locking. */ - protected transient volatile int reseedCounter = 0; + protected volatile int reseedCounter = 0; // Mech features. If not same as below, must be redefined in constructor. @@ -170,7 +172,7 @@ public abstract class AbstractDrbg extends SecureRandomSpi { /** * Algorithm used by this instance (SHA-512 or AES-256). Must be assigned * in {@link #chooseAlgorithmAndStrength}. This field is used in - * {@link #toString()} and {@link DRBG#algorithmName}. + * {@link #toString()}. */ protected String algorithm; @@ -217,7 +219,7 @@ public abstract class AbstractDrbg extends SecureRandomSpi { * After instantiation, this field is not null. Do not modify it * in a mechanism. */ - protected transient byte[] nonce; + protected byte[] nonce; /** * Requested nonce in {@link MoreDrbgParameters}. If set to null, @@ -237,7 +239,7 @@ public abstract class AbstractDrbg extends SecureRandomSpi { * {@link #configure(SecureRandomParameters)}. This field * can be null. {@link #getEntropyInput} will take care of null check. */ - private transient EntropySource es; + private EntropySource es; // Five abstract methods for SP 800-90A DRBG @@ -286,10 +288,7 @@ public abstract class AbstractDrbg extends SecureRandomSpi { /** * Initiates security engines ({@code MessageDigest}, {@code Mac}, - * or {@code Cipher}). Must be called in deserialization. Please note - * that before instantiation the algorithm might not be available yet. - * In this case, just return and this method will be called - * automatically at instantiation. + * or {@code Cipher}). This method is called during instantiation. */ protected abstract void initEngine(); @@ -331,13 +330,11 @@ public abstract class AbstractDrbg extends SecureRandomSpi { // SecureRandomSpi methods taken care of here. All final. - @Override protected final void engineNextBytes(byte[] result) { engineNextBytes(result, DrbgParameters.nextBytes( -1, predictionResistanceFlag, null)); } - @Override protected final void engineNextBytes( byte[] result, SecureRandomParameters params) { @@ -402,7 +399,6 @@ public abstract class AbstractDrbg extends SecureRandomSpi { } } - @Override public final void engineReseed(SecureRandomParameters params) { if (debug != null) { debug.println(this, "reseed with params"); @@ -454,7 +450,6 @@ public abstract class AbstractDrbg extends SecureRandomSpi { * @param numBytes the number of seed bytes to generate. * @return the seed bytes. */ - @Override public final byte[] engineGenerateSeed(int numBytes) { byte[] b = new byte[numBytes]; SeedGenerator.generateSeed(b); @@ -469,7 +464,6 @@ public abstract class AbstractDrbg extends SecureRandomSpi { * * @param input the seed */ - @Override public final synchronized void engineSetSeed(byte[] input) { if (debug != null) { debug.println(this, "setSeed"); @@ -598,7 +592,6 @@ public abstract class AbstractDrbg extends SecureRandomSpi { * * @return the curent configuration */ - @Override protected SecureRandomParameters engineGetParameters() { // Or read from variable. return DrbgParameters.instantiation( @@ -631,7 +624,8 @@ public abstract class AbstractDrbg extends SecureRandomSpi { this.es = m.es; this.requestedAlgorithm = m.algorithm; this.usedf = m.usedf; - params = m.config; + params = DrbgParameters.instantiation(m.strength, + m.capability, m.personalizationString); } if (params != null) { if (params instanceof DrbgParameters.Instantiation) { diff --git a/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java b/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java index 73d40b777da..e49f1349bf8 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java @@ -32,8 +32,6 @@ import java.util.Locale; public abstract class AbstractHashDrbg extends AbstractDrbg { - private static final long serialVersionUID = 9L; - protected int outLen; protected int seedLen; diff --git a/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java b/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java index 1d234172c95..683f5941c45 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java @@ -28,14 +28,12 @@ package sun.security.provider; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; -import java.io.IOException; import java.security.*; import java.util.Arrays; import java.util.Locale; public class CtrDrbg extends AbstractDrbg { - private static final long serialVersionUID = 9L; private static final int AES_LIMIT; static { @@ -47,7 +45,7 @@ public class CtrDrbg extends AbstractDrbg { } } - private transient Cipher cipher; + private Cipher cipher; private String cipherAlg; private String keyAlg; @@ -57,8 +55,8 @@ public class CtrDrbg extends AbstractDrbg { private int keyLen; private int seedLen; - private transient byte[] v; - private transient byte[] k; + private byte[] v; + private byte[] k; public CtrDrbg(SecureRandomParameters params) { mechName = "CTR_DRBG"; @@ -165,7 +163,7 @@ public class CtrDrbg extends AbstractDrbg { protected void initEngine() { try { /* - * Use the local SUN implementation to avoid native + * Use the local SunJCE implementation to avoid native * performance overhead. */ cipher = Cipher.getInstance(cipherAlg, "SunJCE"); @@ -463,12 +461,6 @@ public class CtrDrbg extends AbstractDrbg { // Step 8. Return } - private void readObject(java.io.ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject (); - initEngine(); - } - @Override public String toString() { return super.toString() + "," diff --git a/jdk/src/java.base/share/classes/sun/security/provider/DRBG.java b/jdk/src/java.base/share/classes/sun/security/provider/DRBG.java index b5fa3c4c4d2..47d0f5cac06 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/DRBG.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/DRBG.java @@ -25,6 +25,7 @@ package sun.security.provider; +import java.io.IOException; import java.security.AccessController; import java.security.DrbgParameters; import java.security.PrivilegedAction; @@ -61,11 +62,12 @@ public final class DRBG extends SecureRandomSpi { private static final long serialVersionUID = 9L; - private final AbstractDrbg impl; + private transient AbstractDrbg impl; - private final String mechName; - - private final String algorithmName; + /** + * @serial + */ + private final MoreDrbgParameters mdp; public DRBG(SecureRandomParameters params) { @@ -91,7 +93,7 @@ public final class DRBG extends SecureRandomSpi { // Can be configured with a security property String config = AccessController.doPrivileged((PrivilegedAction) - () -> Security.getProperty(PROP_NAME)); + () -> Security.getProperty(PROP_NAME)); if (config != null && !config.isEmpty()) { for (String part : config.split(",")) { @@ -151,8 +153,9 @@ public final class DRBG extends SecureRandomSpi { if (params != null) { // MoreDrbgParameters is used for testing. if (params instanceof MoreDrbgParameters) { - MoreDrbgParameters m = (MoreDrbgParameters)params; - params = m.config; + MoreDrbgParameters m = (MoreDrbgParameters) params; + params = DrbgParameters.instantiation(m.strength, + m.capability, m.personalizationString); // No need to check null for es and nonce, they are still null es = m.es; @@ -197,26 +200,27 @@ public final class DRBG extends SecureRandomSpi { usedf = true; } - MoreDrbgParameters m = new MoreDrbgParameters( + mdp = new MoreDrbgParameters( es, mech, algorithm, nonce, usedf, DrbgParameters.instantiation(strength, cap, ps)); - switch (mech.toLowerCase(Locale.ROOT)) { + createImpl(); + } + + private void createImpl() { + switch (mdp.mech.toLowerCase(Locale.ROOT)) { case "hash_drbg": - impl = new HashDrbg(m); + impl = new HashDrbg(mdp); break; case "hmac_drbg": - impl = new HmacDrbg(m); + impl = new HmacDrbg(mdp); break; case "ctr_drbg": - impl = new CtrDrbg(m); + impl = new CtrDrbg(mdp); break; default: - throw new IllegalArgumentException("Unsupported mech: " + mech); + throw new IllegalArgumentException("Unsupported mech: " + mdp.mech); } - - mechName = mech; - algorithmName = impl.algorithm; } @Override @@ -268,4 +272,13 @@ public final class DRBG extends SecureRandomSpi { + " cannot be provided more than once in " + PROP_NAME); } } + + private void readObject(java.io.ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + if (mdp.mech == null) { + throw new IllegalArgumentException("Input data is corrupted"); + } + createImpl(); + } } diff --git a/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java b/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java index e3c676b8979..bf641227e85 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java @@ -25,7 +25,6 @@ package sun.security.provider; -import java.io.IOException; import java.math.BigInteger; import java.security.DigestException; import java.security.MessageDigest; @@ -36,15 +35,13 @@ import java.util.Arrays; public class HashDrbg extends AbstractHashDrbg { - private static final long serialVersionUID = 9L; - private static final byte[] ZERO = new byte[1]; private static final byte[] ONE = new byte[]{1}; - private transient MessageDigest digest; + private MessageDigest digest; - private transient byte[] v; - private transient byte[] c; + private byte[] v; + private byte[] c; public HashDrbg(SecureRandomParameters params) { mechName = "Hash_DRBG"; @@ -267,10 +264,4 @@ public class HashDrbg extends AbstractHashDrbg { // Step 5: No need to truncate // Step 6: Return } - - private void readObject(java.io.ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject (); - initEngine(); - } } diff --git a/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java b/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java index 1ee07b02fee..40b43b00e6f 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java @@ -27,7 +27,6 @@ package sun.security.provider; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; @@ -36,14 +35,12 @@ import java.util.Arrays; public class HmacDrbg extends AbstractHashDrbg { - private static final long serialVersionUID = 9L; - - private transient Mac mac; + private Mac mac; private String macAlg; - private transient byte[] v; - private transient byte[] k; + private byte[] v; + private byte[] k; public HmacDrbg(SecureRandomParameters params) { mechName = "HMAC_DRBG"; @@ -101,6 +98,10 @@ public class HmacDrbg extends AbstractHashDrbg { protected void initEngine() { macAlg = "HmacSHA" + algorithm.substring(4); try { + /* + * Use the local SunJCE implementation to avoid native + * performance overhead. + */ mac = Mac.getInstance(macAlg, "SunJCE"); } catch (NoSuchProviderException | NoSuchAlgorithmException e) { // Fallback to any available. @@ -194,10 +195,4 @@ public class HmacDrbg extends AbstractHashDrbg { // Step 8. Return } - - private void readObject(java.io.ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject (); - initEngine(); - } } diff --git a/jdk/src/java.base/share/classes/sun/security/provider/MoreDrbgParameters.java b/jdk/src/java.base/share/classes/sun/security/provider/MoreDrbgParameters.java index 7a2e8c75ca6..808909354d7 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/MoreDrbgParameters.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/MoreDrbgParameters.java @@ -25,20 +25,30 @@ package sun.security.provider; +import java.io.IOException; +import java.io.Serializable; import java.security.DrbgParameters; import java.security.SecureRandomParameters; /** - * Extra non-standard parameters that can be used by DRBGs. + * Exported and non-exported parameters that can be used by DRBGs. */ -public class MoreDrbgParameters implements SecureRandomParameters { +public class MoreDrbgParameters implements SecureRandomParameters, Serializable { + + private static final long serialVersionUID = 9L; + + final transient EntropySource es; final String mech; final String algorithm; - final EntropySource es; - final byte[] nonce; final boolean usedf; - final DrbgParameters.Instantiation config; + final int strength; + final DrbgParameters.Capability capability; + + // The following 2 fields will be reassigned in readObject and + // thus cannot be final + byte[] nonce; + byte[] personalizationString; /** * Creates a new {@code MoreDrbgParameters} object. @@ -61,13 +71,31 @@ public class MoreDrbgParameters implements SecureRandomParameters { this.mech = mech; this.algorithm = algorithm; this.es = es; - this.nonce = nonce; + this.nonce = (nonce == null) ? null : nonce.clone(); this.usedf = usedf; - this.config = config; + + this.strength = config.getStrength(); + this.capability = config.getCapability(); + this.personalizationString = config.getPersonalizationString(); } @Override public String toString() { - return mech + "," + algorithm + "," + usedf + "," + config; + return mech + "," + algorithm + "," + usedf + "," + strength + + "," + capability + "," + personalizationString; + } + + private void readObject(java.io.ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + if (nonce != null) { + nonce = nonce.clone(); + } + if (personalizationString != null) { + personalizationString = personalizationString.clone(); + } + if (capability == null) { + throw new IllegalArgumentException("Input data is corrupted"); + } } } diff --git a/jdk/test/sun/security/provider/SecureRandom/AbstractDrbgSpec.java b/jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/SpecTest.java similarity index 77% rename from jdk/test/sun/security/provider/SecureRandom/AbstractDrbgSpec.java rename to jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/SpecTest.java index a0caa26091e..65a876e4a78 100644 --- a/jdk/test/sun/security/provider/SecureRandom/AbstractDrbgSpec.java +++ b/jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/SpecTest.java @@ -22,20 +22,25 @@ */ /* @test - * @bug 8051408 + * @bug 8051408 8157308 * @modules java.base/sun.security.provider + * @build java.base/sun.security.provider.S + * @run main SpecTest * @summary check the AbstractDrbg API etc */ import java.security.*; -import sun.security.provider.AbstractDrbg; +import sun.security.provider.S; import static java.security.DrbgParameters.Capability.*; /** * This test makes sure the AbstractDrbg API works as specified. It also * checks the SecureRandom API. + * + * The implementations must be patched into java.base/sun.security.provider + * because AbstractDrbg is not a public interface. */ -public class AbstractDrbgSpec { +public class SpecTest { public static void main(String args[]) throws Exception { @@ -170,9 +175,9 @@ public class AbstractDrbgSpec { public static class All extends Provider { protected All(String name, double version, String info) { super(name, version, info); - put("SecureRandom.S1", S1.class.getName()); - put("SecureRandom.S2", S2.class.getName()); - put("SecureRandom.S3", S3.class.getName()); + put("SecureRandom.S1", S.S1.class.getName()); + put("SecureRandom.S2", S.S2.class.getName()); + put("SecureRandom.S3", S.S3.class.getName()); } } @@ -180,92 +185,21 @@ public class AbstractDrbgSpec { public static class Legacy extends Provider { protected Legacy(String name, double version, String info) { super(name, version, info); - put("SecureRandom.S", S1.class.getName()); + put("SecureRandom.S", S.S1.class.getName()); } } public static class Weak extends Provider { protected Weak(String name, double version, String info) { super(name, version, info); - put("SecureRandom.S", S2.class.getName()); + put("SecureRandom.S", S.S2.class.getName()); } } public static class Strong extends Provider { protected Strong(String name, double version, String info) { super(name, version, info); - put("SecureRandom.S", S3.class.getName()); - } - } - - // This is not a DRBG. - public static class S1 extends SecureRandomSpi { - @Override - protected void engineSetSeed(byte[] seed) { - } - - @Override - protected void engineNextBytes(byte[] bytes) { - } - - @Override - protected byte[] engineGenerateSeed(int numBytes) { - return new byte[numBytes]; - } - } - - // This is a strong DRBG. - public static class S3 extends AbstractDrbg { - - public S3(SecureRandomParameters params) { - supportPredictionResistance = true; - supportReseeding = true; - highestSupportedSecurityStrength = 192; - mechName = "S3"; - algorithm = "SQUEEZE"; - configure(params); - } - protected void chooseAlgorithmAndStrength() { - if (requestedInstantiationSecurityStrength < 0) { - securityStrength = DEFAULT_STRENGTH; - } else { - securityStrength = requestedInstantiationSecurityStrength; - } - minLength = securityStrength / 8; - maxAdditionalInputLength = maxPersonalizationStringLength = 100; - } - - @Override - protected void initEngine() { - - } - - @Override - protected void instantiateAlgorithm(byte[] ei) { - - } - - @Override - protected void generateAlgorithm(byte[] result, byte[] additionalInput) { - - } - - @Override - protected void reseedAlgorithm(byte[] ei, byte[] additionalInput) { - - } - } - - // This is a weak DRBG. maximum strength is 128 and does - // not support prediction resistance or reseed. - public static class S2 extends S3 { - public S2(SecureRandomParameters params) { - super(null); - mechName = "S2"; - highestSupportedSecurityStrength = 128; - supportPredictionResistance = false; - supportReseeding = false; - configure(params); + put("SecureRandom.S", S.S3.class.getName()); } } diff --git a/jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/java.base/sun/security/provider/S.java b/jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/java.base/sun/security/provider/S.java new file mode 100644 index 00000000000..e9bdd4f530f --- /dev/null +++ b/jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/java.base/sun/security/provider/S.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016, 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. + */ + +package sun.security.provider; + +import java.security.SecureRandomParameters; +import java.security.SecureRandomSpi; + +/** + * Read ../../../../SpecTest.java for details. + */ +public class S extends SecureRandomSpi { + + protected AbstractDrbg impl; + + // This is not a DRBG. + public static class S1 extends SecureRandomSpi { + @Override + protected void engineSetSeed(byte[] seed) { + } + + @Override + protected void engineNextBytes(byte[] bytes) { + } + + @Override + protected byte[] engineGenerateSeed(int numBytes) { + return new byte[numBytes]; + } + } + + // This is a weak DRBG. maximum strength is 128 and does + // not support prediction resistance or reseed. + public static class S2 extends S { + public S2(SecureRandomParameters params) { + impl = new Impl2(params); + } + } + + // This is a strong DRBG. + public static class S3 extends S { + public S3(SecureRandomParameters params) { + impl = new Impl3(params); + } + } + + // AbstractDrbg Implementations + + static class Impl3 extends AbstractDrbg { + + public Impl3(SecureRandomParameters params) { + supportPredictionResistance = true; + supportReseeding = true; + highestSupportedSecurityStrength = 192; + mechName = "S3"; + algorithm = "SQUEEZE"; + configure(params); + } + + protected void chooseAlgorithmAndStrength() { + if (requestedInstantiationSecurityStrength < 0) { + securityStrength = DEFAULT_STRENGTH; + } else { + securityStrength = requestedInstantiationSecurityStrength; + } + minLength = securityStrength / 8; + maxAdditionalInputLength = maxPersonalizationStringLength = 100; + } + + @Override + protected void initEngine() { + } + + @Override + protected void instantiateAlgorithm(byte[] ei) { + } + + @Override + protected void generateAlgorithm(byte[] result, byte[] additionalInput) { + } + + @Override + protected void reseedAlgorithm(byte[] ei, byte[] additionalInput) { + } + } + + static class Impl2 extends Impl3 { + public Impl2(SecureRandomParameters params) { + super(null); + mechName = "S2"; + highestSupportedSecurityStrength = 128; + supportPredictionResistance = false; + supportReseeding = false; + configure(params); + } + } + + // Overridden SecureRandomSpi methods + + @Override + protected void engineSetSeed(byte[] seed) { + impl.engineSetSeed(seed); + } + + @Override + protected void engineNextBytes(byte[] bytes) { + impl.engineNextBytes(bytes); + } + + @Override + protected byte[] engineGenerateSeed(int numBytes) { + return impl.engineGenerateSeed(numBytes); + } + + @Override + protected void engineNextBytes( + byte[] bytes, SecureRandomParameters params) { + impl.engineNextBytes(bytes, params); + } + + @Override + protected void engineReseed(SecureRandomParameters params) { + impl.engineReseed(params); + } + + @Override + protected SecureRandomParameters engineGetParameters() { + return impl.engineGetParameters(); + } + + @Override + public String toString() { + return impl.toString(); + } +} diff --git a/jdk/test/sun/security/provider/SecureRandom/DRBGS11n.java b/jdk/test/sun/security/provider/SecureRandom/DRBGS11n.java new file mode 100644 index 00000000000..aaf005d44bb --- /dev/null +++ b/jdk/test/sun/security/provider/SecureRandom/DRBGS11n.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016, 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. + */ +import sun.security.provider.DRBG; +import sun.security.provider.MoreDrbgParameters; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.Field; + +/** + * @test + * @bug 8157308 + * @modules java.base/sun.security.provider + * @summary Make AbstractDrbg non-Serializable + * @run main DRBGS11n mech + * @run main DRBGS11n capability + */ +public class DRBGS11n { + + public static void main(String[] args) throws Exception { + + DRBG d = new DRBG(null); + Field f = DRBG.class.getDeclaredField("mdp"); + f.setAccessible(true); + MoreDrbgParameters mdp = (MoreDrbgParameters)f.get(d); + + // Corrupt the mech or capability fields inside DRBG#mdp. + f = MoreDrbgParameters.class.getDeclaredField(args[0]); + f.setAccessible(true); + f.set(mdp, null); + + try { + revive(d); + } catch (IllegalArgumentException iae) { + // Expected + return; + } + + throw new Exception("revive should fail"); + } + + static T revive(T in) throws Exception { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + new ObjectOutputStream(bout).writeObject(in); + return (T) new ObjectInputStream( + new ByteArrayInputStream(bout.toByteArray())).readObject(); + } +}