From 7687ea60d46816c65832d061780fb5b02e5e4d7a Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Sat, 7 Sep 2013 18:02:08 +0100 Subject: Do not apply the PRNG workarounds if an explicit seed is given If the caller seeds the engine, do NOT override that seed with another from urandom. This is a companion change to Ib6bf4478fc1ae3d16eefa4eb2ad90f1f3e9de021, and should be reverted along with it when the proper fix appears. Change-Id: I0a9ba35d74af89c91b6aafa35cc94001372794e1 --- .../provider/crypto/SHA1PRNG_SecureRandomImpl.java | 31 +++++++++++++--------- .../harmony/xnet/provider/jsse/OpenSSLRandom.java | 18 ++++++++++--- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java index de6d853..d4c2d1d 100644 --- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java +++ b/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java @@ -103,8 +103,8 @@ class LinuxPRNGSecureRandom extends SecureRandomSpi { throw new SecurityException("Failed to generate seed", e); } } - @Override - protected void engineSetSeed(byte[] bytes) { + + protected void internalEngineSetSeed(byte[] bytes) { try { OutputStream out; synchronized (sLock) { @@ -120,10 +120,15 @@ class LinuxPRNGSecureRandom extends SecureRandomSpi { } @Override + protected void engineSetSeed(byte[] bytes) { + internalEngineSetSeed(bytes); + } + + @Override protected void engineNextBytes(byte[] bytes) { if (!mSeeded) { // Mix in the invocation-specific seed. - engineSetSeed(generateSeed()); + internalEngineSetSeed(generateSeed()); } try { @@ -365,8 +370,6 @@ public class SHA1PRNG_SecureRandomImpl extends LinuxPRNGSecureRandom implements * NullPointerException - if null is passed to the "seed" argument */ - /* Blocked while LinuxPRNGSecureRandom is in use - protected synchronized void engineSetSeed(byte[] seed) { if (seed == null) { @@ -384,8 +387,6 @@ public class SHA1PRNG_SecureRandomImpl extends LinuxPRNGSecureRandom implements } } - */ - /** * Returns a required number of random bytes.
* @@ -399,9 +400,13 @@ public class SHA1PRNG_SecureRandomImpl extends LinuxPRNGSecureRandom implements * InvalidParameterException - if numBytes < 0 */ - /* Blocked while LinuxPRNGSecureRandom is in use protected synchronized byte[] engineGenerateSeed(int numBytes) { + /* Unseeded by user, fallback to the LinuxPRNGSecureRandom */ + if (state == UNDEFINED) { + return super.engineGenerateSeed(numBytes); + } + byte[] myBytes; // byte[] for bytes returned by "nextBytes()" if (numBytes < 0) { @@ -422,8 +427,6 @@ public class SHA1PRNG_SecureRandomImpl extends LinuxPRNGSecureRandom implements return myBytes; } - */ - /** * Writes random bytes into an array supplied. * Bits in a byte are from left to right.
@@ -441,9 +444,14 @@ public class SHA1PRNG_SecureRandomImpl extends LinuxPRNGSecureRandom implements * NullPointerException - if null is passed to the "bytes" argument */ - /* Blocked while LinuxPRNGSecureRandom is in use protected synchronized void engineNextBytes(byte[] bytes) { + /* Unseeded by user, fallback to the LinuxPRNGSecureRandom */ + if (state == UNDEFINED) { + super.engineNextBytes(bytes); + return; + } + int i, n; long bits; // number of bits required by Secure Hash Standard @@ -579,7 +587,6 @@ public class SHA1PRNG_SecureRandomImpl extends LinuxPRNGSecureRandom implements } } } - */ private void writeObject(ObjectOutputStream oos) throws IOException { diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRandom.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRandom.java index 28b8c02..e9cbc13 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRandom.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRandom.java @@ -26,11 +26,19 @@ import java.io.IOException; public class OpenSSLRandom extends SecureRandomSpi implements Serializable { private static final long serialVersionUID = 8506210602917522860L; + private transient int state; + private static final int UNSEEDED = 0; + private static final int SEEDED = 1; + + public OpenSSLRandom() { + state = UNSEEDED; + } + /** * Generates a invocation-specific seed to be mixed into the * Linux PRNG. */ - private static void generateSeed() { + private void generateSeed() { try { ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream(); DataOutputStream seedBufferOut = @@ -40,6 +48,7 @@ public class OpenSSLRandom extends SecureRandomSpi implements Serializable { seedBufferOut.close(); NativeCrypto.RAND_seed(seedBuffer.toByteArray()); NativeCrypto.RAND_load_file("/dev/urandom", 1024); + state = SEEDED; } catch (IOException e) { throw new SecurityException("Failed to generate seed", e); } @@ -48,18 +57,21 @@ public class OpenSSLRandom extends SecureRandomSpi implements Serializable { @Override protected void engineSetSeed(byte[] seed) { NativeCrypto.RAND_seed(seed); + state = SEEDED; } @Override protected void engineNextBytes(byte[] bytes) { - generateSeed(); + if (state == UNSEEDED) + generateSeed(); NativeCrypto.RAND_bytes(bytes); } @Override protected byte[] engineGenerateSeed(int numBytes) { byte[] output = new byte[numBytes]; - generateSeed(); + if (state == UNSEEDED) + generateSeed(); NativeCrypto.RAND_bytes(output); return output; } -- cgit v1.1