Skip to content

Commit

Permalink
ISPN-10803 WildFly OpenSSL
Browse files Browse the repository at this point in the history
  • Loading branch information
pruivo authored and tristantarrant committed Dec 16, 2019
1 parent 2c36140 commit 80255cc
Show file tree
Hide file tree
Showing 41 changed files with 525 additions and 2,198 deletions.
3 changes: 1 addition & 2 deletions build-configuration/pom.xml
Expand Up @@ -183,8 +183,6 @@
<version.mockito_dep.objenesis>2.6</version.mockito_dep.objenesis>
<version.net.bytebuddy>1.9.12</version.net.bytebuddy>
<version.netty>4.1.43.Final</version.netty>
<version.netty-conscrypt-optional>1.0.0</version.netty-conscrypt-optional>
<version.netty.tcnative>2.0.25.Final</version.netty.tcnative>
<version.okhttp>3.14.3</version.okhttp>
<version.openjdk.jmh>1.12</version.openjdk.jmh>
<version.ops4j.base>1.5.0</version.ops4j.base>
Expand All @@ -196,6 +194,7 @@
<version.org.wildfly.arquillian>2.2.0.Final</version.org.wildfly.arquillian>
<version.org.wildfly.core>10.0.0.Final</version.org.wildfly.core>
<version.org.wildfly.elytron>1.10.3.Final</version.org.wildfly.elytron>
<version.org.wildfly.openssl>1.0.9.Final</version.org.wildfly.openssl>
<version.osgi>4.3.1</version.osgi>
<version.pax.exam>4.11.0</version.pax.exam>
<version.picketbox>5.0.3.Final</version.picketbox>
Expand Down
14 changes: 14 additions & 0 deletions client/hotrod-client/pom.xml
Expand Up @@ -197,11 +197,24 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.wildfly.openssl</groupId>
<artifactId>wildfly-openssl-java</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.wildfly.openssl</groupId>
<artifactId>wildfly-openssl-linux-x86_64</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.geronimo.components</groupId>
<artifactId>geronimo-transaction</artifactId>
Expand All @@ -213,6 +226,7 @@
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.objectweb.howl</groupId>
<artifactId>howl</artifactId>
Expand Down
Expand Up @@ -12,7 +12,6 @@
import java.util.function.BiConsumer;

