Skip to content

Commit

Permalink
EAP7-1121 POC
Browse files Browse the repository at this point in the history
  • Loading branch information
Skyllarr committed Mar 30, 2020
1 parent 8ca9556 commit 5dd4d89
Show file tree
Hide file tree
Showing 15 changed files with 547 additions and 2 deletions.
16 changes: 14 additions & 2 deletions auth/client/pom.xml
Expand Up @@ -52,6 +52,10 @@
<groupId>org.wildfly.security</groupId>
<artifactId>wildfly-elytron-credential-store</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.security</groupId>
<artifactId>wildfly-elytron-dynamic-ssl</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.security</groupId>
<artifactId>wildfly-elytron-keystore</artifactId>
Expand All @@ -76,7 +80,7 @@
<groupId>org.wildfly.security</groupId>
<artifactId>wildfly-elytron-x500-cert</artifactId>
</dependency>

<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-annotations</artifactId>
Expand Down Expand Up @@ -146,6 +150,14 @@
<artifactId>jmockit</artifactId>
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Expand Up @@ -354,6 +354,10 @@ public <T, E extends Exception> T runAsSupplierEx(ExceptionSupplier<T, E> action
return runExFunction(ExceptionSupplier::get, action);
}

RuleNode<SecurityFactory<SSLContext>> getSslRules() {
return this.sslRules;
}

public ContextManager<AuthenticationContext> getInstanceContextManager() {
return getContextManager();
}
Expand Down
Expand Up @@ -30,7 +30,9 @@
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;

Expand Down Expand Up @@ -196,6 +198,21 @@ private static AuthenticationConfiguration initializeConfiguration(final URI uri
return configuration;
}


List<SSLContext> getConfiguredSSLContexts(AuthenticationContext authenticationContext) {
List<SSLContext> sslContexts = new ArrayList<>();
RuleNode<SecurityFactory<SSLContext>> node = authenticationContext.getSslRules();
while (node != null) {
try {
sslContexts.add(node.getConfiguration().create());
} catch (GeneralSecurityException ignored) {
ignored.printStackTrace();
}
node = node.getNext();
}
return sslContexts;
}

