diff --git a/core-feature-pack/common/src/main/resources/modules/system/layers/base/org/wildfly/security/elytron-base/main/module.xml b/core-feature-pack/common/src/main/resources/modules/system/layers/base/org/wildfly/security/elytron-base/main/module.xml index 8753b51d7e9..5bd16aab8d5 100644 --- a/core-feature-pack/common/src/main/resources/modules/system/layers/base/org/wildfly/security/elytron-base/main/module.xml +++ b/core-feature-pack/common/src/main/resources/modules/system/layers/base/org/wildfly/security/elytron-base/main/module.xml @@ -34,7 +34,6 @@ - @@ -112,5 +111,6 @@ modules use the parser, they need to have visibility to this module. --> + diff --git a/core-feature-pack/common/src/main/resources/modules/system/layers/base/org/wildfly/security/elytron-dynamic-ssl/main/module.xml b/core-feature-pack/common/src/main/resources/modules/system/layers/base/org/wildfly/security/elytron-dynamic-ssl/main/module.xml new file mode 100644 index 00000000000..aef462f9edd --- /dev/null +++ b/core-feature-pack/common/src/main/resources/modules/system/layers/base/org/wildfly/security/elytron-dynamic-ssl/main/module.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core-feature-pack/galleon-common/src/main/resources/layers/standalone/elytron/layer-spec.xml b/core-feature-pack/galleon-common/src/main/resources/layers/standalone/elytron/layer-spec.xml index 2a951fd1d97..19f08ecde2b 100644 --- a/core-feature-pack/galleon-common/src/main/resources/layers/standalone/elytron/layer-spec.xml +++ b/core-feature-pack/galleon-common/src/main/resources/layers/standalone/elytron/layer-spec.xml @@ -17,5 +17,9 @@ + + diff --git a/elytron/src/main/java/org/wildfly/extension/elytron/DynamicSSLContextHelper.java b/elytron/src/main/java/org/wildfly/extension/elytron/DynamicSSLContextHelper.java new file mode 100644 index 00000000000..614e30dba06 --- /dev/null +++ b/elytron/src/main/java/org/wildfly/extension/elytron/DynamicSSLContextHelper.java @@ -0,0 +1,34 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.wildfly.extension.elytron; + +import org.wildfly.security.auth.client.AuthenticationContext; +import org.wildfly.security.dynamic.ssl.DynamicSSLContext; +import org.wildfly.security.dynamic.ssl.DynamicSSLContextImpl; +import org.wildfly.security.dynamic.ssl.DynamicSSLContextException; + +import javax.net.ssl.SSLContext; +import java.security.GeneralSecurityException; +import static org.wildfly.extension.elytron._private.ElytronSubsystemMessages.ROOT_LOGGER; + +/** + * Helper class for obtaining an instance of DynamicSSLContext created from the provided AuthenticationContext + */ +class DynamicSSLContextHelper { + + /** + * Get DynamicSSLContext instance from the provided authentication context + * @param authenticationContext authentication context to use with the DynamicSSLContext + * @return DynamicSSLContext instance + */ + static SSLContext getDynamicSSLContextInstance(AuthenticationContext authenticationContext) { + try { + return new DynamicSSLContext(new DynamicSSLContextImpl(authenticationContext)); + } catch (DynamicSSLContextException | GeneralSecurityException e) { + throw ROOT_LOGGER.unableToObtainDynamicSSLContext(); + } + } +} diff --git a/elytron/src/main/java/org/wildfly/extension/elytron/SSLDefinitions.java b/elytron/src/main/java/org/wildfly/extension/elytron/SSLDefinitions.java index 16c4aee595c..e332eabbfbd 100644 --- a/elytron/src/main/java/org/wildfly/extension/elytron/SSLDefinitions.java +++ b/elytron/src/main/java/org/wildfly/extension/elytron/SSLDefinitions.java @@ -116,15 +116,12 @@ import org.wildfly.extension.elytron._private.ElytronSubsystemMessages; import org.wildfly.extension.elytron.capabilities.PrincipalTransformer; import org.wildfly.security.auth.client.AuthenticationContext; -import org.wildfly.security.dynamic.ssl.DynamicSSLContextImpl; import org.wildfly.security.auth.server.MechanismConfiguration; import org.wildfly.security.auth.server.MechanismConfigurationSelector; import org.wildfly.security.auth.server.RealmMapper; import org.wildfly.security.auth.server.SecurityDomain; import org.wildfly.security.credential.PasswordCredential; import org.wildfly.security.credential.source.CredentialSource; -import org.wildfly.security.dynamic.ssl.DynamicSSLContext; -import org.wildfly.security.dynamic.ssl.DynamicSSLContextException; import org.wildfly.security.keystore.AliasFilter; import org.wildfly.security.keystore.FilteringKeyStore; import org.wildfly.security.password.interfaces.ClearPassword; @@ -144,6 +141,7 @@ class SSLDefinitions { private static final BooleanSupplier IS_FIPS = getFipsSupplier(); + private static final String ORG_WILDFLY_SECURITY_ELYTRON_DYNAMIC_SSL = "org.wildfly.security.elytron-dynamic-ssl"; static final ServiceUtil SERVER_SERVICE_UTIL = ServiceUtil.newInstance(SSL_CONTEXT_RUNTIME_CAPABILITY, ElytronDescriptionConstants.SERVER_SSL_CONTEXT, SSLContext.class); static final ServiceUtil CLIENT_SERVICE_UTIL = ServiceUtil.newInstance(SSL_CONTEXT_RUNTIME_CAPABILITY, ElytronDescriptionConstants.CLIENT_SSL_CONTEXT, SSLContext.class); @@ -1226,13 +1224,18 @@ private static ResourceDefinition createSSLContextDefinition(String pathKey, boo } private static ResourceDefinition createSSLContextDefinition(String pathKey, boolean server, AbstractAddStepHandler addHandler, AttributeDefinition[] attributes, boolean serverOrHostController, Stability stability) { + return createSSLContextDefinition(pathKey, server, addHandler, attributes, serverOrHostController, stability, null); + } + + private static ResourceDefinition createSSLContextDefinition(String pathKey, boolean server, AbstractAddStepHandler addHandler, AttributeDefinition[] attributes, boolean serverOrHostController, Stability stability, String dependencyPackageName) { Builder builder = TrivialResourceDefinition.builder() .setPathKey(pathKey) .setAddHandler(addHandler) .setAttributes(attributes) .setRuntimeCapabilities(SSL_CONTEXT_RUNTIME_CAPABILITY) - .setStability(stability); + .setStability(stability) + .setDependencyPackageName(dependencyPackageName); if (serverOrHostController) { builder.addReadOnlyAttribute(ACTIVE_SESSION_COUNT, new SSLContextRuntimeHandler() { @@ -1542,13 +1545,7 @@ protected ValueSupplier getValueSupplier(ServiceBuilder ServiceName acServiceName = context.getCapabilityServiceName(authenticationContextCapability, AuthenticationContext.class); Supplier authenticationContextSupplier = serviceBuilder.requires(acServiceName); - return () -> { - try { - return new DynamicSSLContext(new DynamicSSLContextImpl(authenticationContextSupplier.get())); - } catch (DynamicSSLContextException | GeneralSecurityException e) { - throw new RuntimeException(e); - } - }; + return () -> DynamicSSLContextHelper.getDynamicSSLContextInstance(authenticationContextSupplier.get()); } @Override @@ -1564,7 +1561,7 @@ protected void installedForResource(ServiceController serviceControl } }; - return createSSLContextDefinition(ElytronDescriptionConstants.DYNAMIC_CLIENT_SSL_CONTEXT, false, add, attributes, false, Stability.COMMUNITY); + return createSSLContextDefinition(ElytronDescriptionConstants.DYNAMIC_CLIENT_SSL_CONTEXT, false, add, attributes, false, Stability.COMMUNITY, ORG_WILDFLY_SECURITY_ELYTRON_DYNAMIC_SSL); } private static Provider[] filterProviders(Provider[] all, String provider) { diff --git a/elytron/src/main/java/org/wildfly/extension/elytron/TrivialResourceDefinition.java b/elytron/src/main/java/org/wildfly/extension/elytron/TrivialResourceDefinition.java index 4cb1f4a8a91..c8a9acc4d87 100644 --- a/elytron/src/main/java/org/wildfly/extension/elytron/TrivialResourceDefinition.java +++ b/elytron/src/main/java/org/wildfly/extension/elytron/TrivialResourceDefinition.java @@ -23,6 +23,7 @@ import org.jboss.as.controller.descriptions.ResourceDescriptionResolver; import org.jboss.as.controller.registry.ManagementResourceRegistration; import org.jboss.as.controller.registry.OperationEntry; +import org.jboss.as.controller.registry.RuntimePackageDependency; import org.jboss.as.version.Stability; /** @@ -36,10 +37,25 @@ final class TrivialResourceDefinition extends SimpleResourceDefinition { private final Map operations; private final Map readOnlyAttributes; private final List children; + private final String dependencyPackageName; + + TrivialResourceDefinition(String pathKey, ResourceDescriptionResolver resourceDescriptionResolver, AbstractAddStepHandler add, AttributeDefinition[] attributes, RuntimeCapability ... runtimeCapabilities) { + this(pathKey, resourceDescriptionResolver, add, new TrivialCapabilityServiceRemoveHandler(add, runtimeCapabilities), attributes, null, null, null, runtimeCapabilities, Stability.DEFAULT); + } + + TrivialResourceDefinition(String pathKey, AbstractAddStepHandler add, AttributeDefinition[] attributes, RuntimeCapability ... runtimeCapabilities) { + this(pathKey, ElytronExtension.getResourceDescriptionResolver(pathKey), add, new TrivialCapabilityServiceRemoveHandler(add, runtimeCapabilities), attributes, null, null, null, runtimeCapabilities, Stability.DEFAULT); + } + + private TrivialResourceDefinition(String pathKey, ResourceDescriptionResolver resourceDescriptionResolver, AbstractAddStepHandler add, AbstractRemoveStepHandler remove, AttributeDefinition[] attributes, + Map readOnlyAttributes, Map operations, List children, + RuntimeCapability[] runtimeCapabilities, Stability stability) { + this(pathKey, resourceDescriptionResolver, add, remove, attributes, readOnlyAttributes, operations, children, runtimeCapabilities, stability, null); + } private TrivialResourceDefinition(String pathKey, ResourceDescriptionResolver resourceDescriptionResolver, AbstractAddStepHandler add, AbstractRemoveStepHandler remove, AttributeDefinition[] attributes, Map readOnlyAttributes, Map operations, List children, - RuntimeCapability[] runtimeCapabilities, Stability stability) { + RuntimeCapability[] runtimeCapabilities, Stability stability, String dependencyPackageName) { super(new Parameters(ResourceRegistration.of(PathElement.pathElement(pathKey), stability), resourceDescriptionResolver) .setAddHandler(add) @@ -52,14 +68,7 @@ private TrivialResourceDefinition(String pathKey, ResourceDescriptionResolver re this.readOnlyAttributes = readOnlyAttributes; this.operations = operations; this.children = children; - } - - TrivialResourceDefinition(String pathKey, ResourceDescriptionResolver resourceDescriptionResolver, AbstractAddStepHandler add, AttributeDefinition[] attributes, RuntimeCapability ... runtimeCapabilities) { - this(pathKey, resourceDescriptionResolver, add, new TrivialCapabilityServiceRemoveHandler(add, runtimeCapabilities), attributes, null, null, null, runtimeCapabilities, Stability.DEFAULT); - } - - TrivialResourceDefinition(String pathKey, AbstractAddStepHandler add, AttributeDefinition[] attributes, RuntimeCapability ... runtimeCapabilities) { - this(pathKey, ElytronExtension.getResourceDescriptionResolver(pathKey), add, new TrivialCapabilityServiceRemoveHandler(add, runtimeCapabilities), attributes, null, null, null, runtimeCapabilities, Stability.DEFAULT); + this.dependencyPackageName = dependencyPackageName; } @Override @@ -97,6 +106,13 @@ public void registerChildren(ManagementResourceRegistration resourceRegistration } } + @Override + public void registerAdditionalRuntimePackages(ManagementResourceRegistration resourceRegistration) { + if (dependencyPackageName != null) { + resourceRegistration.registerAdditionalRuntimePackages(RuntimePackageDependency.required(dependencyPackageName)); + } + } + public AttributeDefinition[] getAttributes() { return attributes; } @@ -117,6 +133,7 @@ static class Builder { private RuntimeCapability[] runtimeCapabilities; private List children; private Stability stability = Stability.DEFAULT; + private String dependencyPackageName; Builder() {} @@ -189,11 +206,16 @@ Builder addChild(ResourceDefinition child) { return this; } + Builder setDependencyPackageName(String dependencyPackageName) { + this.dependencyPackageName = dependencyPackageName; + return this; + } + ResourceDefinition build() { ResourceDescriptionResolver resourceDescriptionResolver = this.resourceDescriptionResolver != null ? this.resourceDescriptionResolver : ElytronExtension.getResourceDescriptionResolver(pathKey); return new TrivialResourceDefinition(pathKey, resourceDescriptionResolver, addHandler, removeHandler != null ? removeHandler : new TrivialCapabilityServiceRemoveHandler(addHandler, runtimeCapabilities), - attributes, readOnlyAttributes, operations, children, runtimeCapabilities, stability); + attributes, readOnlyAttributes, operations, children, runtimeCapabilities, stability, dependencyPackageName); } } diff --git a/elytron/src/main/java/org/wildfly/extension/elytron/_private/ElytronSubsystemMessages.java b/elytron/src/main/java/org/wildfly/extension/elytron/_private/ElytronSubsystemMessages.java index ecb12a40f61..cae3bb34a5d 100644 --- a/elytron/src/main/java/org/wildfly/extension/elytron/_private/ElytronSubsystemMessages.java +++ b/elytron/src/main/java/org/wildfly/extension/elytron/_private/ElytronSubsystemMessages.java @@ -728,6 +728,8 @@ public interface ElytronSubsystemMessages extends BasicLogger { "use Elytron Tool command `filesystem-realm-encrypt`") OperationFailedException addSecretKeyToInitializedFilesystemRealm(); + @Message(id = 1221, value = "Unable to obtain DynamicSSLContext from the provided authentication context") + RuntimeException unableToObtainDynamicSSLContext(); /* * Don't just add new errors to the end of the file, there may be an appropriate section above for the resource. *