Skip to content

Commit

Permalink
[ELY-1996] [Community] SSLContext to support delegation to alternate …
Browse files Browse the repository at this point in the history
…instances based on peer information.
  • Loading branch information
Skyllarr committed Mar 3, 2024
1 parent b80aa6a commit 32aedbc
Show file tree
Hide file tree
Showing 21 changed files with 1,700 additions and 2 deletions.
2 changes: 1 addition & 1 deletion ELY_Messages.txt
Expand Up @@ -126,7 +126,7 @@
24000 - 24999 wildfly-elytron-jose-jwk
25000 - 25999 wildfly-elytron-jose-jws
26000 - 26999 wildfly-elytron-jose-util
27000 - 27999
27000 - 27999 wildfly-elytron-dynamic-ssl
28000 - 28999
29000 - 29999
30000 - 30999
Expand Down
5 changes: 4 additions & 1 deletion 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,6 @@
<groupId>org.wildfly.security</groupId>
<artifactId>wildfly-elytron-ssh-util</artifactId>
</dependency>

<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-annotations</artifactId>
Expand Down
Expand Up @@ -361,6 +361,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,28 @@ private static AuthenticationConfiguration initializeConfiguration(final URI uri
return configuration;
}

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

public SSLContext getDefaultSSLContext(AuthenticationContext authenticationContext) throws GeneralSecurityException {
SSLContext defaultSSLContext = null;
RuleNode<SecurityFactory<SSLContext>> node = authenticationContext.getSslRules();
while (node != null) {
if (node.getRule().equals(MatchRule.ALL)) {
defaultSSLContext = node.getConfiguration().create();
}
node = node.getNext();
}
return defaultSSLContext == null ? SSLContext.getDefault() : defaultSSLContext;
}

/**
* Get the configured SSL context which matches ALL rules from provided AuthenticationContext, or {@link SSLContext#getDefault()} if there is none.
*
Expand Down
@@ -0,0 +1,91 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2020 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed 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.wildfly.security.auth.client;

import org.kohsuke.MetaInfServices;
import org.wildfly.common.Assert;
import org.wildfly.security.auth.client._private.ElytronMessages;
import org.wildfly.security.dynamic.ssl.DynamicSSLContextException;
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;

/**
* Elytron client implementation of DynamicSSLContextSPI. It uses configuration from either provided instance of AuthenticationContext
* or from current AuthenticationContext if a configuration was not provided.
*
* @author <a href="mailto:dvilkola@redhat.com">Diana Krepinska (Vilkolakova)</a>
*/
@MetaInfServices(value = DynamicSSLContextSPI.class)
public class DynamicSSLContextImpl implements DynamicSSLContextSPI {

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

public DynamicSSLContextImpl() throws GeneralSecurityException {
}

public DynamicSSLContextImpl(AuthenticationContext authenticationContext) throws GeneralSecurityException {
Assert.assertNotNull("authenticationContext");
this.authenticationContext = authenticationContext;
this.configuredSSLContexts = AUTH_CONTEXT_CLIENT.getConfiguredSSLContexts(authenticationContext);
this.configuredDefaultSSLContext = AUTH_CONTEXT_CLIENT.getDefaultSSLContext(authenticationContext);
}

@Override
public SSLContext getConfiguredDefault() throws DynamicSSLContextException {
if (this.configuredDefaultSSLContext != null) {
return this.configuredDefaultSSLContext;
}
try {
return AUTH_CONTEXT_CLIENT.getDefaultSSLContext(AuthenticationContext.captureCurrent());
} catch (GeneralSecurityException e) {
throw ElytronMessages.log.cannotObtainDefaultSSLContext(e);
}
}

@Override
public List<SSLContext> getConfiguredSSLContexts() throws DynamicSSLContextException {
if (this.configuredSSLContexts != null) {
return this.configuredSSLContexts;
}
try {
return AUTH_CONTEXT_CLIENT.getConfiguredSSLContexts(AuthenticationContext.captureCurrent());
} catch (GeneralSecurityException e) {
throw ElytronMessages.log.cannotObtainConfiguredSSLContexts(e);
}
}

@Override
public SSLContext getSSLContext(URI uri) throws DynamicSSLContextException {
try {
return AUTH_CONTEXT_CLIENT.getSSLContext(uri, authenticationContext == null ? AuthenticationContext.captureCurrent() : authenticationContext);
} catch (GeneralSecurityException e) {
throw ElytronMessages.log.cannotObtainSSLContextForGivenURI(e);
}
}
}
Expand Up @@ -40,6 +40,7 @@
import org.wildfly.client.config.ConfigXMLParseException;
import org.wildfly.client.config.ConfigurationXMLStreamReader;
import org.wildfly.client.config.XMLLocation;
import org.wildfly.security.dynamic.ssl.DynamicSSLContextException;