/**
* Get the SSL context which matches the given URI, or {@link SSLContext#getDefault()} if there is none.
*
Expand Down
@@ -0,0 +1,45 @@
package org.wildfly.security.auth.client;

import org.kohsuke.MetaInfServices;
import org.wildfly.security.dynamic.ssl.DynamicSSLContextSPI;

import javax.net.ssl.SSLContext;
import java.net.URI;
import java.security.AccessController;
import java.security.GeneralSecurityException;
import java.security.PrivilegedAction;
import java.util.List;

@MetaInfServices(value = DynamicSSLContextSPI.class)
public class DynamicSSLContextImpl implements DynamicSSLContextSPI {

private SSLContext configuredDefaultSSLContext;
private final AuthenticationContextConfigurationClient AUTH_CONTEXT_CLIENT =
AccessController.doPrivileged((PrivilegedAction<AuthenticationContextConfigurationClient>) AuthenticationContextConfigurationClient::new);
private AuthenticationContext authenticationContext = AuthenticationContext.captureCurrent();
private List<SSLContext> configuredSSLContexts;

public DynamicSSLContextImpl() {
this.configuredSSLContexts = AUTH_CONTEXT_CLIENT.getConfiguredSSLContexts(authenticationContext);
}

@Override
public SSLContext getConfiguredDefault() {
return this.configuredDefaultSSLContext;
}

@Override
public List<SSLContext> getConfiguredSSLContexts() {
return this.configuredSSLContexts;
}

@Override
public SSLContext getSSLContext(URI uri) {
try {
return AUTH_CONTEXT_CLIENT.getSSLContext(uri, authenticationContext);
} catch (GeneralSecurityException e) {
e.printStackTrace();
return null;
}
}
}
@@ -0,0 +1,106 @@
package org.wildfly.security.auth.client;

import org.junit.Assert;
import org.junit.Test;
import org.wildfly.security.dynamic.ssl.DynamicSSLContext;
import org.wildfly.security.dynamic.ssl.DynamicSslContextSpi;
import org.wildfly.security.SecurityFactory;
import org.wildfly.security.auth.client.mocks.MockSSLContext;
import org.wildfly.security.auth.client.mocks.MockSSLContextSPI;
import org.wildfly.security.auth.client.mocks.MockSSLSocketFactory;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import java.security.GeneralSecurityException;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class DynamicSSLContextIntersectionTest {

@Test
public void testIntersectionOfSupportedCipherSuites() throws GeneralSecurityException {

SSLSocketFactory sslSocketFactory0Ciphers = new MockSSLSocketFactory() {
@Override
public String[] getSupportedCipherSuites() {
return new String[0];
}
};

SSLSocketFactory sslSocketFactory3Ciphers = new MockSSLSocketFactory() {
@Override
public String[] getSupportedCipherSuites() {
return new String[]{"TLS_AES_128_GCM_SHA256", "TLS_CHACHA20_POLY1305_SHA256", "TLS_CIPHER_SUITE_NOT_COMMON"};
}
};

SSLSocketFactory sslSocketFactory4Ciphers = new MockSSLSocketFactory() {
@Override
public String[] getSupportedCipherSuites() {
return new String[]{"TLS_CHACHA20_POLY1305_SHA256", "TLS_AES_128_CCM_8_SHA256", "TLS_AES_128_GCM_SHA256", "TLS_AES_128_CCM_SHA256"};
}
};

SSLContext sslContext0Ciphers = new MockSSLContext(new MockSSLContextSPI() {
@Override
protected SSLSocketFactory engineGetSocketFactory() {
return sslSocketFactory0Ciphers;
}
});

SSLContext sslContext3Ciphers = new MockSSLContext(new MockSSLContextSPI() {
@Override
protected SSLSocketFactory engineGetSocketFactory() {
return sslSocketFactory3Ciphers;
}
});

SSLContext sslContext4Ciphers = new MockSSLContext(new MockSSLContextSPI() {
@Override
protected SSLSocketFactory engineGetSocketFactory() {
return sslSocketFactory4Ciphers;
}
});


SecurityFactory<SSLContext> sslContextSecurityFactory0Ciphers = mock(SecurityFactory.class);
SecurityFactory<SSLContext> sslContextSecurityFactoryt3Ciphers = mock(SecurityFactory.class);
SecurityFactory<SSLContext> sslContextSecurityFactory4Ciphers = mock(SecurityFactory.class);

when(sslContextSecurityFactory0Ciphers.create()).thenReturn(sslContext0Ciphers);
when(sslContextSecurityFactoryt3Ciphers.create()).thenReturn(sslContext3Ciphers);
when(sslContextSecurityFactory4Ciphers.create()).thenReturn(sslContext4Ciphers);

AuthenticationContext ctx = AuthenticationContext.empty()
.withSsl(MatchRule.ALL.matchHost("host1"), sslContextSecurityFactory4Ciphers)
.withSsl(MatchRule.ALL.matchHost("host2"), sslContextSecurityFactoryt3Ciphers);
ctx.run(checkResultIntersectionSizeIs(2));
ctx = AuthenticationContext.empty()
.withSsl(MatchRule.ALL.matchHost("host1"), sslContextSecurityFactory4Ciphers)
.withSsl(MatchRule.ALL.matchHost("host2"), sslContextSecurityFactoryt3Ciphers)
.withSsl(MatchRule.ALL.matchHost("host3"), sslContextSecurityFactory0Ciphers);
ctx.run(checkResultIntersectionSizeIs(0));
ctx = AuthenticationContext.empty()
.withSsl(MatchRule.ALL.matchHost("host3"), sslContextSecurityFactory0Ciphers)
.withSsl(MatchRule.ALL.matchHost("host3"), sslContextSecurityFactory0Ciphers);
ctx.run(checkResultIntersectionSizeIs(0));
ctx = AuthenticationContext.empty()
.withSsl(MatchRule.ALL.matchHost("host1"), sslContextSecurityFactory4Ciphers)
.withSsl(MatchRule.ALL.matchHost("host1"), sslContextSecurityFactory4Ciphers);
ctx.run(checkResultIntersectionSizeIs(4));
}

private Runnable checkResultIntersectionSizeIs(int intersectionSize) {
return () -> {
try {
DynamicSslContextSpi dynamicSslContextSpi = new DynamicSslContextSpi(SSLContext.getDefault());
SSLContext dynamicSSLContext = new DynamicSSLContext(dynamicSslContextSpi, null, null);
Assert.assertEquals(dynamicSSLContext.getSocketFactory().getSupportedCipherSuites().length, intersectionSize);
} catch (Exception e) {
e.printStackTrace();
Assert.fail();
}
};
}
}
@@ -0,0 +1,10 @@
package org.wildfly.security.auth.client.mocks;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLContextSpi;

public class MockSSLContext extends SSLContext {
public MockSSLContext(final SSLContextSpi mockContextSpi) {
super(mockContextSpi, null, null);
}
}
@@ -0,0 +1,40 @@
package org.wildfly.security.auth.client.mocks;

import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContextSpi;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.TrustManager;
import java.security.SecureRandom;

public abstract class MockSSLContextSPI extends SSLContextSpi {
@Override
protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers, SecureRandom secureRandom) {
}

@Override
protected SSLServerSocketFactory engineGetServerSocketFactory() {
return null;
}

@Override
protected SSLEngine engineCreateSSLEngine() {
return null;
}

@Override
protected SSLEngine engineCreateSSLEngine(String s, int i) {
return null;
}

@Override
protected SSLSessionContext engineGetServerSessionContext() {
return null;
}

@Override
protected SSLSessionContext engineGetClientSessionContext() {
return null;
}
}
@@ -0,0 +1,39 @@
package org.wildfly.security.auth.client.mocks;

import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public abstract class MockSSLSocketFactory extends SSLSocketFactory {
@Override
public Socket createSocket(Socket socket, String s, int i, boolean b) throws IOException {
return null;
}

@Override
public Socket createSocket(String s, int i) throws IOException, UnknownHostException {
return null;
}

@Override
public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException, UnknownHostException {
return null;
}

@Override
public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
return null;
}

@Override
public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) throws IOException {
return null;
}

@Override
public String[] getDefaultCipherSuites() {
return new String[0];
}
}
23 changes: 23 additions & 0 deletions dynamic-ssl/pom.xml
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.wildfly.security</groupId>
<artifactId>wildfly-elytron-parent</artifactId>
<version>1.11.4.CR1-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>

<artifactId>wildfly-elytron-dynamic-ssl</artifactId>

<name>WildFly Elytron - Dynamic SSL</name>
<description>WildFly Security Dynamic SSL Implementation</description>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,11 @@
package org.wildfly.security.dynamic.ssl;

import javax.net.ssl.SSLContext;
import java.security.Provider;

public final class DynamicSSLContext extends SSLContext {

public DynamicSSLContext(DynamicSslContextSpi contextSpi, Provider provider, String protocol) {
super(contextSpi, provider, protocol);
}
}
@@ -0,0 +1,12 @@
package org.wildfly.security.dynamic.ssl;

import javax.net.ssl.SSLContext;
import java.net.URI;
import java.util.List;

public interface DynamicSSLContextSPI {

SSLContext getConfiguredDefault();
List<SSLContext> getConfiguredSSLContexts();
SSLContext getSSLContext(URI uri);
}

0 comments on commit 5dd4d89

Please sign in to comment.