8210476: sun/security/mscapi/PrngSlow.java fails with Still too slow
Reviewed-by: xuelei, igerasim, rriggs
This commit is contained in:
parent
86a41aa926
commit
3254283f79
@ -25,6 +25,7 @@
|
||||
|
||||
package sun.security.mscapi;
|
||||
|
||||
import java.lang.ref.Cleaner;
|
||||
import java.security.ProviderException;
|
||||
import java.security.SecureRandomSpi;
|
||||
|
||||
@ -43,12 +44,31 @@ public final class PRNG extends SecureRandomSpi
|
||||
* The CryptGenRandom function fills a buffer with cryptographically random
|
||||
* bytes.
|
||||
*/
|
||||
private static native byte[] generateSeed(int length, byte[] seed);
|
||||
private static native byte[] generateSeed(long ctxt, int length, byte[] seed);
|
||||
private static native long getContext();
|
||||
private static native void releaseContext(long ctxt);
|
||||
private static final Cleaner CLEANER = Cleaner.create();
|
||||
|
||||
private transient long ctxt;
|
||||
|
||||
private static class State implements Runnable {
|
||||
private final long ctxt;
|
||||
|
||||
State(long ctxt) {
|
||||
this.ctxt = ctxt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
releaseContext(ctxt);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a random number generator.
|
||||
*/
|
||||
public PRNG() {
|
||||
ctxt = getContext();
|
||||
CLEANER.register(this, new State(ctxt));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,9 +79,9 @@ public final class PRNG extends SecureRandomSpi
|
||||
* @param seed the seed.
|
||||
*/
|
||||
@Override
|
||||
protected void engineSetSeed(byte[] seed) {
|
||||
protected synchronized void engineSetSeed(byte[] seed) {
|
||||
if (seed != null) {
|
||||
generateSeed(-1, seed);
|
||||
generateSeed(ctxt, -1, seed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,9 +91,9 @@ public final class PRNG extends SecureRandomSpi
|
||||
* @param bytes the array to be filled in with random bytes.
|
||||
*/
|
||||
@Override
|
||||
protected void engineNextBytes(byte[] bytes) {
|
||||
protected synchronized void engineNextBytes(byte[] bytes) {
|
||||
if (bytes != null) {
|
||||
if (generateSeed(0, bytes) == null) {
|
||||
if (generateSeed(ctxt, 0, bytes) == null) {
|
||||
throw new ProviderException("Error generating random bytes");
|
||||
}
|
||||
}
|
||||
@ -88,12 +108,20 @@ public final class PRNG extends SecureRandomSpi
|
||||
* @return the seed bytes.
|
||||
*/
|
||||
@Override
|
||||
protected byte[] engineGenerateSeed(int numBytes) {
|
||||
byte[] seed = generateSeed(numBytes, null);
|
||||
protected synchronized byte[] engineGenerateSeed(int numBytes) {
|
||||
byte[] seed = generateSeed(ctxt, numBytes, null);
|
||||
|
||||
if (seed == null) {
|
||||
throw new ProviderException("Error generating seed bytes");
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
ctxt = getContext();
|
||||
CLEANER.register(this, new State(ctxt));
|
||||
}
|
||||
}
|
||||
|
@ -240,34 +240,56 @@ bool GetCertificateChain(LPSTR lpszKeyUsageIdentifier, PCCERT_CONTEXT pCertConte
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
/*
|
||||
* Class: sun_security_mscapi_PRNG
|
||||
* Method: getContext
|
||||
* Signature: ()J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_sun_security_mscapi_PRNG_getContext
|
||||
(JNIEnv *env, jclass clazz) {
|
||||
HCRYPTPROV hCryptProv = NULL;
|
||||
if(::CryptAcquireContext(
|
||||
&hCryptProv,
|
||||
NULL,
|
||||
NULL,
|
||||
PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT) == FALSE)
|
||||
{
|
||||
ThrowException(env, PROVIDER_EXCEPTION, GetLastError());
|
||||
}
|
||||
return hCryptProv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_security_mscapi_PRNG
|
||||
* Method: releaseContext
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_security_mscapi_PRNG_releaseContext
|
||||
(JNIEnv *env, jclass clazz, jlong ctxt) {
|
||||
if (ctxt) {
|
||||
::CryptReleaseContext((HCRYPTPROV)ctxt, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_security_mscapi_PRNG
|
||||
* Method: generateSeed
|
||||
* Signature: (I[B)[B
|
||||
* Signature: (JI[B)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed
|
||||
(JNIEnv *env, jclass clazz, jint length, jbyteArray seed)
|
||||
(JNIEnv *env, jclass clazz, jlong ctxt, jint length, jbyteArray seed)
|
||||
{
|
||||
|
||||
HCRYPTPROV hCryptProv = NULL;
|
||||
HCRYPTPROV hCryptProv = (HCRYPTPROV)ctxt;
|
||||
jbyte* reseedBytes = NULL;
|
||||
jbyte* seedBytes = NULL;
|
||||
jbyteArray result = NULL;
|
||||
|
||||
__try
|
||||
{
|
||||
// Acquire a CSP context.
|
||||
if(::CryptAcquireContext(
|
||||
&hCryptProv,
|
||||
NULL,
|
||||
NULL,
|
||||
PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT) == FALSE)
|
||||
{
|
||||
ThrowException(env, PROVIDER_EXCEPTION, GetLastError());
|
||||
__leave;
|
||||
}
|
||||
|
||||
/*
|
||||
* If length is negative then use the supplied seed to re-seed the
|
||||
* generator and return null.
|
||||
@ -330,9 +352,6 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed
|
||||
|
||||
if (seedBytes)
|
||||
env->ReleaseByteArrayElements(seed, seedBytes, 0); // update orig
|
||||
|
||||
if (hCryptProv)
|
||||
::CryptReleaseContext(hCryptProv, 0);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
49
test/jdk/sun/security/mscapi/PrngSerialize.java
Normal file
49
test/jdk/sun/security/mscapi/PrngSerialize.java
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8210476
|
||||
* @requires os.family == "windows"
|
||||
* @summary MSCAPI's PRNG should support serialization
|
||||
* @library /test/lib
|
||||
* @run main PrngSerialize
|
||||
*/
|
||||
|
||||
import jdk.test.lib.util.SerializationUtils;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class PrngSerialize {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SecureRandom sr = SecureRandom.getInstance("Windows-PRNG", "SunMSCAPI");
|
||||
sr = (SecureRandom) SerializationUtils.deserialize(SerializationUtils.serialize(sr));
|
||||
|
||||
// This line is likely to release the context in the original sr.
|
||||
System.gc();
|
||||
|
||||
// Make sure the new object is still useable.
|
||||
sr.nextInt();
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 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
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6449335
|
||||
* @bug 6449335 8210476
|
||||
* @requires os.family == "windows"
|
||||
* @summary MSCAPI's PRNG is too slow
|
||||
* @key randomness
|
||||
@ -44,7 +44,7 @@ public class PrngSlow {
|
||||
};
|
||||
t = (System.nanoTime() - start) / 1000000000.0;
|
||||
System.err.println("\nSpend " + t + " seconds");
|
||||
if (t > 5)
|
||||
if (t > 0.5)
|
||||
throw new RuntimeException("Still too slow");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user