lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kris...@apache.org
Subject [45/50] lucene-solr:jira/solr-8593: SOLR-5776: refactor SSLConfig so that SSLTestConfig can provide SSLContexts using a NullSecureRandom to prevent SSL tests from blocking on entropy starved machines
Date Wed, 04 May 2016 16:17:36 GMT
SOLR-5776: refactor SSLConfig so that SSLTestConfig can provide SSLContexts using a NullSecureRandom
to prevent SSL tests from blocking on entropy starved machines


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/9677e2c5
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/9677e2c5
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/9677e2c5

Branch: refs/heads/jira/solr-8593
Commit: 9677e2c54bbc66283f3f4341a4e1166006069fc3
Parents: 6ef0f21
Author: Chris Hostetter <hossman@apache.org>
Authored: Tue May 3 14:01:23 2016 -0700
Committer: Chris Hostetter <hossman@apache.org>
Committed: Tue May 3 15:31:53 2016 -0700

----------------------------------------------------------------------
 .../solr/client/solrj/embedded/SSLConfig.java   | 71 +++++++++-----
 .../org/apache/solr/util/SSLTestConfig.java     | 99 +++++++++++++++++++-
 2 files changed, 144 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9677e2c5/solr/core/src/java/org/apache/solr/client/solrj/embedded/SSLConfig.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/client/solrj/embedded/SSLConfig.java b/solr/core/src/java/org/apache/solr/client/solrj/embedded/SSLConfig.java
