Repository: commons-crypto Updated Branches: refs/heads/master fc1d482bd -> 34df73069
CRYPTO-96: OpenSSL Random implementation silently falls back to Java Fixes #66 Project: http://git-wip-us.apache.org/repos/asf/commons-crypto/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-crypto/commit/34df7306 Tree: http://git-wip-us.apache.org/repos/asf/commons-crypto/tree/34df7306 Diff: http://git-wip-us.apache.org/repos/asf/commons-crypto/diff/34df7306 Branch: refs/heads/master Commit: 34df73069203e8647375e072b99c9538904a0e86 Parents: fc1d482 Author: Sun Dapeng <[email protected]> Authored: Thu Jul 7 14:37:20 2016 +0800 Committer: Sun Dapeng <[email protected]> Committed: Thu Jul 7 14:54:13 2016 +0800 ---------------------------------------------------------------------- .../crypto/random/OpenSslCryptoRandom.java | 54 +++++++++++--------- .../crypto/random/CryptoRandomFactoryTest.java | 2 +- 2 files changed, 32 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/34df7306/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java index 8368ef7..e7f026f 100644 --- a/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java +++ b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java @@ -17,7 +17,7 @@ */ package org.apache.commons.crypto.random; -import java.security.NoSuchAlgorithmException; +import java.security.GeneralSecurityException; import java.util.Properties; import java.util.Random; @@ -44,46 +44,55 @@ import org.apache.commons.crypto.utils.Utils; class OpenSslCryptoRandom extends Random implements CryptoRandom { private static final long serialVersionUID = -7828193502768789584L; - /** If native SecureRandom unavailable, use java SecureRandom */ - private final JavaCryptoRandom fallback; private static final boolean nativeEnabled; + private static final Exception initException; + static { boolean opensslLoaded = false; + Exception except = null; if (Crypto.isNativeCodeLoaded()) { try { OpenSslCryptoRandomNative.initSR(); opensslLoaded = true; - } catch (Exception t) {// NOPMD + } catch (Exception t) { + except = t; } } nativeEnabled = opensslLoaded; + initException = except; } /** - * Judges whether loading native library successfully. + * Judges whether native library was successfully loaded and initialised. * - * @return true if loading library successfully. + * @return true if library was loaded and initialised */ - public static boolean isNativeCodeLoaded() { + public static boolean isNativeCodeEnabled() { return nativeEnabled; } /** * Constructs a {@link OpenSslCryptoRandom}. * - * @param props the configuration properties - * Only used to construct the fallback {@link JavaCryptoRandom} instance - * @throws NoSuchAlgorithmException if no Provider supports a - * SecureRandomSpi implementation for the specified algorithm. + * @param props the configuration properties - not used + * @throws GeneralSecurityException if the native library could not be initialised successfully */ // N.B. this class is not public/protected so does not appear in the main Javadoc // Please ensure that property use is documented in the enum CryptoRandomFactory.RandomProvider - public OpenSslCryptoRandom(Properties props) - throws NoSuchAlgorithmException { - //fallback needs to be initialized here in any case cause even if - //nativeEnabled is true OpenSslCryptoRandomNative.nextRandBytes may fail - fallback = new JavaCryptoRandom(props); + public OpenSslCryptoRandom(Properties props) throws GeneralSecurityException { + if (!nativeEnabled) { + if (initException != null) { + throw new GeneralSecurityException("Native library could not be initialised", initException); + } else { + throw new GeneralSecurityException("Native library is not loaded"); + } + } else { + // Check that nextRandBytes works (is this really needed?) + if (!OpenSslCryptoRandomNative.nextRandBytes(new byte[1])) { + throw new GeneralSecurityException("Check of nextRandBytes failed"); + } + } } /** @@ -93,8 +102,10 @@ class OpenSslCryptoRandom extends Random implements CryptoRandom { */ @Override public void nextBytes(byte[] bytes) { - if (!nativeEnabled || !OpenSslCryptoRandomNative.nextRandBytes(bytes)) { - fallback.nextBytes(bytes); + // Constructor ensures that native is enabled here + if (!OpenSslCryptoRandomNative.nextRandBytes(bytes)) { + // Assume it's a problem with the argument, rather than an internal issue + throw new IllegalArgumentException("The nextRandBytes method failed"); } } @@ -135,13 +146,10 @@ class OpenSslCryptoRandom extends Random implements CryptoRandom { } /** - * Overrides {@link java.lang.AutoCloseable#close()}. Closes OpenSSL context - * if native enabled. + * Overrides {@link java.lang.AutoCloseable#close()}. + * Does nothing. */ @Override public void close() { - if (fallback != null) { - fallback.close(); - } } } http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/34df7306/src/test/java/org/apache/commons/crypto/random/CryptoRandomFactoryTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/random/CryptoRandomFactoryTest.java b/src/test/java/org/apache/commons/crypto/random/CryptoRandomFactoryTest.java index 3f33519..2f78347 100644 --- a/src/test/java/org/apache/commons/crypto/random/CryptoRandomFactoryTest.java +++ b/src/test/java/org/apache/commons/crypto/random/CryptoRandomFactoryTest.java @@ -44,7 +44,7 @@ public class CryptoRandomFactoryTest { Properties props = new Properties(); CryptoRandom random = CryptoRandomFactory.getCryptoRandom(props); final String name = random.getClass().getName(); - if (OpenSslCryptoRandom.isNativeCodeLoaded()) { + if (OpenSslCryptoRandom.isNativeCodeEnabled()) { Assert.assertEquals(OpenSslCryptoRandom.class.getName(), name); } else { Assert.assertEquals(JavaCryptoRandom.class.getName(), name);
