Skip to content

Commit

Permalink
GEODE-7071: Add CA to CertStores so that all certificates can be sign…
Browse files Browse the repository at this point in the history
…ed (apache#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.
  • Loading branch information
jdeppe-pivotal authored and mhansonp committed Aug 21, 2019
1 parent 1dc2e56 commit c63aaf4
Show file tree
Hide file tree
Showing 10 changed files with 660 additions and 433 deletions.
Expand Up @@ -23,6 +23,7 @@
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;
Expand All @@ -36,7 +37,8 @@
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;
Expand All @@ -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);
Expand All @@ -64,23 +76,29 @@ private static void doServerRegionTest() {

@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,
Expand All @@ -90,14 +108,20 @@ public void connectionSuccessfulWhenHostNameOfLocatorAndServer() throws Exceptio
@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,
Expand All @@ -107,16 +131,22 @@ public void expectConnectionFailureWhenNoHostNameInLocatorKey() throws Exception
@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,
Expand All @@ -125,54 +155,55 @@ public void expectConnectionFailureWhenWrongHostNameInLocatorKey() throws Except

@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
Expand Down

0 comments on commit c63aaf4

Please sign in to comment.