import javax.net.ssl.SNIHostName;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
Expand Down Expand Up @@ -106,41 +105,42 @@ protected void initChannel(Channel channel) throws Exception {

private void initSsl(Channel channel) {
SslConfiguration ssl = configuration.security().ssl();
SslContext nettySslContext;
SSLContext jdkSslContext = ssl.sslContext();
if (jdkSslContext == null) {
SslContext sslContext;
if (ssl.sslContext() == null) {
SslContextBuilder builder = SslContextBuilder.forClient();
try {
if (ssl.keyStoreFileName() != null) {
builder.keyManager(SslContextFactory.getKeyManagerFactory(
ssl.keyStoreFileName(),
ssl.keyStoreType(),
ssl.keyStorePassword(),
ssl.keyStoreCertificatePassword(),
ssl.keyAlias(),
configuration.classLoader()));
builder.keyManager(new SslContextFactory()
.keyStoreFileName(ssl.keyStoreFileName())
.keyStoreType(ssl.keyStoreType())
.keyStorePassword(ssl.keyStorePassword())
.keyAlias(ssl.keyAlias())
.keyStoreCertificatePassword(ssl.keyStoreCertificatePassword())
.classLoader(configuration.classLoader())
.getKeyManagerFactory());
}
if (ssl.trustStoreFileName() != null) {
builder.trustManager(SslContextFactory.getTrustManagerFactory(
ssl.trustStoreFileName(),
ssl.trustStoreType(),
ssl.trustStorePassword(),
configuration.classLoader()));
builder.trustManager(new SslContextFactory()
.trustStoreFileName(ssl.trustStoreFileName())
.trustStoreType(ssl.trustStoreType())
.trustStorePassword(ssl.trustStorePassword())
.classLoader(configuration.classLoader())
.getTrustManagerFactory());
}
if (ssl.trustStorePath() != null) {
builder.trustManager(new File(ssl.trustStorePath()));
}
if (ssl.protocol() != null) {
builder.protocols(ssl.protocol());
}
nettySslContext = builder.build();
sslContext = builder.build();
} catch (Exception e) {
throw new CacheConfigurationException(e);
}
} else {
nettySslContext = new JdkSslContext(jdkSslContext, true, ClientAuth.NONE);
sslContext = new JdkSslContext(ssl.sslContext(), true, ClientAuth.NONE);
}
SslHandler sslHandler = nettySslContext.newHandler(channel.alloc(), ssl.sniHostName(), -1);
SslHandler sslHandler = sslContext.newHandler(channel.alloc(), ssl.sniHostName(), -1);
if (ssl.sniHostName() != null) {
SSLParameters sslParameters = sslHandler.engine().getSSLParameters();
sslParameters.setServerNames(Collections.singletonList(new SNIHostName(ssl.sniHostName())));
Expand Down
Expand Up @@ -149,14 +149,14 @@ protected void clearContent() {
}


public void testSSLAuthentication() throws Exception {
public void testSSLAuthentication() {
RemoteCache<String, String> cache = remoteCacheManager.getCache();
cache.put("k","v");
assertEquals("v", cache.get("k"));
}

@Test(expectedExceptions = HotRodClientException.class, expectedExceptionsMessageRegExp = ".*ISPN000287.*")
public void testSSLUnauthorized() throws Exception {
public void testSSLUnauthorized() {
RemoteCache<String, String> cache = remoteCacheManager.getCache(UNAUTHORIZED);
cache.put("k1","v1");
assertEquals("v1", cache.get("k1"));
Expand Down
Expand Up @@ -17,7 +17,13 @@ public void testLoadTrustStore() {
char[] password = "secret".toCharArray();

SSLContext context =
SslContextFactory.getContext(keyStoreFileName, "pkcs12", password, truststoreFileName, "pkcs12", password);
new SslContextFactory()
.keyStoreFileName(keyStoreFileName)
.keyStoreType("pkcs12")
.keyStorePassword(password)
.trustStoreFileName(truststoreFileName)
.trustStoreType("pkcs12")
.trustStorePassword(password).getContext();

assertNotNull(context);
}
Expand Down
@@ -1,5 +1,6 @@
package org.infinispan.client.rest;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.CompletionStage;

Expand All @@ -12,5 +13,9 @@ public interface RestRawClient {

CompletionStage<RestResponse> putValue(String url, Map<String, String> headers, String body, String bodyMediaType);

CompletionStage<RestResponse> get(String url);
default CompletionStage<RestResponse> get(String url) {
return get(url, Collections.emptyMap());
}

CompletionStage<RestResponse> get(String url, Map<String, String> headers);
}
Expand Up @@ -11,8 +11,8 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import org.infinispan.client.rest.RestCacheClient;
Expand All @@ -28,6 +28,7 @@
import org.infinispan.client.rest.configuration.AuthenticationConfiguration;
import org.infinispan.client.rest.configuration.RestClientConfiguration;
import org.infinispan.client.rest.configuration.ServerConfiguration;
import org.infinispan.client.rest.configuration.SslConfiguration;
import org.infinispan.client.rest.impl.okhttp.auth.AutoDetectAuthenticator;
import org.infinispan.client.rest.impl.okhttp.auth.BasicAuthenticator;
import org.infinispan.client.rest.impl.okhttp.auth.BearerAuthenticator;
Expand All @@ -36,6 +37,7 @@
import org.infinispan.client.rest.impl.okhttp.auth.CachingAuthenticatorWrapper;
import org.infinispan.client.rest.impl.okhttp.auth.DigestAuthenticator;
import org.infinispan.client.rest.impl.okhttp.auth.NegotiateAuthenticator;
import org.infinispan.commons.util.SslContextFactory;

import okhttp3.Authenticator;
import okhttp3.Call;
Expand Down Expand Up @@ -64,13 +66,31 @@ public RestClientOkHttp(RestClientConfiguration configuration) {
builder
.connectTimeout(configuration.connectionTimeout(), TimeUnit.MILLISECONDS)
.readTimeout(configuration.socketTimeout(), TimeUnit.MILLISECONDS).followRedirects(configuration.followRedirects());

SSLContext sslContext = configuration.security().ssl().sslContext();
if (sslContext != null) {
builder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) configuration.security().ssl().trustManagers()[0]);
HostnameVerifier hostnameVerifier = configuration.security().ssl().hostnameVerifier();
if (hostnameVerifier != null) {
builder.hostnameVerifier(hostnameVerifier);
SslConfiguration ssl = configuration.security().ssl();
if (ssl.enabled()) {
SSLContext sslContext = ssl.sslContext();
if (sslContext == null) {
SslContextFactory sslContextFactory = new SslContextFactory()
.keyStoreFileName(ssl.keyStoreFileName())
.keyStorePassword(ssl.keyStorePassword())
.keyStoreType(ssl.keyStoreType())
.trustStoreFileName(ssl.trustStoreFileName())
.trustStorePassword(ssl.trustStorePassword())
.trustStoreType(ssl.trustStoreType())
.classLoader(Thread.currentThread().getContextClassLoader())
.useNativeIfAvailable(false);
sslContext = sslContextFactory.getContext();
try {
TrustManagerFactory tmf = sslContextFactory.getTrustManagerFactory();
builder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0]);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
builder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) ssl.trustManagers()[0]);
}
if (ssl.hostnameVerifier() != null) {
builder.hostnameVerifier(ssl.hostnameVerifier());
}
}

Expand All @@ -79,7 +99,7 @@ public RestClientOkHttp(RestClientConfiguration configuration) {
builder.protocols(Arrays.asList(Protocol.HTTP_1_1));
break;
case HTTP_20:
if (sslContext == null) {
if (!ssl.enabled()) {
builder.protocols(Arrays.asList(Protocol.H2_PRIOR_KNOWLEDGE));
} else {
builder.protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1));
Expand Down Expand Up @@ -120,7 +140,7 @@ public RestClientOkHttp(RestClientConfiguration configuration) {

httpClient = builder.build();
ServerConfiguration server = configuration.servers().get(0);
baseURL = String.format("%s://%s:%d", sslContext == null ? "http" : "https", server.host(), server.port()).replaceAll("//", "/");
baseURL = String.format("%s://%s:%d", ssl.enabled() ? "https" : "http", server.host(), server.port()).replaceAll("//", "/");
}

@Override
Expand Down
Expand Up @@ -43,8 +43,9 @@ public CompletionStage<RestResponse> putValue(String url, Map<String, String> he
}

@Override
public CompletionStage<RestResponse> get(String url) {
public CompletionStage<RestResponse> get(String url, Map<String, String> headers) {
Request.Builder builder = new Request.Builder().get().url(restClient.getBaseURL() + url);
headers.forEach(builder::header);
return restClient.execute(builder);
}
}
6 changes: 6 additions & 0 deletions commons/pom.xml
Expand Up @@ -52,6 +52,12 @@
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.wildfly.openssl</groupId>
<artifactId>wildfly-openssl-java</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>framework</artifactId>
Expand Down
9 changes: 9 additions & 0 deletions commons/src/main/java/org/infinispan/commons/logging/Log.java
@@ -1,6 +1,7 @@
package org.infinispan.commons.logging;

import static org.jboss.logging.Logger.Level.ERROR;
import static org.jboss.logging.Logger.Level.INFO;
import static org.jboss.logging.Logger.Level.WARN;

import java.io.IOException;
Expand Down Expand Up @@ -209,6 +210,14 @@ public interface Log extends BasicLogger {
// @Message(value = "Unable to marshall Object '%s' wrapped by '%s', the wrapped object must be registered with the marshallers SerializationContext", id = 945)
// MarshallingException unableToMarshallRuntimeObject(String wrappedObjectClass, String wrapperClass);

@LogMessage(level = INFO)
@Message(value = "Using OpenSSL Provider", id = 946)
void openSSLAvailable();

@LogMessage(level = INFO)
@Message(value = "Using Java SSL Provider", id = 947)
void openSSLNotAvailable();

//----- counters exceptions // don't use the same id range ------

@Message(value = CounterOutOfBoundsException.FORMAT_MESSAGE, id = 29501)
Expand Down

0 comments on commit 80255cc

Please sign in to comment.