You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2019/08/19 13:35:44 UTC

[geode] branch develop updated: GEODE-7071: Add CA to CertStores so that all certificates can be signed (#3905)

This is an automated email from the ASF dual-hosted git repository.

jensdeppe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 87b3110  GEODE-7071: Add CA to CertStores so that all certificates can be signed (#3905)
87b3110 is described below

commit 87b31108a3cb9e2a7acca1a02643b71cd7b73d3f
Author: Jens Deppe <jd...@pivotal.io>
AuthorDate: Mon Aug 19 06:35:05 2019 -0700

    GEODE-7071: Add CA to CertStores so that all certificates can be signed (#3905)
    
    - CAs need to be explicitly created and added as trusted.
    - Certificates need to be explicitly signed.
    - Introduce CertificateMaterial which includes the generated
      X509Certificate, the certificate's KeyPair and the issuer if relevant.
    - Future work should convert all other tests, which utilize key/trust
      stores to use the CertStores class.
---
 ...tServerHostNameVerificationDistributedTest.java | 107 +++++++----
 .../internal/CustomSSLProviderDistributedTest.java | 124 +++++++-----
 .../GfshHostNameVerificationDistributedTest.java   |  67 ++++---
 .../tcpserver/TCPClientSSLIntegrationTest.java     |  72 ++++---
 ...LSocketHostNameVerificationIntegrationTest.java |  22 ++-
 .../org/apache/geode/cache/ssl/CertStores.java     | 119 +++++++-----
 .../apache/geode/cache/ssl/CertificateBuilder.java | 213 +++++++++++++++++++++
 .../geode/cache/ssl/CertificateMaterial.java       |  58 ++++++
 .../org/apache/geode/cache/ssl/TestSSLUtils.java   | 195 -------------------
 .../WANHostNameVerificationDistributedTest.java    | 116 +++++------
 10 files changed, 660 insertions(+), 433 deletions(-)

diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/ClientServerHostNameVerificationDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/ClientServerHostNameVerificationDistributedTest.java
index 5565360..a1bb2c3 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/ClientServerHostNameVerificationDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/ClientServerHostNameVerificationDistributedTest.java
@@ -23,6 +23,7 @@ import java.net.InetAddress;
 import java.security.GeneralSecurityException;
 import java.util.Properties;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -36,7 +37,8 @@ import org.apache.geode.cache.client.ClientRegionFactory;
 import org.apache.geode.cache.client.ClientRegionShortcut;
 import org.apache.geode.cache.client.NoAvailableServersException;
 import org.apache.geode.cache.ssl.CertStores;
-import org.apache.geode.cache.ssl.TestSSLUtils.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateMaterial;
 import org.apache.geode.distributed.internal.tcpserver.LocatorCancelException;
 import org.apache.geode.internal.net.SocketCreatorFactory;
 import org.apache.geode.test.dunit.IgnoredException;
@@ -49,6 +51,16 @@ public class ClientServerHostNameVerificationDistributedTest {
   @Rule
   public ClusterStartupRule cluster = new ClusterStartupRule();
 
+  private CertificateMaterial ca;
+
+  @Before
+  public void setup() {
+    ca = new CertificateBuilder()
+        .commonName("Test CA")
+        .isCA()
+        .generate();
+  }
+
   private static void createServerRegion() {
     RegionFactory factory =
         ClusterStartupRule.getCache().createRegionFactory(RegionShortcut.REPLICATE);
@@ -64,23 +76,29 @@ public class ClientServerHostNameVerificationDistributedTest {
 
   @Test
   public void connectionSuccessfulWhenHostNameOfLocatorAndServer() throws Exception {
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
         .commonName("locator")
+        .issuedBy(ca)
         // ClusterStartupRule uses 'localhost' as locator host
         .sanDnsName(InetAddress.getLoopbackAddress().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName())
         .sanIpAddress(InetAddress.getLocalHost())
-        .sanIpAddress(InetAddress.getByName("0.0.0.0")); // to pass on windows
+        .sanIpAddress(InetAddress.getByName("0.0.0.0")) // to pass on windows
+        .generate();
 
-    CertificateBuilder serverCertificate = new CertificateBuilder()
+    CertificateMaterial serverCertificate = new CertificateBuilder()
         .commonName("server")
+        .issuedBy(ca)
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName())
-        .sanIpAddress(InetAddress.getLocalHost());
+        .sanIpAddress(InetAddress.getLocalHost())
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("client")
+        .issuedBy(ca)
+        .generate();
 
     validateClientConnection(locatorCertificate, serverCertificate, clientCertificate, true, true,
         true,
@@ -90,14 +108,20 @@ public class ClientServerHostNameVerificationDistributedTest {
   @Test
   public void expectConnectionFailureWhenNoHostNameInLocatorKey() throws Exception {
 
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
-        .commonName("locator");
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
+        .commonName("locator")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder serverCertificate = new CertificateBuilder()
-        .commonName("server");
+    CertificateMaterial serverCertificate = new CertificateBuilder()
+        .commonName("server")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("client")
+        .issuedBy(ca)
+        .generate();
 
     validateClientConnection(locatorCertificate, serverCertificate, clientCertificate, false, false,
         true,
@@ -107,16 +131,22 @@ public class ClientServerHostNameVerificationDistributedTest {
   @Test
   public void expectConnectionFailureWhenWrongHostNameInLocatorKey() throws Exception {
 
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
         .commonName("locator")
-        .sanDnsName("example.com");;
+        .sanDnsName("example.com")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder serverCertificate = new CertificateBuilder()
+    CertificateMaterial serverCertificate = new CertificateBuilder()
         .commonName("server")
-        .sanDnsName("example.com");;
+        .sanDnsName("example.com")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("client")
+        .issuedBy(ca)
+        .generate();
 
     validateClientConnection(locatorCertificate, serverCertificate, clientCertificate, false, false,
         true,
@@ -125,54 +155,55 @@ public class ClientServerHostNameVerificationDistributedTest {
 
   @Test
   public void expectConnectionFailureWhenNoHostNameInServerKey() throws Exception {
-    CertificateBuilder locatorCertificateWithSan = new CertificateBuilder()
+    CertificateMaterial locatorCertificateWithSan = new CertificateBuilder()
         .commonName("locator")
+        .issuedBy(ca)
         .sanDnsName(InetAddress.getLoopbackAddress().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName())
-        .sanIpAddress(InetAddress.getLocalHost());
+        .sanIpAddress(InetAddress.getLocalHost())
+        .generate();
 
-    CertificateBuilder serverCertificateWithNoSan = new CertificateBuilder()
-        .commonName("server");
+    CertificateMaterial serverCertificateWithNoSan = new CertificateBuilder()
+        .commonName("server")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("client")
+        .issuedBy(ca)
+        .generate();
 
     validateClientConnection(locatorCertificateWithSan, serverCertificateWithNoSan,
         clientCertificate, false, false, true,
         NoAvailableServersException.class);
   }
 
-  private void validateClientConnection(CertificateBuilder locatorCertificate,
-      CertificateBuilder serverCertificate, CertificateBuilder clientCertificate,
+  private void validateClientConnection(CertificateMaterial locatorCertificate,
+      CertificateMaterial serverCertificate, CertificateMaterial clientCertificate,
       boolean enableHostNameVerficiationForLocator, boolean enableHostNameVerificationForServer,
       boolean enableHostNameVerificationForClient,
       Class<? extends Throwable> expectedExceptionOnClient)
       throws GeneralSecurityException, IOException {
     CertStores locatorStore = CertStores.locatorStore();
-    locatorStore.withCertificate(locatorCertificate);
+    locatorStore.withCertificate("locator", locatorCertificate);
+    locatorStore.trust("ca", ca);
 
     CertStores serverStore = CertStores.serverStore();
-    serverStore.withCertificate(serverCertificate);
+    serverStore.withCertificate("server", serverCertificate);
+    serverStore.trust("ca", ca);
 
     CertStores clientStore = CertStores.clientStore();
-    clientStore.withCertificate(clientCertificate);
+    clientStore.withCertificate("client", clientCertificate);
+    clientStore.trust("ca", ca);
 
     Properties locatorSSLProps = locatorStore
-        .trustSelf()
-        .trust(clientStore.alias(), clientStore.certificate())
-        .trust(serverStore.alias(), serverStore.certificate())
         .propertiesWith(ALL, true, enableHostNameVerficiationForLocator);
 
     Properties serverSSLProps = serverStore
-        .trustSelf()
-        .trust(locatorStore.alias(), locatorStore.certificate())
-        .trust(clientStore.alias(), clientStore.certificate())
         .propertiesWith(ALL, true, enableHostNameVerificationForServer);
 
     Properties clientSSLProps = clientStore
-        .trust(locatorStore.alias(), locatorStore.certificate())
-        .trust(serverStore.alias(), serverStore.certificate())
         .propertiesWith(ALL, true, enableHostNameVerificationForClient);
 
     // create a cluster
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/CustomSSLProviderDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/CustomSSLProviderDistributedTest.java
index 9fddeec6..db9c224 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/CustomSSLProviderDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/CustomSSLProviderDistributedTest.java
@@ -33,6 +33,7 @@ import java.util.Properties;
 
 import javax.net.ssl.SSLContext;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -48,7 +49,8 @@ import org.apache.geode.cache.client.NoAvailableServersException;
 import org.apache.geode.cache.client.internal.provider.CustomKeyManagerFactory;
 import org.apache.geode.cache.client.internal.provider.CustomTrustManagerFactory;
 import org.apache.geode.cache.ssl.CertStores;
-import org.apache.geode.cache.ssl.TestSSLUtils.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateMaterial;
 import org.apache.geode.distributed.internal.tcpserver.LocatorCancelException;
 import org.apache.geode.internal.net.SocketCreatorFactory;
 import org.apache.geode.test.dunit.IgnoredException;
@@ -60,10 +62,19 @@ import org.apache.geode.test.junit.categories.ClientServerTest;
 public class CustomSSLProviderDistributedTest {
   private static MemberVM locator;
   private static MemberVM server;
+  private CertificateMaterial ca;
 
   @Rule
   public ClusterStartupRule cluster = new ClusterStartupRule();
 
+  @Before
+  public void setup() {
+    ca = new CertificateBuilder()
+        .commonName("Test CA")
+        .isCA()
+        .generate();
+  }
+
   private CustomKeyManagerFactory.PKIXFactory keyManagerFactory;
   private CustomTrustManagerFactory.PKIXFactory trustManagerFactory;
 
@@ -86,23 +97,29 @@ public class CustomSSLProviderDistributedTest {
 
   @Test
   public void hostNameIsValidatedWhenUsingDefaultContext() throws Exception {
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
         .commonName("locator")
+        .issuedBy(ca)
         // ClusterStartupRule uses 'localhost' as locator host
         .sanDnsName(InetAddress.getLoopbackAddress().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName())
         .sanIpAddress(InetAddress.getLocalHost())
-        .sanIpAddress(InetAddress.getByName("0.0.0.0")); // to pass on windows
+        .sanIpAddress(InetAddress.getByName("0.0.0.0")) // to pass on windows
+        .generate();
 
-    CertificateBuilder serverCertificate = new CertificateBuilder()
+    CertificateMaterial serverCertificate = new CertificateBuilder()
         .commonName("server")
+        .issuedBy(ca)
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName())
-        .sanIpAddress(InetAddress.getLocalHost());
+        .sanIpAddress(InetAddress.getLocalHost())
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("client")
+        .issuedBy(ca)
+        .generate();
 
     validateClientSSLConnection(locatorCertificate, serverCertificate, clientCertificate, true,
         true, false, null);
@@ -110,14 +127,20 @@ public class CustomSSLProviderDistributedTest {
 
   @Test
   public void clientCanChooseNotToValidateHostName() throws Exception {
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
-        .commonName("locator");
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
+        .commonName("locator")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder serverCertificate = new CertificateBuilder()
-        .commonName("server");
+    CertificateMaterial serverCertificate = new CertificateBuilder()
+        .commonName("server")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("client")
+        .issuedBy(ca)
+        .generate();
 
     validateClientSSLConnection(locatorCertificate, serverCertificate, clientCertificate, false,
         false, true, null);
@@ -125,14 +148,20 @@ public class CustomSSLProviderDistributedTest {
 
   @Test
   public void clientConnectionFailsIfNoHostNameInLocatorKey() throws Exception {
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
-        .commonName("locator");
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
+        .commonName("locator")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder serverCertificate = new CertificateBuilder()
-        .commonName("server");
+    CertificateMaterial serverCertificate = new CertificateBuilder()
+        .commonName("server")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("client")
+        .issuedBy(ca)
+        .generate();
 
     validateClientSSLConnection(locatorCertificate, serverCertificate, clientCertificate, false,
         false, false, LocatorCancelException.class);
@@ -140,16 +169,22 @@ public class CustomSSLProviderDistributedTest {
 
   @Test
   public void clientConnectionFailsWhenWrongHostNameInLocatorKey() throws Exception {
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
         .commonName("locator")
-        .sanDnsName("example.com");;
+        .sanDnsName("example.com")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder serverCertificate = new CertificateBuilder()
+    CertificateMaterial serverCertificate = new CertificateBuilder()
         .commonName("server")
-        .sanDnsName("example.com");;
+        .sanDnsName("example.com")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("client")
+        .issuedBy(ca)
+        .generate();
 
     validateClientSSLConnection(locatorCertificate, serverCertificate, clientCertificate, false,
         false,
@@ -159,56 +194,57 @@ public class CustomSSLProviderDistributedTest {
 
   @Test
   public void expectConnectionFailureWhenNoHostNameInServerKey() throws Exception {
-    CertificateBuilder locatorCertificateWithSan = new CertificateBuilder()
+    CertificateMaterial locatorCertificateWithSan = new CertificateBuilder()
         .commonName("locator")
+        .issuedBy(ca)
         .sanDnsName(InetAddress.getLoopbackAddress().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName())
-        .sanIpAddress(InetAddress.getLocalHost());
+        .sanIpAddress(InetAddress.getLocalHost())
+        .generate();
 
-    CertificateBuilder serverCertificateWithNoSan = new CertificateBuilder()
-        .commonName("server");
+    CertificateMaterial serverCertificateWithNoSan = new CertificateBuilder()
+        .commonName("server")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("client")
+        .issuedBy(ca)
+        .generate();
 
     validateClientSSLConnection(locatorCertificateWithSan, serverCertificateWithNoSan,
         clientCertificate, false, false, false,
         NoAvailableServersException.class);
   }
 
-  private void validateClientSSLConnection(CertificateBuilder locatorCertificate,
-      CertificateBuilder serverCertificate, CertificateBuilder clientCertificate,
+  private void validateClientSSLConnection(CertificateMaterial locatorCertificate,
+      CertificateMaterial serverCertificate, CertificateMaterial clientCertificate,
       boolean enableHostNameVerficationForLocator, boolean enableHostNameVerificationForServer,
       boolean disableHostNameVerificationForClient,
       Class expectedExceptionOnClient)
       throws GeneralSecurityException, IOException {
 
     CertStores locatorStore = CertStores.locatorStore();
-    locatorStore.withCertificate(locatorCertificate);
+    locatorStore.withCertificate("locator", locatorCertificate);
+    locatorStore.trust("ca", ca);
 
     CertStores serverStore = CertStores.serverStore();
-    serverStore.withCertificate(serverCertificate);
+    serverStore.withCertificate("server", serverCertificate);
+    serverStore.trust("ca", ca);
 
     CertStores clientStore = CertStores.clientStore();
-    clientStore.withCertificate(clientCertificate);
+    clientStore.withCertificate("client", clientCertificate);
+    clientStore.trust("ca", ca);
 
     Properties locatorSSLProps = locatorStore
-        .trustSelf()
-        .trust(serverStore.alias(), serverStore.certificate())
-        .trust(clientStore.alias(), clientStore.certificate())
         .propertiesWith(ALL, false, enableHostNameVerficationForLocator);
 
     Properties serverSSLProps = serverStore
-        .trustSelf()
-        .trust(locatorStore.alias(), locatorStore.certificate())
-        .trust(clientStore.alias(), clientStore.certificate())
         .propertiesWith(ALL, true, enableHostNameVerificationForServer);
 
     // this props is only to create temp keystore and truststore and get paths
     Properties clientSSLProps = clientStore
-        .trust(locatorStore.alias(), locatorStore.certificate())
-        .trust(serverStore.alias(), serverStore.certificate())
         .propertiesWith(ALL, true, true);
 
     setupCluster(locatorSSLProps, serverSSLProps);
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/GfshHostNameVerificationDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/GfshHostNameVerificationDistributedTest.java
index c794247..f232748 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/GfshHostNameVerificationDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/GfshHostNameVerificationDistributedTest.java
@@ -30,7 +30,8 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.ssl.CertStores;
-import org.apache.geode.cache.ssl.TestSSLUtils.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateMaterial;
 import org.apache.geode.test.dunit.IgnoredException;
 import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
@@ -41,6 +42,7 @@ import org.apache.geode.test.junit.rules.GfshCommandRule;
 @Category({GfshTest.class})
 public class GfshHostNameVerificationDistributedTest {
   private static MemberVM locator;
+  private CertificateMaterial ca;
 
   @Rule
   public ClusterStartupRule cluster = new ClusterStartupRule();
@@ -53,28 +55,32 @@ public class GfshHostNameVerificationDistributedTest {
 
   @Before
   public void setupCluster() throws Exception {
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
+    ca = new CertificateBuilder()
+        .commonName("Test CA")
+        .isCA()
+        .generate();
+
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
         .commonName("locator")
+        .issuedBy(ca)
         .sanDnsName(InetAddress.getLoopbackAddress().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanIpAddress(InetAddress.getLocalHost())
-        .sanIpAddress(InetAddress.getByName("0.0.0.0")); // to pass on windows
+        .sanIpAddress(InetAddress.getByName("0.0.0.0")) // to pass on windows
+        .generate();
 
-    CertificateBuilder gfshCertificate = new CertificateBuilder()
-        .commonName("gfsh");
+    CertificateMaterial gfshCertificate = new CertificateBuilder()
+        .commonName("gfsh")
+        .issuedBy(ca)
+        .generate();
 
     locatorStore = CertStores.locatorStore();
-    gfshStore = CertStores.clientStore();
-
-    locatorStore.withCertificate(locatorCertificate);
-    gfshStore.withCertificate(gfshCertificate);
+    locatorStore.withCertificate("locator", locatorCertificate);
+    locatorStore.trust("ca", ca);
 
-    locatorStore
-        .trustSelf()
-        .trust(gfshStore.alias(), gfshStore.certificate());
-
-    gfshStore
-        .trust(locatorStore.alias(), locatorStore.certificate());
+    gfshStore = CertStores.clientStore();
+    gfshStore.withCertificate("gfsh", gfshCertificate);
+    gfshStore.trust("ca", ca);
   }
 
   private File gfshSecurityProperties(Properties clientSSLProps) throws IOException {
@@ -103,34 +109,39 @@ public class GfshHostNameVerificationDistributedTest {
 
   @Test
   public void expectConnectionFailureWhenNoHostNameInLocatorKey() throws Exception {
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
-        .commonName("locator");
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
+        .commonName("locator")
+        .issuedBy(ca)
+        .generate();
 
     validateGfshConnection(locatorCertificate);
   }
 
   @Test
   public void expectConnectionFailureWhenWrongHostNameInLocatorKey() throws Exception {
-    CertificateBuilder locatorCertificate = new CertificateBuilder()
+    CertificateMaterial locatorCertificate = new CertificateBuilder()
         .commonName("locator")
-        .sanDnsName("example.com");
+        .issuedBy(ca)
+        .sanDnsName("example.com")
+        .generate();
 
     validateGfshConnection(locatorCertificate);
   }
 
-  private void validateGfshConnection(CertificateBuilder locatorCertificate)
+  private void validateGfshConnection(CertificateMaterial locatorCertificate)
       throws Exception {
-    CertificateBuilder gfshCertificate = new CertificateBuilder().commonName("gfsh");
+    CertificateMaterial gfshCertificate = new CertificateBuilder()
+        .commonName("gfsh")
+        .issuedBy(ca)
+        .generate();
 
     CertStores lstore = CertStores.locatorStore();
-    CertStores gstore = CertStores.clientStore();
-
-    lstore.withCertificate(locatorCertificate);
-    gstore.withCertificate(gfshCertificate);
+    lstore.withCertificate("locator", locatorCertificate);
+    lstore.trust("ca", ca);
 
-    lstore.trustSelf().trust(gstore.alias(), gstore.certificate());
-
-    gstore.trust(lstore.alias(), lstore.certificate());
+    CertStores gstore = CertStores.clientStore();
+    gstore.withCertificate("gfsh", gfshCertificate);
+    gstore.trust("ca", ca);
 
     Properties locatorSSLProps = lstore.propertiesWith(ALL, false, false);
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPClientSSLIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPClientSSLIntegrationTest.java
index 858a469..f40a291 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPClientSSLIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPClientSSLIntegrationTest.java
@@ -36,7 +36,8 @@ import org.junit.experimental.categories.Category;
 import org.mockito.Mockito;
 
 import org.apache.geode.cache.ssl.CertStores;
-import org.apache.geode.cache.ssl.TestSSLUtils.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateMaterial;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.DistributionConfigImpl;
 import org.apache.geode.distributed.internal.PoolStatHelper;
@@ -55,6 +56,7 @@ public class TCPClientSSLIntegrationTest {
   private int port;
   private FakeTcpServer server;
   private TcpClient client;
+  private CertificateMaterial ca;
 
   @Rule
   public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
@@ -62,25 +64,29 @@ public class TCPClientSSLIntegrationTest {
   @Before
   public void setup() {
     SocketCreatorFactory.setDistributionConfig(new DistributionConfigImpl(new Properties()));
+
+    ca = new CertificateBuilder()
+        .commonName("Test CA")
+        .isCA()
+        .generate();
   }
 
-  private void startServerAndClient(CertificateBuilder serverCertificate,
-      CertificateBuilder clientCertificate, boolean enableHostNameValidation)
+  private void startServerAndClient(CertificateMaterial serverCertificate,
+      CertificateMaterial clientCertificate, boolean enableHostNameValidation)
       throws GeneralSecurityException, IOException {
 
     CertStores serverStore = CertStores.locatorStore();
-    serverStore.withCertificate(serverCertificate);
+    serverStore.withCertificate("server", serverCertificate);
+    serverStore.trust("ca", ca);
 
     CertStores clientStore = CertStores.clientStore();
-    clientStore.withCertificate(clientCertificate);
+    clientStore.withCertificate("client", clientCertificate);
+    clientStore.trust("ca", ca);
 
     Properties serverProperties = serverStore
-        .trustSelf()
-        .trust(clientStore.alias(), clientStore.certificate())
         .propertiesWith(LOCATOR, true, enableHostNameValidation);
 
     Properties clientProperties = clientStore
-        .trust(serverStore.alias(), serverStore.certificate())
         .propertiesWith(LOCATOR, true, enableHostNameValidation);
 
     startTcpServer(serverProperties);
@@ -108,12 +114,16 @@ public class TCPClientSSLIntegrationTest {
 
   @Test
   public void clientConnectsIfServerCertificateHasHostname() throws Exception {
-    CertificateBuilder serverCertificate = new CertificateBuilder()
+    CertificateMaterial serverCertificate = new CertificateBuilder()
         .commonName("tcp-server")
-        .sanDnsName(InetAddress.getLocalHost().getHostName());
+        .issuedBy(ca)
+        .sanDnsName(InetAddress.getLocalHost().getHostName())
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("tcp-client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("tcp-client")
+        .issuedBy(ca)
+        .generate();
 
     startServerAndClient(serverCertificate, clientCertificate, true);
     String response =
@@ -124,11 +134,15 @@ public class TCPClientSSLIntegrationTest {
   @Test
   public void clientChooseToDisableHasHostnameValidation() throws Exception {
     // no host name in server cert
-    CertificateBuilder serverCertificate = new CertificateBuilder()
-        .commonName("tcp-server");
+    CertificateMaterial serverCertificate = new CertificateBuilder()
+        .commonName("tcp-server")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("tcp-client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("tcp-client")
+        .issuedBy(ca)
+        .generate();
 
     startServerAndClient(serverCertificate, clientCertificate, false);
     String response =
@@ -138,11 +152,15 @@ public class TCPClientSSLIntegrationTest {
 
   @Test
   public void clientFailsToConnectIfServerCertificateNoHostname() throws Exception {
-    CertificateBuilder serverCertificate = new CertificateBuilder()
-        .commonName("tcp-server");
+    CertificateMaterial serverCertificate = new CertificateBuilder()
+        .commonName("tcp-server")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("tcp-client");
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("tcp-client")
+        .issuedBy(ca)
+        .generate();
 
     startServerAndClient(serverCertificate, clientCertificate, true);
 
@@ -154,12 +172,16 @@ public class TCPClientSSLIntegrationTest {
 
   @Test
   public void clientFailsToConnectIfServerCertificateWrongHostname() throws Exception {
-    CertificateBuilder serverCertificate = new CertificateBuilder()
+    CertificateMaterial serverCertificate = new CertificateBuilder()
         .commonName("tcp-server")
-        .sanDnsName("example.com");
-
-    CertificateBuilder clientCertificate = new CertificateBuilder()
-        .commonName("tcp-client");
+        .issuedBy(ca)
+        .sanDnsName("example.com")
+        .generate();
+
+    CertificateMaterial clientCertificate = new CertificateBuilder()
+        .commonName("tcp-client")
+        .issuedBy(ca)
+        .generate();
 
     startServerAndClient(serverCertificate, clientCertificate, true);
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/net/SSLSocketHostNameVerificationIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/net/SSLSocketHostNameVerificationIntegrationTest.java
index b14f78f..2715c24 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/net/SSLSocketHostNameVerificationIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/net/SSLSocketHostNameVerificationIntegrationTest.java
@@ -49,7 +49,8 @@ import org.junit.runners.Parameterized.Parameter;
 import org.junit.runners.Parameterized.Parameters;
 
 import org.apache.geode.cache.ssl.CertStores;
-import org.apache.geode.cache.ssl.TestSSLUtils;
+import org.apache.geode.cache.ssl.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateMaterial;
 import org.apache.geode.distributed.internal.DMStats;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.DistributionConfigImpl;
@@ -104,16 +105,25 @@ public class SSLSocketHostNameVerificationIntegrationTest {
     IgnoredException.addIgnoredException("javax.net.ssl.SSLException: Read timed out");
 
     this.localHost = InetAddress.getLoopbackAddress();
-    TestSSLUtils.CertificateBuilder certBuilder = new TestSSLUtils.CertificateBuilder()
-        .commonName("iAmTheServer");
+
+    CertificateMaterial ca = new CertificateBuilder()
+        .commonName("Test CA")
+        .isCA()
+        .generate();
+
+    CertStores certStores = CertStores.locatorStore();
+    certStores.trust("ca", ca);
+
+    CertificateBuilder certBuilder = new CertificateBuilder()
+        .commonName("iAmTheServer")
+        .issuedBy(ca);
 
     if (addCertificateSAN) {
       certBuilder.sanDnsName(this.localHost.getHostName());
     }
 
-    CertStores certStores = CertStores.locatorStore();
-    certStores.withCertificate(certBuilder);
-    certStores.trustSelf();
+    CertificateMaterial locatorCert = certBuilder.generate();
+    certStores.withCertificate("locator", locatorCert);
 
     this.distributionConfig =
         new DistributionConfigImpl(
diff --git a/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertStores.java b/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertStores.java
index 7fca0a4..a72c2fe 100644
--- a/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertStores.java
+++ b/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertStores.java
@@ -14,9 +14,6 @@
  */
 package org.apache.geode.cache.ssl;
 
-import static org.apache.geode.cache.ssl.TestSSLUtils.createKeyStore;
-import static org.apache.geode.cache.ssl.TestSSLUtils.createTrustStore;
-import static org.apache.geode.cache.ssl.TestSSLUtils.generateKeyPair;
 import static org.apache.geode.distributed.ConfigurationProperties.SSL_CIPHERS;
 import static org.apache.geode.distributed.ConfigurationProperties.SSL_ENABLED_COMPONENTS;
 import static org.apache.geode.distributed.ConfigurationProperties.SSL_ENDPOINT_IDENTIFICATION_ENABLED;
@@ -29,74 +26,62 @@ import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTOR
 import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD;
 import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_TYPE;
 
+import java.io.EOFException;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.security.cert.X509Certificate;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
+/**
+ * The {@code CertStores} class encapsulates the key and trust stores typically used by various
+ * components in a Geode cluster. It currently supports certificate collections for servers,
+ * locators and clients. All certificates are signed by a single Root Certificate Authority.
+ */
 public class CertStores {
-  private final String alias;
   private final String storePrefix;
 
-  private Map<String, X509Certificate> trustedCerts = new HashMap<>();
+  // Contents of keystore
+  private Map<String, CertificateMaterial> keyStoreEntries = new HashMap<>();
 
-  private File keyStoreFile;
+  // Contents of truststore
+  private Map<String, CertificateMaterial> trustedCerts = new HashMap<>();
 
   private String trustStorePassword = "password";
   private String keyStorePassword = "password";
 
-  private X509Certificate cert;
-
   public static CertStores locatorStore() {
-    return new CertStores("locator", "locator");
+    return new CertStores("locator");
   }
 
   public static CertStores serverStore() {
-    return new CertStores("server", "server");
+    return new CertStores("server");
   }
 
   public static CertStores clientStore() {
-    return new CertStores("client", "client");
+    return new CertStores("client");
   }
 
-  public CertStores(String alias, String storePrefix) {
-    this.alias = alias;
+  public CertStores(String storePrefix) {
     this.storePrefix = storePrefix;
   }
 
-  public String alias() {
-    return alias;
-  }
-
-  public X509Certificate certificate() {
-    return cert;
-  }
-
-  public CertStores withCertificate(TestSSLUtils.CertificateBuilder certificateBuilder)
-      throws GeneralSecurityException, IOException {
-    keyStoreFile = File.createTempFile(storePrefix + "KS", ".jks");
-    withCertificate(certificateBuilder, keyStoreFile);
+  public CertStores withCertificate(String alias, CertificateMaterial material) {
+    keyStoreEntries.put(alias, material);
     return this;
   }
 
-  private void withCertificate(TestSSLUtils.CertificateBuilder certificateBuilder,
-      File keyStoreFile) throws GeneralSecurityException, IOException {
-    KeyPair keyPair = generateKeyPair("RSA");
-    cert = certificateBuilder.generate(keyPair);
-    createKeyStore(keyStoreFile.getPath(), keyStorePassword, alias, keyPair.getPrivate(), cert);
-  }
-
-  public CertStores trustSelf() {
-    this.trustedCerts.put(alias, cert);
-    return this;
-  }
-
-  public CertStores trust(String alias, X509Certificate certificate) {
-    this.trustedCerts.put(alias, certificate);
+  public CertStores trust(String alias, CertificateMaterial material) {
+    this.trustedCerts.put(alias, material);
     return this;
   }
 
@@ -114,10 +99,13 @@ public class CertStores {
   public Properties propertiesWith(String components, String protocols,
       String ciphers, boolean requireAuth, boolean endPointIdentification)
       throws GeneralSecurityException, IOException {
-    File trustStoreFile = File.createTempFile(storePrefix + "TS", ".jks");
+    File trustStoreFile = File.createTempFile(storePrefix + "-TS-", ".jks");
     trustStoreFile.deleteOnExit();
+    createTrustStore(trustStoreFile.getPath(), trustStorePassword);
 
-    createTrustStore(trustStoreFile.getPath(), trustStorePassword, trustedCerts);
+    File keyStoreFile = File.createTempFile(storePrefix + "-KS-", ".jks");
+    keyStoreFile.deleteOnExit();
+    createKeyStore(keyStoreFile.getPath(), keyStorePassword);
 
     return propertiesWith(components, protocols, ciphers, trustStoreFile, keyStoreFile, requireAuth,
         endPointIdentification);
@@ -142,4 +130,49 @@ public class CertStores {
 
     return sslConfigs;
   }
+
+  private void createTrustStore(String filename, String password)
+      throws GeneralSecurityException, IOException {
+    KeyStore ks = KeyStore.getInstance("JKS");
+    try (InputStream in = Files.newInputStream(Paths.get(filename))) {
+      ks.load(in, password.toCharArray());
+    } catch (EOFException e) {
+      ks = createEmptyKeyStore();
+    }
+    for (Map.Entry<String, CertificateMaterial> cert : trustedCerts.entrySet()) {
+      ks.setCertificateEntry(cert.getKey(), cert.getValue().getCertificate());
+    }
+
+    try (OutputStream out = Files.newOutputStream(Paths.get(filename))) {
+      ks.store(out, password.toCharArray());
+    }
+  }
+
+  private void createKeyStore(String filename, String password)
+      throws GeneralSecurityException, IOException {
+    KeyStore ks = createEmptyKeyStore();
+
+    for (Map.Entry<String, CertificateMaterial> entry : keyStoreEntries.entrySet()) {
+      CertificateMaterial cert = entry.getValue();
+
+      List<Certificate> chain = new ArrayList<>();
+      chain.add(cert.getCertificate());
+
+      cert.getIssuer().ifPresent(chain::add);
+
+      ks.setKeyEntry(entry.getKey(), cert.getPrivateKey(), password.toCharArray(),
+          chain.toArray(new Certificate[] {}));
+    }
+    try (OutputStream out = Files.newOutputStream(Paths.get(filename))) {
+      ks.store(out, password.toCharArray());
+    }
+  }
+
+
+  private KeyStore createEmptyKeyStore() throws GeneralSecurityException, IOException {
+    KeyStore ks = KeyStore.getInstance("JKS");
+    ks.load(null, null); // initialize
+    return ks;
+  }
+
 }
diff --git a/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertificateBuilder.java b/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertificateBuilder.java
new file mode 100644
index 0000000..0dd226e
--- /dev/null
+++ b/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertificateBuilder.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.cache.ssl;
+
+import static java.util.stream.Collectors.toList;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.asn1.x509.KeyUsage;
+import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.crypto.util.PrivateKeyFactory;
+import org.bouncycastle.crypto.util.PublicKeyFactory;
+import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;
+
+/**
+ * Class which allows easily building certificates. It can also be used to build
+ * Certificate Authorities. The class is intended to be used in conjunction with {@link CertStores}
+ * to facilitate building key and trust stores.
+ */
+public class CertificateBuilder {
+  private final int days;
+  private final String algorithm;
+  private X500Name name;
+  private List<String> dnsNames;
+  private List<InetAddress> ipAddresses;
+  private boolean isCA;
+  private CertificateMaterial issuer;
+
+  public CertificateBuilder() {
+    this(30, "SHA256withRSA");
+  }
+
+  public CertificateBuilder(int days, String algorithm) {
+    this.days = days;
+    this.algorithm = algorithm;
+    this.dnsNames = new ArrayList<>();
+    this.ipAddresses = new ArrayList<>();
+  }
+
+  private static GeneralName dnsGeneralName(String name) {
+    return new GeneralName(GeneralName.dNSName, name);
+  }
+
+  private static GeneralName ipGeneralName(InetAddress hostAddress) {
+    return new GeneralName(GeneralName.iPAddress,
+        new DEROctetString(hostAddress.getAddress()));
+  }
+
+  public CertificateBuilder commonName(String cn) {
+    this.name = new X500Name("CN=" + cn + ", O=Geode");
+    return this;
+  }
+
+  public CertificateBuilder sanDnsName(String hostName) {
+    this.dnsNames.add(hostName);
+    return this;
+  }
+
+  public CertificateBuilder sanIpAddress(InetAddress hostAddress) {
+    this.ipAddresses.add(hostAddress);
+    return this;
+  }
+
+  public CertificateBuilder isCA() {
+    this.isCA = true;
+    return this;
+  }
+
+  public CertificateBuilder issuedBy(CertificateMaterial issuer) {
+    this.issuer = issuer;
+    return this;
+  }
+
+  private byte[] san() throws IOException {
+    List<GeneralName> names = dnsNames.stream()
+        .map(CertificateBuilder::dnsGeneralName)
+        .collect(toList());
+
+    names.addAll(ipAddresses.stream()
+        .map(CertificateBuilder::ipGeneralName)
+        .collect(toList()));
+
+    return names.isEmpty() ? null
+        : new GeneralNames(names.toArray(new GeneralName[] {})).getEncoded();
+  }
+
+  public CertificateMaterial generate() {
+    KeyPair keyPair = generateKeyPair("RSA");
+    PrivateKey privateKey;
+    X509Certificate issuerCertificate = null;
+
+    if (issuer == null) {
+      privateKey = keyPair.getPrivate();
+    } else {
+      privateKey = issuer.getPrivateKey();
+    }
+
+    X509Certificate cert = generate(keyPair.getPublic(), privateKey);
+
+    if (issuer != null) {
+      issuerCertificate = issuer.getCertificate();
+    }
+
+    return new CertificateMaterial(cert, keyPair, issuerCertificate);
+  }
+
+  private X509Certificate generate(PublicKey publicKey, PrivateKey privateKey) {
+    try {
+      AlgorithmIdentifier sigAlgId =
+          new DefaultSignatureAlgorithmIdentifierFinder().find(algorithm);
+      AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
+      AsymmetricKeyParameter publicKeyAsymKeyParam =
+          PublicKeyFactory.createKey(publicKey.getEncoded());
+      AsymmetricKeyParameter privateKeyAsymKeyParam =
+          PrivateKeyFactory.createKey(privateKey.getEncoded());
+      SubjectPublicKeyInfo subPubKeyInfo =
+          SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
+
+      ContentSigner sigGen =
+          new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(privateKeyAsymKeyParam);
+
+      Date from = new Date();
+      Date to = new Date(from.getTime() + days * 86400000L);
+      BigInteger sn = new BigInteger(64, new SecureRandom());
+
+      X509v3CertificateBuilder v3CertGen;
+      if (issuer == null) {
+        // This is a self-signed certificate
+        v3CertGen = new X509v3CertificateBuilder(name, sn, from, to, name, subPubKeyInfo);
+      } else {
+        v3CertGen = new X509v3CertificateBuilder(
+            new X500Name(issuer.getCertificate().getIssuerDN().getName()),
+            sn, from, to, name, subPubKeyInfo);
+      }
+
+      byte[] subjectAltName = san();
+      if (subjectAltName != null) {
+        v3CertGen.addExtension(Extension.subjectAlternativeName, false, subjectAltName);
+      }
+
+      if (isCA) {
+        v3CertGen.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign));
+        v3CertGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0));
+      }
+
+      // Not strictly necessary, but this makes the certs look like those generated
+      // by `keytool`.
+      SubjectKeyIdentifier subjectKeyIdentifier =
+          new SubjectKeyIdentifier(
+              SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKeyAsymKeyParam)
+                  .getEncoded());
+      v3CertGen.addExtension(Extension.subjectKeyIdentifier, false, subjectKeyIdentifier);
+
+      X509CertificateHolder certificateHolder = v3CertGen.build(sigGen);
+      return new JcaX509CertificateConverter()
+          .setProvider(new BouncyCastleProvider())
+          .getCertificate(certificateHolder);
+    } catch (Exception e) {
+      throw new RuntimeException("Unable to create certificate", e);
+    }
+  }
+
+  private KeyPair generateKeyPair(String algorithm) {
+    try {
+      KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm);
+      keyGen.initialize(2048);
+      return keyGen.genKeyPair();
+    } catch (NoSuchAlgorithmException nex) {
+      throw new RuntimeException("Unable to generate " + algorithm + " keypair");
+    }
+  }
+}
diff --git a/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertificateMaterial.java b/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertificateMaterial.java
new file mode 100644
index 0000000..6656818
--- /dev/null
+++ b/geode-junit/src/main/java/org/apache/geode/cache/ssl/CertificateMaterial.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.cache.ssl;
+
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.Optional;
+
+/**
+ * Class which encapsulates a {@link X509Certificate} as well as the associated
+ * {@link KeyPair}. If the certificate is not self-signed it will also hold an issuer.
+ * <p/>
+ * {@code CertificateMaterial} is produced by {@link CertificateBuilder}s.
+ *
+ * @see CertificateBuilder
+ * @see CertStores
+ */
+public class CertificateMaterial {
+  private final X509Certificate certificate;
+  private final KeyPair keyPair;
+  private final Optional<X509Certificate> issuer;
+
+  public CertificateMaterial(X509Certificate certificate, KeyPair keyPair, X509Certificate issuer) {
+    this.certificate = certificate;
+    this.keyPair = keyPair;
+    this.issuer = Optional.ofNullable(issuer);
+  }
+
+  public X509Certificate getCertificate() {
+    return certificate;
+  }
+
+  public PublicKey getPublicKey() {
+    return keyPair.getPublic();
+  }
+
+  public PrivateKey getPrivateKey() {
+    return keyPair.getPrivate();
+  }
+
+  public Optional<X509Certificate> getIssuer() {
+    return issuer;
+  }
+}
diff --git a/geode-junit/src/main/java/org/apache/geode/cache/ssl/TestSSLUtils.java b/geode-junit/src/main/java/org/apache/geode/cache/ssl/TestSSLUtils.java
deleted file mode 100644
index 42a945b..0000000
--- a/geode-junit/src/main/java/org/apache/geode/cache/ssl/TestSSLUtils.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package org.apache.geode.cache.ssl;
-
-import static java.util.stream.Collectors.toList;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.security.GeneralSecurityException;
-import java.security.Key;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.GeneralName;
-import org.bouncycastle.asn1.x509.GeneralNames;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.crypto.util.PrivateKeyFactory;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
-import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
-import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;
-
-public class TestSSLUtils {
-
-  public static KeyPair generateKeyPair(String algorithm) throws NoSuchAlgorithmException {
-    KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm);
-    keyGen.initialize(1024);
-    return keyGen.genKeyPair();
-  }
-
-  private static KeyStore createEmptyKeyStore() throws GeneralSecurityException, IOException {
-    KeyStore ks = KeyStore.getInstance("JKS");
-    ks.load(null, null); // initialize
-    return ks;
-  }
-
-  public static void createKeyStore(String filename,
-      String password, String alias,
-      Key privateKey, Certificate cert) throws GeneralSecurityException, IOException {
-    KeyStore ks = createEmptyKeyStore();
-    ks.setKeyEntry(alias, privateKey, password.toCharArray(), new Certificate[] {cert});
-    try (OutputStream out = Files.newOutputStream(Paths.get(filename))) {
-      ks.store(out, password.toCharArray());
-    }
-  }
-
-  public static <T extends Certificate> void createTrustStore(
-      String filename, String password, Map<String, T> certs)
-      throws GeneralSecurityException, IOException {
-    KeyStore ks = KeyStore.getInstance("JKS");
-    try (InputStream in = Files.newInputStream(Paths.get(filename))) {
-      ks.load(in, password.toCharArray());
-    } catch (EOFException e) {
-      ks = createEmptyKeyStore();
-    }
-    for (Map.Entry<String, T> cert : certs.entrySet()) {
-      ks.setCertificateEntry(cert.getKey(), cert.getValue());
-    }
-    try (OutputStream out = Files.newOutputStream(Paths.get(filename))) {
-      ks.store(out, password.toCharArray());
-    }
-  }
-
-  public static class CertificateBuilder {
-    private final int days;
-    private final String algorithm;
-    private String name;
-    private List<String> dnsNames;
-    private List<InetAddress> ipAddresses;
-
-    public CertificateBuilder() {
-      this(30, "SHA1withRSA");
-    }
-
-    public CertificateBuilder(int days, String algorithm) {
-      this.days = days;
-      this.algorithm = algorithm;
-      this.dnsNames = new ArrayList<>();
-      this.ipAddresses = new ArrayList<>();
-    }
-
-    private static GeneralName dnsGeneralName(String name) {
-      return new GeneralName(GeneralName.dNSName, name);
-    }
-
-    private static GeneralName ipGeneralName(InetAddress hostAddress) {
-      return new GeneralName(GeneralName.iPAddress,
-          new DEROctetString(hostAddress.getAddress()));
-    }
-
-    public CertificateBuilder commonName(String cn) {
-      this.name = "CN=" + cn + ", O=Geode";
-      return this;
-    }
-
-    public CertificateBuilder sanDnsName(String hostName) {
-      this.dnsNames.add(hostName);
-      return this;
-    }
-
-    public CertificateBuilder sanIpAddress(InetAddress hostAddress) {
-      this.ipAddresses.add(hostAddress);
-      return this;
-    }
-
-    private byte[] san() throws IOException {
-      List<GeneralName> names = dnsNames.stream()
-          .map(CertificateBuilder::dnsGeneralName)
-          .collect(toList());
-
-      names.addAll(ipAddresses.stream()
-          .map(CertificateBuilder::ipGeneralName)
-          .collect(toList()));
-
-      return names.isEmpty() ? null
-          : new GeneralNames(names.toArray(new GeneralName[] {})).getEncoded();
-    }
-
-    public X509Certificate generate(KeyPair keyPair) throws CertificateException {
-      return this.generate(this.name, keyPair);
-    }
-
-    public X509Certificate generate(String dn, KeyPair keyPair) throws CertificateException {
-      try {
-        Security.addProvider(new BouncyCastleProvider());
-        AlgorithmIdentifier sigAlgId =
-            new DefaultSignatureAlgorithmIdentifierFinder().find(algorithm);
-        AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
-        AsymmetricKeyParameter privateKeyAsymKeyParam =
-            PrivateKeyFactory.createKey(keyPair.getPrivate().getEncoded());
-        SubjectPublicKeyInfo subPubKeyInfo =
-            SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
-        ContentSigner sigGen =
-            new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(privateKeyAsymKeyParam);
-        X500Name name = new X500Name(dn);
-        Date from = new Date();
-        Date to = new Date(from.getTime() + days * 86400000L);
-        BigInteger sn = new BigInteger(64, new SecureRandom());
-        X509v3CertificateBuilder v3CertGen =
-            new X509v3CertificateBuilder(name, sn, from, to, name, subPubKeyInfo);
-
-        byte[] subjectAltName = san();
-        if (subjectAltName != null) {
-          v3CertGen.addExtension(Extension.subjectAlternativeName, false, subjectAltName);
-        }
-        X509CertificateHolder certificateHolder = v3CertGen.build(sigGen);
-        return new JcaX509CertificateConverter().setProvider("BC")
-            .getCertificate(certificateHolder);
-      } catch (CertificateException ce) {
-        throw ce;
-      } catch (Exception e) {
-        throw new CertificateException(e);
-      }
-    }
-  }
-}
diff --git a/geode-wan/src/distributedTest/java/org/apache/geode/internal/cache/wan/serial/WANHostNameVerificationDistributedTest.java b/geode-wan/src/distributedTest/java/org/apache/geode/internal/cache/wan/serial/WANHostNameVerificationDistributedTest.java
index 177570a..329e800 100644
--- a/geode-wan/src/distributedTest/java/org/apache/geode/internal/cache/wan/serial/WANHostNameVerificationDistributedTest.java
+++ b/geode-wan/src/distributedTest/java/org/apache/geode/internal/cache/wan/serial/WANHostNameVerificationDistributedTest.java
@@ -14,7 +14,6 @@
  */
 package org.apache.geode.internal.cache.wan.serial;
 
-import static org.apache.geode.cache.ssl.TestSSLUtils.CertificateBuilder;
 import static org.apache.geode.distributed.ConfigurationProperties.DISTRIBUTED_SYSTEM_ID;
 import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.REMOTE_LOCATORS;
@@ -37,6 +36,8 @@ import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionFactory;
 import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.cache.ssl.CertStores;
+import org.apache.geode.cache.ssl.CertificateBuilder;
+import org.apache.geode.cache.ssl.CertificateMaterial;
 import org.apache.geode.cache.wan.GatewayReceiverFactory;
 import org.apache.geode.cache.wan.GatewaySenderFactory;
 import org.apache.geode.internal.AvailablePortHelper;
@@ -66,42 +67,38 @@ public class WANHostNameVerificationDistributedTest {
     IgnoredException.addIgnoredException("Unexpected IOException");
   }
 
-  private void setupWanSites(CertificateBuilder locator_ln_cert, CertificateBuilder server_ln_cert,
-      CertificateBuilder locator_ny_cert, CertificateBuilder server_ny_cert)
+  private void setupWanSites(CertificateMaterial ca, CertificateMaterial locator_ln_cert,
+      CertificateMaterial server_ln_cert,
+      CertificateMaterial locator_ny_cert, CertificateMaterial server_ny_cert)
       throws GeneralSecurityException, IOException {
-    CertStores locator_ln_store = new CertStores("ln_locator", "ln_locator");
-    locator_ln_store.withCertificate(locator_ln_cert);
+    CertStores locator_ln_store = new CertStores("ln_locator");
+    locator_ln_store.withCertificate("ln_locator", locator_ln_cert);
+    locator_ln_store.trust("ca", ca);
 
-    CertStores server_ln_store = new CertStores("ln_server", "ln_server");
-    server_ln_store.withCertificate(server_ln_cert);
+    CertStores server_ln_store = new CertStores("ln_server");
+    server_ln_store.withCertificate("ln_server", server_ln_cert);
+    server_ln_store.trust("ca", ca);
 
-    CertStores locator_ny_store = new CertStores("ny_locator", "ny_locator");
-    locator_ny_store.withCertificate(locator_ny_cert);
+    CertStores locator_ny_store = new CertStores("ny_locator");
+    locator_ny_store.withCertificate("ny_locator", locator_ny_cert);
+    locator_ny_store.trust("ca", ca);
 
-    CertStores server_ny_store = new CertStores("ny_server", "ny_server");
-    server_ny_store.withCertificate(server_ny_cert);
+    CertStores server_ny_store = new CertStores("ny_server");
+    server_ny_store.withCertificate("ny_server", server_ny_cert);
+    server_ny_store.trust("ca", ca);
 
     int site1Port =
-        setupWanSite1(locator_ln_store, server_ln_store, locator_ny_store, server_ny_store);
-    setupWanSite2(site1Port, locator_ny_store, server_ny_store, locator_ln_store, server_ln_store);
+        setupWanSite1(locator_ln_store, server_ln_store);
+    setupWanSite2(site1Port, locator_ny_store, server_ny_store);
   }
 
-  private int setupWanSite1(CertStores locator_ln_store, CertStores server_ln_store,
-      CertStores locator_ny_store, CertStores server_ny_store)
+  private int setupWanSite1(CertStores locator_ln_store, CertStores server_ln_store)
       throws GeneralSecurityException, IOException {
 
     Properties locatorSSLProps = locator_ln_store
-        .trustSelf()
-        .trust(server_ln_store.alias(), server_ln_store.certificate())
-        .trust(locator_ny_store.alias(), locator_ny_store.certificate())
-        .trust(server_ny_store.alias(), server_ny_store.certificate())
         .propertiesWith(ALL, true, true);
 
     Properties serverSSLProps = server_ln_store
-        .trustSelf()
-        .trust(locator_ln_store.alias(), locator_ln_store.certificate())
-        .trust(locator_ny_store.alias(), locator_ny_store.certificate())
-        .trust(server_ny_store.alias(), server_ny_store.certificate())
         .propertiesWith(ALL, true, true);
 
     // create a cluster
@@ -120,15 +117,10 @@ public class WANHostNameVerificationDistributedTest {
   }
 
   private void setupWanSite2(int site1Port, CertStores locator_ny_store,
-      CertStores server_ny_store,
-      CertStores locator_ln_store, CertStores server_ln_store)
+      CertStores server_ny_store)
       throws GeneralSecurityException, IOException {
 
     Properties locator_ny_props = locator_ny_store
-        .trustSelf()
-        .trust(server_ln_store.alias(), server_ln_store.certificate())
-        .trust(server_ny_store.alias(), server_ny_store.certificate())
-        .trust(locator_ln_store.alias(), locator_ln_store.certificate())
         .propertiesWith(ALL, true, true);
 
     locator_ny_props.setProperty(MCAST_PORT, "0");
@@ -136,10 +128,6 @@ public class WANHostNameVerificationDistributedTest {
     locator_ny_props.setProperty(REMOTE_LOCATORS, "localhost[" + site1Port + "]");
 
     Properties server_ny_props = server_ny_store
-        .trustSelf()
-        .trust(locator_ln_store.alias(), locator_ln_store.certificate())
-        .trust(locator_ny_store.alias(), locator_ny_store.certificate())
-        .trust(server_ln_store.alias(), server_ln_store.certificate())
         .propertiesWith(ALL, true, true);
 
     // create a cluster
@@ -203,35 +191,48 @@ public class WANHostNameVerificationDistributedTest {
     // server-ln -> locator-ny
     // server-ln -> server-ny
 
-    CertificateBuilder locator_ln_cert = new CertificateBuilder()
+    CertificateMaterial ca = new CertificateBuilder()
+        .commonName("Test CA")
+        .isCA()
+        .generate();
+
+    CertificateMaterial locator_ln_cert = new CertificateBuilder()
         .commonName("locator_ln")
+        .issuedBy(ca)
         // ClusterStartupRule uses 'localhost' as locator host
         .sanDnsName(InetAddress.getLoopbackAddress().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanIpAddress(InetAddress.getLocalHost())
-        .sanIpAddress(InetAddress.getByName("0.0.0.0")); // to pass on windows
+        .sanIpAddress(InetAddress.getByName("0.0.0.0")) // to pass on windows
+        .generate();
 
-    CertificateBuilder server_ln_cert = new CertificateBuilder()
+    CertificateMaterial server_ln_cert = new CertificateBuilder()
         .commonName("server_ln")
+        .issuedBy(ca)
         .sanDnsName(InetAddress.getLocalHost().getHostName())
-        .sanIpAddress(InetAddress.getLocalHost());
+        .sanIpAddress(InetAddress.getLocalHost())
+        .generate();
 
-    CertificateBuilder locator_ny_cert = new CertificateBuilder()
+    CertificateMaterial locator_ny_cert = new CertificateBuilder()
         .commonName("locator_ny")
+        .issuedBy(ca)
         // ClusterStartupRule uses 'localhost' as locator host
         .sanDnsName(InetAddress.getLoopbackAddress().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName())
         .sanIpAddress(InetAddress.getLocalHost())
-        .sanIpAddress(InetAddress.getByName("0.0.0.0")); // to pass on windows
+        .sanIpAddress(InetAddress.getByName("0.0.0.0")) // to pass on windows
+        .generate();
 
-    CertificateBuilder server_ny_cert = new CertificateBuilder()
+    CertificateMaterial server_ny_cert = new CertificateBuilder()
         .commonName("server_ny")
+        .issuedBy(ca)
         .sanDnsName(InetAddress.getLocalHost().getHostName())
         .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName())
-        .sanIpAddress(InetAddress.getLocalHost());
+        .sanIpAddress(InetAddress.getLocalHost())
+        .generate();
 
-    setupWanSites(locator_ln_cert, server_ln_cert, locator_ny_cert, server_ny_cert);
+    setupWanSites(ca, locator_ln_cert, server_ln_cert, locator_ny_cert, server_ny_cert);
 
     server_ln.invoke(WANHostNameVerificationDistributedTest::doPutOnSite1);
     server_ny.invoke(WANHostNameVerificationDistributedTest::verifySite2Received);
@@ -239,26 +240,33 @@ public class WANHostNameVerificationDistributedTest {
 
   @Test
   public void gwsenderFailsToConnectIfGWReceiverHasNoHostName() throws Exception {
-    CertificateBuilder gwSenderCertificate = new CertificateBuilder()
-        .commonName("gwsender-ln");
+    CertificateMaterial ca = new CertificateBuilder()
+        .commonName("Test CA")
+        .isCA()
+        .generate();
+
+    CertificateMaterial gwSenderCertificate = new CertificateBuilder()
+        .commonName("gwsender-ln")
+        .issuedBy(ca)
+        .generate();
 
-    CertificateBuilder gwReceiverCertificate = new CertificateBuilder()
-        .commonName("gwreceiver-ny");
+    CertificateMaterial gwReceiverCertificate = new CertificateBuilder()
+        .commonName("gwreceiver-ny")
+        .issuedBy(ca)
+        .generate();
 
-    CertStores gwSender = new CertStores("gwsender", "gwsender");
-    gwSender.withCertificate(gwSenderCertificate);
+    CertStores gwSender = new CertStores("gwsender");
+    gwSender.withCertificate("gwsender", gwSenderCertificate);
+    gwSender.trust("ca", ca);
 
-    CertStores gwReceiver = new CertStores("gwreceiver", "gwreceiver");
-    gwReceiver.withCertificate(gwReceiverCertificate);
+    CertStores gwReceiver = new CertStores("gwreceiver");
+    gwReceiver.withCertificate("gwreceiver", gwReceiverCertificate);
+    gwReceiver.trust("ca", ca);
 
     Properties ln_SSLProps = gwSender
-        .trustSelf()
-        .trust(gwReceiver.alias(), gwReceiver.certificate())
         .propertiesWith(GATEWAY, true, true);
 
     Properties ny_SSLProps = gwReceiver
-        .trustSelf()
-        .trust(gwSender.alias(), gwSender.certificate())
         .propertiesWith(GATEWAY, true, true);
 
     // create a ln cluster