index f777951..60f383c 100644
--- a/solr/core/src/java/org/apache/solr/client/solrj/embedded/SSLConfig.java
+++ b/solr/core/src/java/org/apache/solr/client/solrj/embedded/SSLConfig.java
@@ -77,38 +77,63 @@ public class SSLConfig {
 
   /**
    * Returns an SslContextFactory that should be used by a jetty server based on the specified

-   * configuration, or null if no SSL should be used.
+   * SSLConfig param which may be null.
    *
-   * The specified sslConfig will be completely ignored if the "tests.jettySsl" system property
is 
-   * true - in which case standard "javax.net.ssl.*" system properties will be used instead,
along 
-   * with "tests.jettySsl.clientAuth"
+   * if the SSLConfig param is non-null, then this method will return the results of 
+   * {@link #createContextFactory()}.
    * 
-   * @see #isSSLMode
+   * If the SSLConfig param is null, then this method will return null unless the 
+   * <code>tests.jettySsl</code> system property is true, in which case standard
"javax.net.ssl.*" 
+   * system properties will be used instead, along with "tests.jettySsl.clientAuth".
+   * 
+   * @see #createContextFactory()
    */
   public static SslContextFactory createContextFactory(SSLConfig sslConfig) {
 
-    if (sslConfig == null) {
-      if (Boolean.getBoolean("tests.jettySsl")) {
-        return configureSslFromSysProps();
-      }
-      return null;
+    if (sslConfig != null) {
+      return sslConfig.createContextFactory();
     }
+    // else...
+    if (Boolean.getBoolean("tests.jettySsl")) {
+      return configureSslFromSysProps();
+    }
+    // else...
+    return null;
+  }
+  
+  /**
+   * Returns an SslContextFactory that should be used by a jetty server based on this SSLConfig
instance, 
+   * or null if SSL should not be used.
+   *
+   * The default implementation generates a simple factory according to the keystore, truststore,

+   * and clientAuth properties of this object.
+   *
+   * @see #getKeyStore
+   * @see #getKeyStorePassword
+   * @see #isClientAuthMode
+   * @see #getTrustStore
+   * @see #getTrustStorePassword
+   */
+  public SslContextFactory createContextFactory() {
 
-    if (!sslConfig.isSSLMode()) 
-       return null;
-
+    if (! isSSLMode()) {
+      return null;
+    }
+    // else...
+    
     SslContextFactory factory = new SslContextFactory(false);
-    if (sslConfig.getKeyStore() != null)
-      factory.setKeyStorePath(sslConfig.getKeyStore());
-    if (sslConfig.getKeyStorePassword() != null)
-      factory.setKeyStorePassword(sslConfig.getKeyStorePassword());
-    factory.setNeedClientAuth(sslConfig.isClientAuthMode());
+    if (getKeyStore() != null)
+      factory.setKeyStorePath(getKeyStore());
+    if (getKeyStorePassword() != null)
+      factory.setKeyStorePassword(getKeyStorePassword());
+    
+    factory.setNeedClientAuth(isClientAuthMode());
     
-    if (sslConfig.isClientAuthMode()) {
-      if (sslConfig.getTrustStore() != null)
-        factory.setTrustStorePath(sslConfig.getTrustStore());
-      if (sslConfig.getTrustStorePassword() != null)
-        factory.setTrustStorePassword(sslConfig.getTrustStorePassword());
+    if (isClientAuthMode()) {
+      if (getTrustStore() != null)
+        factory.setTrustStorePath(getTrustStore());
+      if (getTrustStorePassword() != null)
+        factory.setTrustStorePassword(getTrustStorePassword());
     }
     return factory;
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9677e2c5/solr/test-framework/src/java/org/apache/solr/util/SSLTestConfig.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/util/SSLTestConfig.java b/solr/test-framework/src/java/org/apache/solr/util/SSLTestConfig.java
index 9049618..9d65a88 100644
--- a/solr/test-framework/src/java/org/apache/solr/util/SSLTestConfig.java
+++ b/solr/test-framework/src/java/org/apache/solr/util/SSLTestConfig.java
@@ -21,6 +21,8 @@ import java.security.KeyManagementException;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.SecureRandomSpi;
 import java.security.UnrecoverableKeyException;
 
 import javax.net.ssl.SSLContext;
@@ -40,8 +42,10 @@ import org.apache.solr.client.solrj.embedded.SSLConfig;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.client.solrj.impl.HttpClientUtil.SchemaRegistryProvider;
 import org.apache.solr.client.solrj.impl.SolrHttpClientBuilder;
+
 import org.eclipse.jetty.util.resource.Resource;
 import org.eclipse.jetty.util.security.CertificateUtils;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
 
 public class SSLTestConfig extends SSLConfig {
   public static File TEST_KEYSTORE = ExternalPaths.SERVER_HOME == null ? null
@@ -82,7 +86,10 @@ public class SSLTestConfig extends SSLConfig {
   
   /**
    * Builds a new SSLContext for HTTP <b>clients</b> to use when communicating
with servers which have 
-   * been configured based on the settings of this object.  Also explicitly allows the use
of self-signed 
+   * been configured based on the settings of this object.  
+   *
+   * NOTE: Uses a completely insecure {@link SecureRandom} instance to prevent tests from
blocking 
+   * due to lack of entropy, also explicitly allows the use of self-signed 
    * certificates (since that's what is almost always used during testing).
    */
   public SSLContext buildClientSSLContext() throws KeyManagementException, 
@@ -91,7 +98,8 @@ public class SSLTestConfig extends SSLConfig {
     assert isSSLMode();
     
     SSLContextBuilder builder = SSLContexts.custom();
-
+    builder.setSecureRandom(NullSecureRandom.INSTANCE);
+    
     // NOTE: KeyStore & TrustStore are swapped because they are from configured from
server perspective...
     // we are a client - our keystore contains the keys the server trusts, and vice versa
     builder.loadTrustMaterial(buildKeyStore(getKeyStore(), getKeyStorePassword()), new TrustSelfSignedStrategy()).build();
@@ -105,6 +113,54 @@ public class SSLTestConfig extends SSLConfig {
   }
   
   /**
+   * Builds a new SSLContext for jetty servers which have been configured based on the settings
of 
+   * this object.
+   *
+   * NOTE: Uses a completely insecure {@link SecureRandom} instance to prevent tests from
blocking 
+   * due to lack of entropy, also explicitly allows the use of self-signed 
+   * certificates (since that's what is almost always used during testing).
+   * almost always used during testing). 
+   */
+  public SSLContext buildServerSSLContext() throws KeyManagementException, 
+    UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
+
+    assert isSSLMode();
+    
+    SSLContextBuilder builder = SSLContexts.custom();
+    builder.setSecureRandom(NullSecureRandom.INSTANCE);
+    
+    builder.loadKeyMaterial(buildKeyStore(getKeyStore(), getKeyStorePassword()), getKeyStorePassword().toCharArray());
+
+    if (isClientAuthMode()) {
+      builder.loadTrustMaterial(buildKeyStore(getTrustStore(), getTrustStorePassword()),
new TrustSelfSignedStrategy()).build();
+      
+    }
+
+    return builder.build();
+  }
+
+  /**
+   * Returns an SslContextFactory using {@link buildServerSSLContext} if SSL should be used,
else returns null.
+   */
+  @Override
+  public SslContextFactory createContextFactory() {
+    if (!isSSLMode()) {
+      return null;
+    }
+    // else...
+
+    
+    SslContextFactory factory = new SslContextFactory(false);
+    try {
+      factory.setSslContext(buildServerSSLContext());
+    } catch (Exception e) { 
+      throw new RuntimeException("ssl context init failure: " + e.getMessage(), e); 
+    }
+    factory.setNeedClientAuth(isClientAuthMode());
+    return factory;
+  }
+  
+  /**
    * Constructs a KeyStore using the specified filename and password
    */
   protected static KeyStore buildKeyStore(String keyStoreLocation, String password) {
@@ -202,5 +258,42 @@ public class SSLTestConfig extends SSLConfig {
     System.clearProperty("javax.net.ssl.trustStore");
     System.clearProperty("javax.net.ssl.trustStorePassword");
   }
-  
+
+  /**
+   * A mocked up instance of SecureRandom that always does the minimal amount of work to
generate 
+   * "random" numbers.  This is to prevent blocking issues that arise in platform default

+   * SecureRandom instances due to too many instances / not enough random entropy.  
+   * Tests do not need secure SSL.
+   */
+  private static class NullSecureRandom extends SecureRandom {
+    public static final SecureRandom INSTANCE = new NullSecureRandom();
+    
+    /** SPI Used to init all instances */
+    private static final SecureRandomSpi NULL_SPI = new SecureRandomSpi() {
+      /** NOOP: returns new uninitialized byte[] */
+      public byte[] engineGenerateSeed(int numBytes) {
+        return new byte[numBytes];
+      }
+      /** NOOP */
+      public void engineNextBytes(byte[] bytes) { /* NOOP */ }
+      /** NOOP */
+      public void engineSetSeed(byte[] seed) { /* NOOP */ }
+    };
+    
+    private NullSecureRandom() {
+      super(NULL_SPI, null) ;
+    }
+    
+    /** NOOP: returns new uninitialized byte[] */
+    public byte[] generateSeed(int numBytes) {
+      return new byte[numBytes];
+    }
+    /** NOOP */
+    synchronized public void nextBytes(byte[] bytes) { /* NOOP */ }
+    /** NOOP */
+    synchronized public void setSeed(byte[] seed) { /* NOOP */ }
+    /** NOOP */
+    synchronized public void setSeed(long seed) { /* NOOP */ }
+    
+  }
 }


Mime
View raw message