/**
* Log messages and exceptions for Elytron.
Expand Down Expand Up @@ -213,4 +214,12 @@ ConfigXMLParseException xmlUnableToIdentifyProvider(@Param Location location, St

@Message(id = 14008, value = "WildFlyElytronClientDefaultSSLContextProvider could not obtain client default SSLContext")
NoSuchAlgorithmException couldNotObtainClientDefaultSSLContext();
@Message(id = 14009, value = "Obtaining of the default SSLContext from current authentication context resulted in exception.")
DynamicSSLContextException cannotObtainDefaultSSLContext(@Cause Throwable cause);

@Message(id = 14010, value = "Obtaining of all configured SSLContexts from current authentication context resulted in exception.")
DynamicSSLContextException cannotObtainConfiguredSSLContexts(@Cause Throwable cause);

@Message(id = 14011, value = "Obtaining of the SSLContext from current authentication context and provided URI resulted in exception.")
DynamicSSLContextException cannotObtainSSLContextForGivenURI(@Cause Throwable cause);
}
39 changes: 39 additions & 0 deletions dynamic-ssl/pom.xml
@@ -0,0 +1,39 @@
<?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>2.3.2.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>org.jboss.logging</groupId>
<artifactId>jboss-logging-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-processor</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logmanager</groupId>
<artifactId>jboss-logmanager</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,54 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2020 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed 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.wildfly.security.dynamic.ssl;

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

/**
* SSLContext that resolves which SSLContext to use based on peer's host and port information.
*
* @author <a href="mailto:dvilkola@redhat.com">Diana Krepinska (Vilkolakova)</a>
*/
public final class DynamicSSLContext extends SSLContext {

private static SSLContext resolverSSLContext(DynamicSSLContextSPI dynamicSSLContextSPIImpl) throws NoSuchAlgorithmException, DynamicSSLContextException {
return dynamicSSLContextSPIImpl.getConfiguredDefault() == null ?
SSLContext.getDefault() : dynamicSSLContextSPIImpl.getConfiguredDefault();
}

/**
* This constructor uses ServiceLoader to find provider of DynamicSSLContextSPI on classpath.
*/
public DynamicSSLContext() throws NoSuchAlgorithmException {
// this does not use provider and protocol from DynamicSSLContextSPI implementation found on classpath
// to avoid this ServiceLoader.load would have to be called 3 times in separate static method
super(new DynamicSSLContextSpiImpl(), SSLContext.getDefault().getProvider(), SSLContext.getDefault().getProtocol());
}

/**
* This constructor uses received DynamicSSLContextSPI implementation or finds it on classpath if received is null.
*
* @param dynamicSSLContextSPIImpl DynamicSSLContextSPI implementation to use. If null then ServiceLoader is used to locate it on classpath.
*/
public DynamicSSLContext(DynamicSSLContextSPI dynamicSSLContextSPIImpl) throws NoSuchAlgorithmException, DynamicSSLContextException {
super(new DynamicSSLContextSpiImpl(dynamicSSLContextSPIImpl),
resolverSSLContext(dynamicSSLContextSPIImpl).getProvider(),
resolverSSLContext(dynamicSSLContextSPIImpl).getProtocol());
}
}
@@ -0,0 +1,42 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2020 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed 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.wildfly.security.dynamic.ssl;

/**
* Exception to indicate a failure related to the DynamicSSLContext.
*
* @author <a href="mailto:dvilkola@redhat.com">Diana Krepinska (Vilkolakova)</a>
*/
public class DynamicSSLContextException extends Exception {
private static final long serialVersionUID = 894798122053539237L;

public DynamicSSLContextException() {
}

public DynamicSSLContextException(String msg) {
super(msg);
}

public DynamicSSLContextException(String message, Throwable cause) {
super(message, cause);
}

public DynamicSSLContextException(Throwable cause) {
super(cause);
}
}
@@ -0,0 +1,52 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2020 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed 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.wildfly.security.dynamic.ssl;

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

/**
* This interface provides configuration that is used by DynamicSSLContext.
*
* @author <a href="mailto:dvilkola@redhat.com">Diana Krepinska (Vilkolakova)</a>
*/
public interface DynamicSSLContextSPI {

/**
* Get SSLContext that will be used as a default, eg. when no URI is provided.
*
* @return configured default SSLContext
*/
SSLContext getConfiguredDefault() throws DynamicSSLContextException;

/**
* Get list of all configured SSLContexts. This is used to obtain cipher suites supported by all SSLContexts.
*
* @return list of all configured SSLContexts
*/
List<SSLContext> getConfiguredSSLContexts() throws DynamicSSLContextException;

/**
* Get the SSLContext that matches the given URI.
*
* @return SSLContext that matches the given URI
*/
SSLContext getSSLContext(URI uri) throws DynamicSSLContextException;
}

0 comments on commit 32aedbc

Please sign in to comment.