8202608: CommonSeeder test needs a white-box testing mechanism to replace the default entropy source
Reviewed-by: xuelei
This commit is contained in:
parent
3e7196c114
commit
3ad65642c8
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2018, 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
|
||||
@ -516,7 +516,7 @@ public abstract class AbstractDrbg {
|
||||
* This object uses {@link SeedGenerator#generateSeed(byte[])} to
|
||||
* return a byte array containing {@code minLength} bytes. It is
|
||||
* assumed to support prediction resistance and always contains
|
||||
* full-entropy. A trusted application can update this field.
|
||||
* full-entropy.
|
||||
*/
|
||||
private final static EntropySource defaultES =
|
||||
(minE, minLen, maxLen, pr) -> {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2018, 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
|
||||
@ -21,70 +21,39 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import sun.security.provider.AbstractDrbg;
|
||||
import sun.security.provider.EntropySource;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.DrbgParameters;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
|
||||
import sun.security.provider.SeedGenerator;
|
||||
/**
|
||||
* @test
|
||||
* @bug 8051408
|
||||
* @modules java.base/java.lang.reflect:open
|
||||
* java.base/sun.security.provider:+open
|
||||
* @bug 8051408 8202608
|
||||
* @modules java.base/sun.security.provider
|
||||
* @build java.base/sun.security.provider.SeedGenerator
|
||||
* @run main/othervm CommonSeeder
|
||||
* @summary check entropy reading of DRBGs
|
||||
*/
|
||||
public class CommonSeeder {
|
||||
|
||||
static class MyES implements EntropySource {
|
||||
int count = 100;
|
||||
int lastCount = 100;
|
||||
|
||||
@Override
|
||||
public byte[] getEntropy(int minEntropy, int minLength,
|
||||
int maxLength, boolean pr) {
|
||||
count--;
|
||||
return new byte[minLength];
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms genEntropy() has been called {@code less} times
|
||||
* since last check.
|
||||
*/
|
||||
public void checkUsage(int less) throws Exception {
|
||||
if (lastCount != count + less) {
|
||||
throw new Exception(String.format(
|
||||
"lastCount = %d, count = %d, less = %d",
|
||||
lastCount, count, less));
|
||||
}
|
||||
lastCount = count;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
byte[] result = new byte[10];
|
||||
MyES es = new MyES();
|
||||
|
||||
// Set es as the default entropy source, overriding SeedGenerator.
|
||||
setDefaultSeeder(es);
|
||||
// Use patched SeedGenerator in java.base/sun/security/provider/.
|
||||
|
||||
// Nothing happened yet
|
||||
es.checkUsage(0);
|
||||
SeedGenerator.checkUsage(0);
|
||||
|
||||
SecureRandom sr;
|
||||
sr = SecureRandom.getInstance("DRBG");
|
||||
|
||||
// No entropy reading if only getInstance
|
||||
es.checkUsage(0);
|
||||
SeedGenerator.checkUsage(0);
|
||||
|
||||
// Entropy is read at 1st nextBytes of the 1st DRBG
|
||||
sr.nextInt();
|
||||
es.checkUsage(1);
|
||||
SeedGenerator.checkUsage(1);
|
||||
|
||||
for (String mech : new String[]{"Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) {
|
||||
System.out.println("Testing " + mech + "...");
|
||||
@ -96,7 +65,7 @@ public class CommonSeeder {
|
||||
sr = SecureRandom.getInstance("DRBG");
|
||||
sr.nextInt();
|
||||
sr.reseed();
|
||||
es.checkUsage(0);
|
||||
SeedGenerator.checkUsage(0);
|
||||
|
||||
// DRBG with pr_true always read from default entropy, and
|
||||
// its nextBytes always reseed itself
|
||||
@ -106,28 +75,19 @@ public class CommonSeeder {
|
||||
sr = SecureRandom.getInstance("DRBG");
|
||||
|
||||
sr.nextInt();
|
||||
es.checkUsage(2); // one instantiate, one reseed
|
||||
SeedGenerator.checkUsage(2); // one instantiate, one reseed
|
||||
sr.nextInt();
|
||||
es.checkUsage(1); // one reseed in nextBytes
|
||||
SeedGenerator.checkUsage(1); // one reseed in nextBytes
|
||||
sr.reseed();
|
||||
es.checkUsage(1); // one reseed
|
||||
SeedGenerator.checkUsage(1); // one reseed
|
||||
sr.nextBytes(result, DrbgParameters.nextBytes(-1, false, null));
|
||||
es.checkUsage(0); // pr_false for this call
|
||||
SeedGenerator.checkUsage(0); // pr_false for this call
|
||||
sr.nextBytes(result, DrbgParameters.nextBytes(-1, true, null));
|
||||
es.checkUsage(1); // pr_true for this call
|
||||
SeedGenerator.checkUsage(1); // pr_true for this call
|
||||
sr.reseed(DrbgParameters.reseed(true, null));
|
||||
es.checkUsage(1); // reseed from es
|
||||
SeedGenerator.checkUsage(1); // reseed from es
|
||||
sr.reseed(DrbgParameters.reseed(false, null));
|
||||
es.checkUsage(0); // reseed from AbstractDrbg.SeederHolder.seeder
|
||||
SeedGenerator.checkUsage(0); // reseed from AbstractDrbg.SeederHolder.seeder
|
||||
}
|
||||
}
|
||||
|
||||
static void setDefaultSeeder(EntropySource es) throws Exception {
|
||||
Field f = AbstractDrbg.class.getDeclaredField("defaultES");
|
||||
f.setAccessible(true); // no more private
|
||||
Field f2 = Field.class.getDeclaredField("modifiers");
|
||||
f2.setAccessible(true);
|
||||
f2.setInt(f, f2.getInt(f) - Modifier.FINAL); // no more final
|
||||
f.set(null, es);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*/
|
||||
|
||||
// This is not the real sun.security.provider.SeedGenerator class. Used by
|
||||
// ../../../../CommonSeeder.java only.
|
||||
package sun.security.provider;
|
||||
|
||||
public class SeedGenerator {
|
||||
|
||||
static int count = 100;
|
||||
static int lastCount = 100;
|
||||
|
||||
public static void generateSeed(byte[] result) {
|
||||
count--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms genEntropy() has been called {@code less} times
|
||||
* since last check.
|
||||
*/
|
||||
public static void checkUsage(int less) throws Exception {
|
||||
if (lastCount != count + less) {
|
||||
throw new Exception(String.format(
|
||||
"lastCount = %d, count = %d, less = %d",
|
||||
lastCount, count, less));
|
||||
}
|
||||
lastCount = count;
|
||||
}
|
||||
|
||||
// Needed by AbstractDrbg.java
|
||||
static byte[] getSystemEntropy() {
|
||||
return new byte[20];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user