From cb01334e94dc44444b5aae3eb54b52aa440746a3 Mon Sep 17 00:00:00 2001 From: Martin Mazanek Date: Sat, 10 Oct 2020 08:00:48 +0200 Subject: [PATCH] [ELY-2084] Split Elytron SSL into its own subsystem and layer Removing the dependency of SSL classes on auth-related code --- pom.xml | 18 +- ssl/{ => base}/pom.xml | 31 +- .../ssl/AbstractDelegatingSSLContextSpi.java | 0 .../ssl/AbstractDelegatingSSLEngine.java | 0 .../ssl/AbstractDelegatingSSLParameters.java | 0 .../AbstractDelegatingSSLServerSocket.java | 0 ...tractDelegatingSSLServerSocketFactory.java | 0 .../AbstractDelegatingSSLSessionContext.java | 0 .../ssl/AbstractDelegatingSSLSocket.java | 0 .../AbstractDelegatingSSLSocketFactory.java | 0 .../security/ssl/AndCipherSuitePredicate.java | 0 .../wildfly/security/ssl/Authentication.java | 2 +- .../AuthenticationCipherSuitePredicate.java | 0 .../security/ssl/BaseElytronMessages.java} | 23 +- .../security/ssl/BaseSSLContextBuilder.java | 339 ++++++++++++++++++ .../ssl/BooleanCipherSuitePredicate.java | 0 .../security/ssl/CipherSuitePredicate.java | 0 .../security/ssl/CipherSuiteSelector.java | 38 +- .../security/ssl/ConfiguredSSLContextSpi.java | 0 .../security/ssl/ConfiguredSSLEngine.java | 0 .../ssl/ConfiguredSSLServerSocket.java | 0 .../ssl/ConfiguredSSLServerSocketFactory.java | 0 .../security/ssl/ConfiguredSSLSocket.java | 0 .../ssl/ConfiguredSSLSocketFactory.java | 0 .../security/ssl/DelegatingSSLContext.java | 0 .../java/org/wildfly/security/ssl/Digest.java | 0 .../ssl/DigestCipherSuitePredicate.java | 0 .../org/wildfly/security/ssl/Encryption.java | 2 +- .../ssl/EncryptionCipherSuitePredicate.java | 0 .../ssl/ExportCipherSuitePredicate.java | 0 .../ssl/FipsCipherSuitePredicate.java | 0 .../org/wildfly/security/ssl/JDKSpecific.java | 2 +- .../wildfly/security/ssl/KeyAgreement.java | 2 +- .../ssl/KeyAgreementCipherSuitePredicate.java | 0 .../ssl/LevelCipherSuitePredicate.java | 0 .../security/ssl/LinkedProperties.java | 0 .../security/ssl/MechanismDatabase.java | 2 +- .../security/ssl/MechanismDatabase.properties | 0 .../security/ssl/NotCipherSuitePredicate.java | 0 .../security/ssl/OrCipherSuitePredicate.java | 0 .../org/wildfly/security/ssl/Protocol.java | 0 .../ssl/ProtocolCipherSuitePredicate.java | 0 .../security/ssl/ProtocolSelector.java | 0 .../security/ssl/SNIContextMatcher.java | 2 +- .../wildfly/security/ssl/SNISSLContext.java | 0 .../security/ssl/SNISSLContextSpi.java | 0 .../wildfly/security/ssl/SNISSLEngine.java | 2 +- .../wildfly/security/ssl/SNISSLExplorer.java | 2 +- .../wildfly/security/ssl/SSLConfigurator.java | 0 .../security/ssl/SSLConfiguratorImpl.java | 6 +- .../ssl/SSLConnectionInformation.java | 0 .../security/ssl/SSLContextSelector.java | 0 .../org/wildfly/security/ssl/SSLExplorer.java | 30 +- .../org/wildfly/security/ssl/SSLUtils.java | 11 +- .../wildfly/security/ssl/SecurityLevel.java | 0 .../ssl/SelectingServerSSLEngine.java | 8 +- .../ssl/TLS13MechanismDatabase.properties | 0 .../ssl/WrappingX509ExtendedTrustManager.java | 0 .../ssl/X509CRLExtendedTrustManager.java | 6 +- .../ssl/X509RevocationTrustManager.java | 4 +- .../ssl/_private/SelectingContext.java | 0 .../org/wildfly/security/ssl/JDKSpecific.java | 0 .../security/ssl/CipherSuiteSelectorTest.java | 0 .../security/ssl/MechanismDatabaseTest.java | 0 ssl/domain/pom.xml | 86 +++++ .../wildfly/security/ssl/ElytronMessages.java | 64 ++++ .../security/ssl/SSLContextBuilder.java | 2 + .../ssl/SecurityDomainTrustManager.java | 0 .../ssl/DomainCipherSuiteSelectorTest.java | 26 ++ .../ssl/DomainMechanismDatabaseTest.java | 21 ++ wildfly-elytron/pom.xml | 9 + 71 files changed, 642 insertions(+), 96 deletions(-) rename ssl/{ => base}/pom.xml (89%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSessionContext.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AndCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/Authentication.java (98%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AuthenticationCipherSuitePredicate.java (100%) rename ssl/{src/main/java/org/wildfly/security/ssl/ElytronMessages.java => base/src/main/java/org/wildfly/security/ssl/BaseElytronMessages.java} (88%) create mode 100644 ssl/base/src/main/java/org/wildfly/security/ssl/BaseSSLContextBuilder.java rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/BooleanCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/CipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/CipherSuiteSelector.java (96%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLContextSpi.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLEngine.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocket.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocketFactory.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocket.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocketFactory.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/DelegatingSSLContext.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/Digest.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/DigestCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/Encryption.java (98%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/EncryptionCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/ExportCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/FipsCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/JDKSpecific.java (99%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/KeyAgreement.java (98%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/KeyAgreementCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/LevelCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/LinkedProperties.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/MechanismDatabase.java (99%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/MechanismDatabase.properties (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/NotCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/OrCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/Protocol.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/ProtocolCipherSuitePredicate.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/ProtocolSelector.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SNIContextMatcher.java (98%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SNISSLContext.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SNISSLContextSpi.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SNISSLEngine.java (99%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SNISSLExplorer.java (99%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SSLConfigurator.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SSLConfiguratorImpl.java (97%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SSLConnectionInformation.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SSLContextSelector.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SSLExplorer.java (96%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SSLUtils.java (97%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SecurityLevel.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java (98%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/TLS13MechanismDatabase.properties (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/X509CRLExtendedTrustManager.java (96%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/X509RevocationTrustManager.java (98%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/_private/SelectingContext.java (100%) rename ssl/{ => base}/src/main/java9/org/wildfly/security/ssl/JDKSpecific.java (100%) rename ssl/{ => base}/src/test/java/org/wildfly/security/ssl/CipherSuiteSelectorTest.java (100%) rename ssl/{ => base}/src/test/java/org/wildfly/security/ssl/MechanismDatabaseTest.java (100%) create mode 100644 ssl/domain/pom.xml create mode 100644 ssl/domain/src/main/java/org/wildfly/security/ssl/ElytronMessages.java rename ssl/{ => domain}/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java (99%) rename ssl/{ => domain}/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java (100%) create mode 100644 ssl/domain/src/test/java/org/wildfly/security/ssl/DomainCipherSuiteSelectorTest.java create mode 100644 ssl/domain/src/test/java/org/wildfly/security/ssl/DomainMechanismDatabaseTest.java diff --git a/pom.xml b/pom.xml index e2e11e973d9..959619b1500 100644 --- a/pom.xml +++ b/pom.xml @@ -319,7 +319,8 @@ ${project.basedir}/sasl/otp/src/main/java/; ${project.basedir}/sasl/plain/src/main/java/; ${project.basedir}/sasl/scram/src/main/java/; - ${project.basedir}/ssl/src/main/java/; + ${project.basedir}/ssl/base/src/main/java/; + ${project.basedir}/ssl/domain/src/main/java/; ${project.basedir}/tests/base/src/main/java/; ${project.basedir}/tests/common/src/main/java/; ${project.basedir}/tool/src/main/java/; @@ -789,6 +790,18 @@ wildfly-elytron-ssl ${project.version} + + org.wildfly.security + wildfly-elytron-ssl-base + ${project.version} + + + org.wildfly.security + wildfly-elytron-ssl-base + ${project.version} + test-jar + test + org.wildfly.security wildfly-elytron-ssh-util @@ -1423,7 +1436,8 @@ sasl/otp sasl/plain sasl/scram - ssl + ssl/base + ssl/domain ssh/util tool util diff --git a/ssl/pom.xml b/ssl/base/pom.xml similarity index 89% rename from ssl/pom.xml rename to ssl/base/pom.xml index c08ba555c59..5d7c97dee43 100644 --- a/ssl/pom.xml +++ b/ssl/base/pom.xml @@ -25,14 +25,15 @@ org.wildfly.security wildfly-elytron-parent 2.2.2.CR1-SNAPSHOT + ../../pom.xml 4.0.0 - wildfly-elytron-ssl + wildfly-elytron-ssl-base - WildFly Elytron - SSL - WildFly Security SSL + WildFly Elytron - SSL Base + WildFly Security - Base SSL @@ -79,6 +80,16 @@ org.apache.maven.plugins maven-jar-plugin ${version.jar.plugin} + + + + test-jar + package + + test-jar + + + @@ -93,26 +104,14 @@ - - org.wildfly.security - wildfly-elytron-auth-server - org.wildfly.security wildfly-elytron-base org.wildfly.security - wildfly-elytron-credential - - - org.wildfly.security - wildfly-elytron-auth + wildfly-elytron-provider-util - - org.wildfly.security - wildfly-elytron-util - org.wildfly.security wildfly-elytron-x500 diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSessionContext.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSessionContext.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSessionContext.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSessionContext.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AndCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AndCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AndCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AndCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/Authentication.java b/ssl/base/src/main/java/org/wildfly/security/ssl/Authentication.java similarity index 98% rename from ssl/src/main/java/org/wildfly/security/ssl/Authentication.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/Authentication.java index 6284e2fa9bf..60183eb8a46 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/Authentication.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/Authentication.java @@ -18,7 +18,7 @@ package org.wildfly.security.ssl; -import static org.wildfly.security.ssl.ElytronMessages.log; +import static org.wildfly.security.ssl.BaseElytronMessages.log; import java.util.EnumSet; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AuthenticationCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/AuthenticationCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/AuthenticationCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/AuthenticationCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ElytronMessages.java b/ssl/base/src/main/java/org/wildfly/security/ssl/BaseElytronMessages.java similarity index 88% rename from ssl/src/main/java/org/wildfly/security/ssl/ElytronMessages.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/BaseElytronMessages.java index 3f9efdbf2e7..082570352a3 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/ElytronMessages.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/BaseElytronMessages.java @@ -21,8 +21,6 @@ import static org.jboss.logging.Logger.Level.WARN; import java.security.NoSuchAlgorithmException; -import java.security.Principal; -import java.security.cert.CertificateException; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; @@ -36,11 +34,12 @@ import org.jboss.logging.annotations.MessageLogger; import org.jboss.logging.annotations.ValidIdRange; import org.jboss.logging.annotations.ValidIdRanges; -import org.wildfly.security.auth.server.RealmUnavailableException; /** * Log messages and exceptions for Elytron. * + * @apiNote Security domain-specific messages are included in {@code ElytronMessages} from module + * {@code wildfly-elytron-ssl}. The interfaces share message IDs, and they should always be modified together. * @author David M. Lloyd * @author Darran Lofthouse */ @@ -51,10 +50,10 @@ @ValidIdRange(min = 5015, max = 5017), @ValidIdRange(min = 15000, max = 15999) }) -interface ElytronMessages extends BasicLogger { +interface BaseElytronMessages extends BasicLogger { - ElytronMessages log = Logger.getMessageLogger(ElytronMessages.class, "org.wildfly.security"); - ElytronMessages tls = Logger.getMessageLogger(ElytronMessages.class, "org.wildfly.security.tls"); + BaseElytronMessages log = Logger.getMessageLogger(BaseElytronMessages.class, "org.wildfly.security"); + BaseElytronMessages tls = Logger.getMessageLogger(BaseElytronMessages.class, "org.wildfly.security.tls"); @LogMessage(level = WARN) @Message(id = 1066, value = "Invalid string count for mechanism database entry \"%s\"") @@ -107,15 +106,6 @@ interface ElytronMessages extends BasicLogger { @Message(id = 4001, value = "No algorithm found matching TLS/SSL protocol selection criteria") NoSuchAlgorithmException noAlgorithmForSslProtocol(); - @Message(id = 4002, value = "Empty certificate chain is not trusted") - CertificateException emptyChainNotTrusted(); - - @Message(id = 4003, value = "Certificate not trusted due to realm failure for principal [%s]") - CertificateException notTrustedRealmProblem(@Cause RealmUnavailableException e, Principal principal); - - @Message(id = 4004, value = "Credential validation failed: certificate is not trusted for principal [%s]") - CertificateException notTrusted(Principal principal); - @Message(id = 4005, value = "No default trust manager available") NoSuchAlgorithmException noDefaultTrustManager(); @@ -167,9 +157,6 @@ interface ElytronMessages extends BasicLogger { @Message(id = 4026, value = "Could not create trust manager [%s]") IllegalStateException sslErrorCreatingTrustManager(String name, @Cause Throwable cause); - @Message(id = 4027, value = "SecurityDomain of SSLContext does not support X509PeerCertificateChainEvidence verification") - IllegalArgumentException securityDomainOfSSLContextDoesNotSupportX509(); - @Message(id = 4029, value = "Default context cannot be null") IllegalStateException defaultContextCannotBeNull(); diff --git a/ssl/base/src/main/java/org/wildfly/security/ssl/BaseSSLContextBuilder.java b/ssl/base/src/main/java/org/wildfly/security/ssl/BaseSSLContextBuilder.java new file mode 100644 index 00000000000..a76a48e2b51 --- /dev/null +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/BaseSSLContextBuilder.java @@ -0,0 +1,339 @@ +/* + * Copyright 2023 Red Hat, Inc. + * + * 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.ssl; + +import org.wildfly.common.Assert; +import org.wildfly.security.FixedSecurityFactory; +import org.wildfly.security.OneTimeSecurityFactory; +import org.wildfly.security.SecurityFactory; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSessionContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509ExtendedKeyManager; +import javax.net.ssl.X509KeyManager; +import javax.net.ssl.X509TrustManager; +import java.security.Provider; +import java.security.Security; +import java.util.function.Supplier; + +import static org.wildfly.security.provider.util.ProviderUtil.INSTALLED_PROVIDERS; + +/** + * A class which allows building and configuration of a single client- or server-side SSL context. The builder requires, at a + * minimum, that a key manager be set; all other parameters have default values as follows: + *
    + *
  • The cipher suite selector defaults to {@link CipherSuiteSelector#openSslDefault()}
  • + *
  • The protocol suite selector defaults to {@link ProtocolSelector#DEFAULT_SELECTOR}
  • + *
  • The "require client authentication" flag defaults to {@code false}
  • + *
  • The provider supplier defaults to {@link Security#getProviders() Security::getProviders}
  • + *
+ * + * @apiNote This class is mirrored by {@code SSLContextBuilder} in module {@code wildfly-elytron-ssl}; both + * classes should always be modified together. + * @author David M. Lloyd + */ +public final class BaseSSLContextBuilder { + + // ELY-1917: This should be changed to CipherSuiteSelector.openSslCombinedDefault once we are ready to enable + // TLS 1.3 by default + private CipherSuiteSelector cipherSuiteSelector = CipherSuiteSelector.openSslDefault(); + private ProtocolSelector protocolSelector = ProtocolSelector.DEFAULT_SELECTOR; + private boolean useCipherSuitesOrder = true; + private boolean wantClientAuth; + private boolean needClientAuth; + private boolean authenticationOptional; + private boolean clientMode; + private int sessionCacheSize; + private int sessionTimeout; + private SecurityFactory keyManagerSecurityFactory; + private SecurityFactory trustManagerSecurityFactory = SSLUtils.getDefaultX509TrustManagerSecurityFactory(); + private Supplier providerSupplier = INSTALLED_PROVIDERS; + private String providerName; + private boolean wrap = true; + + + /** + * Set the cipher suite selector to use for this context. + * + * @param cipherSuiteSelector the cipher suite selector (not {@code null}) + */ + public BaseSSLContextBuilder setCipherSuiteSelector(final CipherSuiteSelector cipherSuiteSelector) { + Assert.checkNotNullParam("cipherSuiteSelector", cipherSuiteSelector); + this.cipherSuiteSelector = cipherSuiteSelector; + + return this; + } + + /** + * Set the protocol selector to use for this context. + * + * @param protocolSelector the protocol selector to use for this context (not {@code null}) + */ + public BaseSSLContextBuilder setProtocolSelector(final ProtocolSelector protocolSelector) { + Assert.checkNotNullParam("protocolSelector", protocolSelector); + this.protocolSelector = protocolSelector; + + return this; + } + + /** + * Sets whether the local cipher suites preference should be honored. + * + * @param useCipherSuitesOrder whether the local cipher suites preference should be honored. + */ + public BaseSSLContextBuilder setUseCipherSuitesOrder(final boolean useCipherSuitesOrder) { + Assert.checkNotNullParam("useCipherSuitesOrder", useCipherSuitesOrder); + this.useCipherSuitesOrder = useCipherSuitesOrder; + + return this; + } + + /** + * Force the SSLContext created by this builder to want client authentication. + * + * The SSLContext returned by this builder will be configured to want client authentication if this value is set to true OR + * of a SecurityDomain is associated. + * + * @param wantClientAuth should the SSLContext be forced to want client authentication. + */ + public BaseSSLContextBuilder setWantClientAuth(final boolean wantClientAuth) { + this.wantClientAuth = wantClientAuth; + + return this; + } + + /** + * Force the SSLContext created by this builder to need client authentication. + * + * The SSLContext returned by this builder will be configured to need client authentication if this value is set to true. + * + * @param needClientAuth should the SSLContext be forced to need client authentication. + */ + public BaseSSLContextBuilder setNeedClientAuth(final boolean needClientAuth) { + this.needClientAuth = needClientAuth; + + return this; + } + + /** + * Where a SecurityDomain is associated with this Builder if the client presents a certificate an attempt will be made to + * obtain a SecurityIdentity by using the certificate for authentication, setting this flag to {@code true} allows for a + * failed authentication to be silently ignored. + * + * This setting does not bypass any certificate checking performed by the underlying TrustManager so failure there will still cause the connection attempt to be aborted. + * + * The reason this setting would be used would be to enable a fallback to another authentication mechanism after the connection is established. + * + * Note: Where this is no security domain associated there is no authentication step so this value will be ignored. + * + * @param authenticationOptional should the authentication step be allowed to silently fail. + */ + public BaseSSLContextBuilder setAuthenticationOptional(final boolean authenticationOptional) { + this.authenticationOptional = authenticationOptional; + + return this; + } + + + /** + * Sets the size of the cache used for storing SSLSession objects. + * + * @param sessionCacheSize the size of the cache used for storing SSLSession objects. + * @return The {@link BaseSSLContextBuilder} to allow chaining of method calls. + */ + public BaseSSLContextBuilder setSessionCacheSize(final int sessionCacheSize) { + this.sessionCacheSize = sessionCacheSize; + + return this; + } + + /** + * Sets the timeout limit for SSLSession objects. + * + * @param sessionTimeout the timeout limit for SSLSession objects. + * @return The {@link BaseSSLContextBuilder} to allow chaining of method calls. + */ + public BaseSSLContextBuilder setSessionTimeout(final int sessionTimeout) { + this.sessionTimeout = sessionTimeout; + + return this; + } + + /** + * Set the factory for the key manager which should be used to hold identities for this context. + * + * @param keyManagerSecurityFactory the security factory which produces the key manager (not {@code null}) + */ + public BaseSSLContextBuilder setKeyManagerSecurityFactory(final SecurityFactory keyManagerSecurityFactory) { + Assert.checkNotNullParam("keyManagerSecurityFactory", keyManagerSecurityFactory); + this.keyManagerSecurityFactory = keyManagerSecurityFactory; + + return this; + } + + /** + * Set the key manager which should be used to hold identities for this context. + * + * @param keyManager the security factory which produces the key manager (not {@code null}) + */ + public BaseSSLContextBuilder setKeyManager(final X509ExtendedKeyManager keyManager) { + Assert.checkNotNullParam("keyManager", keyManager); + this.keyManagerSecurityFactory = new FixedSecurityFactory<>(keyManager); + + return this; + } + + /** + * Set the factory for the trust manager which should be used for the initial trust decisions during connection. + * + * @param trustManagerSecurityFactory the factory for the trust manager which should be used for the initial trust decisions during connection (not {@code null}). + */ + public BaseSSLContextBuilder setTrustManagerSecurityFactory(final SecurityFactory trustManagerSecurityFactory) { + this.trustManagerSecurityFactory = Assert.checkNotNullParam("trustManagerSecurityFactory", trustManagerSecurityFactory); + + return this; + } + + /** + * Set the trust manager which should be used to hold identities for this context. + * + * @param trustManager the trust manager which should be used to hold identities for this context (not {@code null}). + */ + public BaseSSLContextBuilder setTrustManager(final X509TrustManager trustManager) { + Assert.checkNotNullParam("trustManager", trustManager); + this.trustManagerSecurityFactory = new FixedSecurityFactory<>(trustManager); + + return this; + } + + // todo: add a setter which simply accepts a single org.wildfly.security.ssl.X500CertificateChainPrivateCredential instance + + /** + * Set the provider supplier. + * + * @param providerSupplier the provider supplier (not {@code null}) + */ + public BaseSSLContextBuilder setProviderSupplier(final Supplier providerSupplier) { + Assert.checkNotNullParam("providerSupplier", providerSupplier); + this.providerSupplier = providerSupplier; + + return this; + } + + /** + * Set the provider name. + * + * @param name the provider name (if {@code null} and provider is allowed) + * @return this builder + */ + public BaseSSLContextBuilder setProviderName(final String name) { + this.providerName = name; + return this; + } + + /** + * Set the client mode of the target SSL context. + * + * @param clientMode {@code true} to use client mode, {@code false} otherwise + * @return this builder + */ + public BaseSSLContextBuilder setClientMode(final boolean clientMode) { + this.clientMode = clientMode; + return this; + } + + /** + * Set if the configured SSL engine and sockets created using the SSL context should be wrapped to prevent modification to the configuration. + * + * Defaults to {@code true}. + * + * @param wrap should the engine or socket created by the SSL context be wrapped to prevent modification to the configuration. + * @return this builder + */ + public BaseSSLContextBuilder setWrap(final boolean wrap) { + this.wrap = wrap; + return this; + } + + /** + * Build a security factory for the new context. The factory will cache the constructed instance. + * + * @return the security factory + */ + public SecurityFactory build() { + final CipherSuiteSelector cipherSuiteSelector = this.cipherSuiteSelector; + final ProtocolSelector protocolSelector = this.protocolSelector; + final SecurityFactory trustManagerSecurityFactory = this.trustManagerSecurityFactory; + final SecurityFactory keyManagerSecurityFactory = this.keyManagerSecurityFactory; + final Supplier providerSupplier = this.providerSupplier; + final boolean clientMode = this.clientMode; + final boolean authenticationOptional = this.authenticationOptional; + final int sessionCacheSize = this.sessionCacheSize; + final int sessionTimeout = this.sessionTimeout; + final boolean wantClientAuth = this.wantClientAuth; + final boolean needClientAuth = this.needClientAuth; + final boolean useCipherSuitesOrder = this.useCipherSuitesOrder; + final boolean wrap = this.wrap; + + return new OneTimeSecurityFactory<>(() -> { + final SecurityFactory sslContextFactory = SSLUtils.createSslContextFactory(protocolSelector, providerSupplier, providerName); + // construct the original context + final SSLContext sslContext = sslContextFactory.create(); + final X509KeyManager x509KeyManager = keyManagerSecurityFactory == null ? null : keyManagerSecurityFactory.create(); + final X509TrustManager x509TrustManager = trustManagerSecurityFactory.create(); + + if (BaseElytronMessages.tls.isTraceEnabled()) { + BaseElytronMessages.tls.tracef("SSLContext initialization (no security domain):%n" + + " cipherSuiteSelector = %s%n" + + " protocolSelector = %s%n" + + " x509TrustManager = %s%n" + + " x509KeyManager = %s%n" + + " providerSupplier = %s%n" + + " clientMode = %s%n" + + " authenticationOptional = %s%n" + + " sessionCacheSize = %s%n" + + " sessionTimeout = %s%n" + + " wantClientAuth = %s%n" + + " needClientAuth = %s%n" + + " useCipherSuitesOrder = %s%n" + + " wrap = %s%n", + cipherSuiteSelector, protocolSelector, x509TrustManager, + x509KeyManager, providerSupplier, clientMode, authenticationOptional, sessionCacheSize, + sessionTimeout, wantClientAuth, needClientAuth, useCipherSuitesOrder, wrap); + } + + sslContext.init(x509KeyManager == null ? null : new KeyManager[]{ + x509KeyManager + }, new TrustManager[]{x509TrustManager}, null); + + SSLSessionContext sessionContext = clientMode ? sslContext.getClientSessionContext() : sslContext.getServerSessionContext(); + if (sessionContext != null) { + if (sessionCacheSize >= 0) sessionContext.setSessionCacheSize(sessionCacheSize); + if (sessionTimeout >= 0) sessionContext.setSessionTimeout(sessionTimeout); + } + + // now, set up the wrapping configuration + final SSLConfigurator sslConfigurator = clientMode ? + new SSLConfiguratorImpl(protocolSelector, cipherSuiteSelector, useCipherSuitesOrder) : + new SSLConfiguratorImpl(protocolSelector, cipherSuiteSelector, wantClientAuth, needClientAuth, useCipherSuitesOrder); + final ConfiguredSSLContextSpi contextSpi = new ConfiguredSSLContextSpi(sslContext, sslConfigurator, wrap); + return new DelegatingSSLContext(contextSpi); + }); + } +} diff --git a/ssl/src/main/java/org/wildfly/security/ssl/BooleanCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/BooleanCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/BooleanCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/BooleanCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/CipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/CipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/CipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/CipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/CipherSuiteSelector.java b/ssl/base/src/main/java/org/wildfly/security/ssl/CipherSuiteSelector.java similarity index 96% rename from ssl/src/main/java/org/wildfly/security/ssl/CipherSuiteSelector.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/CipherSuiteSelector.java index df9a498314c..a9066cd52c7 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/CipherSuiteSelector.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/CipherSuiteSelector.java @@ -283,23 +283,23 @@ MechanismDatabase getMechanismDatabase() { * @return the enabled mechanisms (not {@code null}) */ public String[] evaluate(String[] supportedMechanisms) { - if (ElytronMessages.tls.isTraceEnabled()) { + if (BaseElytronMessages.tls.isTraceEnabled()) { StringBuilder b = new StringBuilder(supportedMechanisms.length * 16); b.append("Evaluating filter \"").append(this).append("\" on supported mechanisms:"); for (String s : supportedMechanisms) { b.append("\n ").append(s); } - ElytronMessages.tls.trace(b); + BaseElytronMessages.tls.trace(b); } final MechanismDatabase database = getMechanismDatabase(); final LinkedHashMap supportedMap = new LinkedHashMap<>(supportedMechanisms.length); for (String supportedMechanism : supportedMechanisms) { final MechanismDatabase.Entry entry = database.getCipherSuite(supportedMechanism); if (entry != null) { - ElytronMessages.tls.tracef("Found supported mechanism %s", supportedMechanism); + BaseElytronMessages.tls.tracef("Found supported mechanism %s", supportedMechanism); supportedMap.put(entry, supportedMechanism); } else { - ElytronMessages.tls.tracef("Dropping unknown mechanism %s", supportedMechanism); + BaseElytronMessages.tls.tracef("Dropping unknown mechanism %s", supportedMechanism); } } final LinkedHashSet enabledSet = new LinkedHashSet(supportedMap.size()); @@ -450,7 +450,7 @@ public static CipherSuiteSelector fromString(String string) throws IllegalArgume break; } case '=': { - throw ElytronMessages.log.mechSelectorTokenNotAllowed("=", i.getIndex(), string); + throw BaseElytronMessages.log.mechSelectorTokenNotAllowed("=", i.getIndex(), string); } case ',': case ':': { @@ -481,13 +481,13 @@ public static CipherSuiteSelector fromString(String string) throws IllegalArgume // case "SUITEB128ONLY": return null; // case "SUITEB192": return null; default: { - throw ElytronMessages.log.mechSelectorUnknownToken(name, string); + throw BaseElytronMessages.log.mechSelectorUnknownToken(name, string); } } } break; } - throw ElytronMessages.log.mechSelectorUnexpectedChar(cp, i.getIndex(), string); + throw BaseElytronMessages.log.mechSelectorUnexpectedChar(cp, i.getIndex(), string); } } // current character should be : or EOS after parse* methods @@ -513,7 +513,7 @@ public static CipherSuiteSelector fromNamesString(String names) throws IllegalAr final MechanismDatabase database = MechanismDatabase.getTLS13Instance(); MechanismDatabase.Entry entry = database.getCipherSuiteOpenSSLName(name); if (entry == null) { - throw ElytronMessages.log.unknownCipherSuiteName(name, names); + throw BaseElytronMessages.log.unknownCipherSuiteName(name, names); } current = current.add(name); } else { @@ -580,12 +580,12 @@ private static CipherSuiteSelector parseSpecial(final CipherSuiteSelector curren switch (word) { case "STRENGTH": { if (i.hasNext() && i.next() == '=') { - throw ElytronMessages.log.mechSelectorTokenNotAllowed("=", i.getIndex(), i.drainToString()); + throw BaseElytronMessages.log.mechSelectorTokenNotAllowed("=", i.getIndex(), i.drainToString()); } return current.sortByAlgorithmKeyLength(); } default: { - throw ElytronMessages.log.mechSelectorUnknownToken(word, i.drainToString()); + throw BaseElytronMessages.log.mechSelectorUnknownToken(word, i.drainToString()); } } } @@ -598,7 +598,7 @@ private static CipherSuitePredicate parsePredicate(final CodePointIterator i, fi CipherSuitePredicate item = getSimplePredicateByName(word); if (i.hasNext() && i.next() == '+') { if (item == null) { - throw ElytronMessages.log.mechSelectorTokenNotAllowed("+", i.getIndex(), i.drainToString()); + throw BaseElytronMessages.log.mechSelectorTokenNotAllowed("+", i.getIndex(), i.drainToString()); } return parseAndPredicate(item, i); } else { @@ -734,9 +734,9 @@ void applyFilter(final Set enabled, final Map enabled, final Map enabled, final Map enabled, final Map(); pushed.add(name); iterator.remove(); - ElytronMessages.tls.tracef("Pushing cipher suite %s to end due to push rule", entry); + BaseElytronMessages.tls.tracef("Pushing cipher suite %s to end due to push rule", entry); } } if (pushed != null) { @@ -870,13 +870,13 @@ void applyFilter(final Set enabled, final Map recordLength - 4) { // 4: handshake header size - throw ElytronMessages.log.multiRecordSSLHandshake(); + throw BaseElytronMessages.log.multiRecordSSLHandshake(); } input = input.duplicate(); @@ -501,14 +501,14 @@ private static List exploreALPN(ByteBuffer input, if (extLen >= 2) { int listLen = getInt16(input); if (listLen == 0 || listLen + 2 != extLen) { - throw ElytronMessages.log.invalidTlsExt(); + throw BaseElytronMessages.log.invalidTlsExt(); } rem -= 2; while (rem > 0) { int len = getInt8(input); if (len > rem) { - throw ElytronMessages.log.notEnoughData(); + throw BaseElytronMessages.log.notEnoughData(); } byte[] b = new byte[len]; input.get(b); @@ -547,7 +547,7 @@ private static List exploreSNIExt(ByteBuffer input, if (extLen >= 2) { // "server_name" extension in ClientHello int listLen = getInt16(input); // length of server_name_list if (listLen == 0 || listLen + 2 != extLen) { - throw ElytronMessages.log.invalidTlsExt(); + throw BaseElytronMessages.log.invalidTlsExt(); } remains -= 2; // 0x02: the length field of server_name_list @@ -555,7 +555,7 @@ private static List exploreSNIExt(ByteBuffer input, int code = getInt8(input); // name_type int snLen = getInt16(input); // length field of server name if (snLen > remains) { - throw ElytronMessages.log.notEnoughData(); + throw BaseElytronMessages.log.notEnoughData(); } byte[] encoded = new byte[snLen]; input.get(encoded); @@ -564,7 +564,7 @@ private static List exploreSNIExt(ByteBuffer input, switch (code) { case StandardConstants.SNI_HOST_NAME: if (encoded.length == 0) { - throw ElytronMessages.log.emptyHostNameSni(); + throw BaseElytronMessages.log.emptyHostNameSni(); } serverName = new SNIHostName(encoded); break; @@ -573,18 +573,18 @@ private static List exploreSNIExt(ByteBuffer input, } // check for duplicated server name type if (sniMap.put(serverName.getType(), serverName) != null) { - throw ElytronMessages.log.duplicatedSniServerName(serverName.getType()); + throw BaseElytronMessages.log.duplicatedSniServerName(serverName.getType()); } remains -= encoded.length + 3; // NameType: 1 byte // HostName length: 2 bytes } } else if (extLen == 0) { // "server_name" extension in ServerHello - throw ElytronMessages.log.invalidTlsExt(); + throw BaseElytronMessages.log.invalidTlsExt(); } if (remains != 0) { - throw ElytronMessages.log.invalidTlsExt(); + throw BaseElytronMessages.log.invalidTlsExt(); } return Collections.unmodifiableList(new ArrayList<>(sniMap.values())); diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SSLUtils.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SSLUtils.java similarity index 97% rename from ssl/src/main/java/org/wildfly/security/ssl/SSLUtils.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SSLUtils.java index 4d1285a6c9a..1ebdecf43a8 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/SSLUtils.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/SSLUtils.java @@ -50,9 +50,8 @@ import org.wildfly.common.Assert; import org.wildfly.security.OneTimeSecurityFactory; import org.wildfly.security.SecurityFactory; -import org.wildfly.security.auth.server.SecurityIdentity; -import static org.wildfly.security.ssl.ElytronMessages.log; +import static org.wildfly.security.ssl.BaseElytronMessages.log; /** * SSL factories and utilities. @@ -68,7 +67,7 @@ private SSLUtils() {} private static final String SERVICE_TYPE = SSLContext.class.getSimpleName(); /** - * The key used to store the authenticated {@link SecurityIdentity} onto the {@link SSLSession}. + * The key used to store the authenticated SecurityIdentity onto the {@link SSLSession}. */ public static final String SSL_SESSION_IDENTITY_KEY = "org.wildfly.security.ssl.identity"; @@ -151,7 +150,7 @@ public static SecurityFactory createSslContextFactory(ProtocolSelect log.tracef("No %s provided by providers in %s: %s", SERVICE_TYPE, SSLUtils.class.getSimpleName(), Arrays.toString(providerSupplier.get())); } - throw ElytronMessages.log.noSslContextProvided(SERVICE_TYPE); + throw BaseElytronMessages.log.noSslContextProvided(SERVICE_TYPE); }; } @@ -163,7 +162,7 @@ public static SecurityFactory createSslContextFactory(ProtocolSelect } private static SSLContext throwIt() throws NoSuchAlgorithmException { - throw ElytronMessages.log.noSslContextProvided(SERVICE_TYPE); + throw BaseElytronMessages.log.noSslContextProvided(SERVICE_TYPE); } /** @@ -220,7 +219,7 @@ public static SecurityFactory createConfiguredSslContextFactory(Secu return (X509TrustManager) trustManager; } } - throw ElytronMessages.log.noDefaultTrustManager(); + throw BaseElytronMessages.log.noDefaultTrustManager(); }); /** diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SecurityLevel.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SecurityLevel.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SecurityLevel.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SecurityLevel.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java similarity index 98% rename from ssl/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java index 57a4b1b9188..3915f1a6692 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java @@ -329,7 +329,7 @@ public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts, fin SSLContext sslContext = selector.selectContext(SSLExplorer.explore(src)); if (sslContext == null) { // no SSL context is available - throw ElytronMessages.log.noContextForSslConnection(); + throw BaseElytronMessages.log.noContextForSslConnection(); } next = engineFunction.apply(sslContext); next.setUseClientMode(false); @@ -463,11 +463,11 @@ public boolean getEnableSessionCreation() { static final SSLEngine CLOSED_STATE = new SSLEngine() { public SSLEngineResult wrap(final ByteBuffer[] srcs, final int offset, final int length, final ByteBuffer dst) throws SSLException { - throw ElytronMessages.log.sslClosed(); + throw BaseElytronMessages.log.sslClosed(); } public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts, final int offset, final int length) throws SSLException { - throw ElytronMessages.log.sslClosed(); + throw BaseElytronMessages.log.sslClosed(); } public Runnable getDelegatedTask() { @@ -518,7 +518,7 @@ public SSLSession getSession() { } public void beginHandshake() throws SSLException { - throw ElytronMessages.log.sslClosed(); + throw BaseElytronMessages.log.sslClosed(); } public SSLEngineResult.HandshakeStatus getHandshakeStatus() { diff --git a/ssl/src/main/java/org/wildfly/security/ssl/TLS13MechanismDatabase.properties b/ssl/base/src/main/java/org/wildfly/security/ssl/TLS13MechanismDatabase.properties similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/TLS13MechanismDatabase.properties rename to ssl/base/src/main/java/org/wildfly/security/ssl/TLS13MechanismDatabase.properties diff --git a/ssl/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java b/ssl/base/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/X509CRLExtendedTrustManager.java b/ssl/base/src/main/java/org/wildfly/security/ssl/X509CRLExtendedTrustManager.java similarity index 96% rename from ssl/src/main/java/org/wildfly/security/ssl/X509CRLExtendedTrustManager.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/X509CRLExtendedTrustManager.java index 822d19282cd..0d8aa001f4a 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/X509CRLExtendedTrustManager.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/X509CRLExtendedTrustManager.java @@ -93,14 +93,14 @@ public X509CRLExtendedTrustManager(KeyStore trustStore, TrustManagerFactory trus X509TrustManager[] trustManagers = Stream.of(trustManagerFactory.getTrustManagers()).map(trustManager -> trustManager instanceof X509TrustManager ? (X509TrustManager) trustManager : null).filter(Objects::nonNull).toArray(X509TrustManager[]::new); if (trustManagers.length == 0) { - throw ElytronMessages.log.noDefaultTrustManager(); + throw BaseElytronMessages.log.noDefaultTrustManager(); } this.trustManager = trustManagers[0]; } catch (InvalidAlgorithmParameterException e) { - throw ElytronMessages.log.sslErrorCreatingRevocationTrustManager(trustManagerFactory.getAlgorithm(), e); + throw BaseElytronMessages.log.sslErrorCreatingRevocationTrustManager(trustManagerFactory.getAlgorithm(), e); } catch (GeneralSecurityException e) { - throw ElytronMessages.log.sslErrorCreatingTrustManager(getClass().getName(), e); + throw BaseElytronMessages.log.sslErrorCreatingTrustManager(getClass().getName(), e); } if (acceptedIssuers != null) { diff --git a/ssl/src/main/java/org/wildfly/security/ssl/X509RevocationTrustManager.java b/ssl/base/src/main/java/org/wildfly/security/ssl/X509RevocationTrustManager.java similarity index 98% rename from ssl/src/main/java/org/wildfly/security/ssl/X509RevocationTrustManager.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/X509RevocationTrustManager.java index aef9cf3d35e..b389462d054 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/X509RevocationTrustManager.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/X509RevocationTrustManager.java @@ -114,12 +114,12 @@ private X509RevocationTrustManager(Builder builder) { X509TrustManager[] trustManagers = Stream.of(builder.trustManagerFactory.getTrustManagers()).map(trustManager -> trustManager instanceof X509TrustManager ? (X509TrustManager) trustManager : null).filter(Objects::nonNull).toArray(X509TrustManager[]::new); if (trustManagers.length == 0) { - throw ElytronMessages.log.noDefaultTrustManager(); + throw BaseElytronMessages.log.noDefaultTrustManager(); } this.trustManager = trustManagers[0]; } catch(GeneralSecurityException e) { - throw ElytronMessages.log.sslErrorCreatingRevocationTrustManager(builder.trustManagerFactory.getAlgorithm(), e); + throw BaseElytronMessages.log.sslErrorCreatingRevocationTrustManager(builder.trustManagerFactory.getAlgorithm(), e); } if (builder.acceptedIssuers != null) { diff --git a/ssl/src/main/java/org/wildfly/security/ssl/_private/SelectingContext.java b/ssl/base/src/main/java/org/wildfly/security/ssl/_private/SelectingContext.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/_private/SelectingContext.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/_private/SelectingContext.java diff --git a/ssl/src/main/java9/org/wildfly/security/ssl/JDKSpecific.java b/ssl/base/src/main/java9/org/wildfly/security/ssl/JDKSpecific.java similarity index 100% rename from ssl/src/main/java9/org/wildfly/security/ssl/JDKSpecific.java rename to ssl/base/src/main/java9/org/wildfly/security/ssl/JDKSpecific.java diff --git a/ssl/src/test/java/org/wildfly/security/ssl/CipherSuiteSelectorTest.java b/ssl/base/src/test/java/org/wildfly/security/ssl/CipherSuiteSelectorTest.java similarity index 100% rename from ssl/src/test/java/org/wildfly/security/ssl/CipherSuiteSelectorTest.java rename to ssl/base/src/test/java/org/wildfly/security/ssl/CipherSuiteSelectorTest.java diff --git a/ssl/src/test/java/org/wildfly/security/ssl/MechanismDatabaseTest.java b/ssl/base/src/test/java/org/wildfly/security/ssl/MechanismDatabaseTest.java similarity index 100% rename from ssl/src/test/java/org/wildfly/security/ssl/MechanismDatabaseTest.java rename to ssl/base/src/test/java/org/wildfly/security/ssl/MechanismDatabaseTest.java diff --git a/ssl/domain/pom.xml b/ssl/domain/pom.xml new file mode 100644 index 00000000000..544903fd007 --- /dev/null +++ b/ssl/domain/pom.xml @@ -0,0 +1,86 @@ + + + + + + + org.wildfly.security + wildfly-elytron-parent + 2.2.2.CR1-SNAPSHOT + ../../pom.xml + + + 4.0.0 + + wildfly-elytron-ssl + + WildFly Elytron - SSL Security Domain + WildFly Security SSL with Security Domain Components + + + + org.wildfly.security + wildfly-elytron-ssl-base + + + org.wildfly.security + wildfly-elytron-auth-server + + + org.wildfly.security + wildfly-elytron-auth + + + + org.jboss.logging + jboss-logging + + + org.jboss.logging + jboss-logging-annotations + provided + + + org.jboss.logging + jboss-logging-processor + provided + + + + org.wildfly.security + wildfly-elytron-ssl-base + test-jar + test + + + junit + junit + test + + + org.jmockit + jmockit + test + + + + + diff --git a/ssl/domain/src/main/java/org/wildfly/security/ssl/ElytronMessages.java b/ssl/domain/src/main/java/org/wildfly/security/ssl/ElytronMessages.java new file mode 100644 index 00000000000..9070eb94e28 --- /dev/null +++ b/ssl/domain/src/main/java/org/wildfly/security/ssl/ElytronMessages.java @@ -0,0 +1,64 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2014 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.ssl; + +import org.jboss.logging.Logger; +import org.jboss.logging.annotations.Cause; +import org.jboss.logging.annotations.Message; +import org.jboss.logging.annotations.MessageLogger; +import org.jboss.logging.annotations.ValidIdRange; +import org.jboss.logging.annotations.ValidIdRanges; +import org.wildfly.security.auth.server.RealmUnavailableException; + +import java.security.Principal; +import java.security.cert.CertificateException; + +/** + * Log messages and exceptions for Elytron. + * + * @apiNote This interface complements {@code BaseElytronMessages} from module {@code wildfly-elytron-ssl-base} with messages + * for security domains. The interfaces share message IDs, and they should always be modified together. + * @author David M. Lloyd + * @author Darran Lofthouse + */ +@MessageLogger(projectCode = "ELY", length = 5) +@ValidIdRanges({ + @ValidIdRange(min = 1066, max = 1077), + @ValidIdRange(min = 4001, max = 4031), + @ValidIdRange(min = 5015, max = 5017), + @ValidIdRange(min = 15000, max = 15999) +}) +interface ElytronMessages extends BaseElytronMessages { + + ElytronMessages log = Logger.getMessageLogger(ElytronMessages.class, "org.wildfly.security"); + ElytronMessages tls = Logger.getMessageLogger(ElytronMessages.class, "org.wildfly.security.tls"); + + @Message(id = 4002, value = "Empty certificate chain is not trusted") + CertificateException emptyChainNotTrusted(); + + @Message(id = 4003, value = "Certificate not trusted due to realm failure for principal [%s]") + CertificateException notTrustedRealmProblem(@Cause RealmUnavailableException e, Principal principal); + + @Message(id = 4004, value = "Credential validation failed: certificate is not trusted for principal [%s]") + CertificateException notTrusted(Principal principal); + + @Message(id = 4027, value = "SecurityDomain of SSLContext does not support X509PeerCertificateChainEvidence verification") + IllegalArgumentException securityDomainOfSSLContextDoesNotSupportX509(); + +} diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java b/ssl/domain/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java rename to ssl/domain/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java index 5ca5e0e24be..2bd2767d1ab 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java +++ b/ssl/domain/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java @@ -55,6 +55,8 @@ *
  • The provider supplier defaults to {@link Security#getProviders() Security::getProviders}
  • * * + * @apiNote This class mirrors and extends {@code BaseSSLContextBuilder} in module {@code wildfly-elytron-ssl-base}; + * both classes should always be modified together. * @author David M. Lloyd */ public final class SSLContextBuilder { diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java b/ssl/domain/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java rename to ssl/domain/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java diff --git a/ssl/domain/src/test/java/org/wildfly/security/ssl/DomainCipherSuiteSelectorTest.java b/ssl/domain/src/test/java/org/wildfly/security/ssl/DomainCipherSuiteSelectorTest.java new file mode 100644 index 00000000000..39d2681bc96 --- /dev/null +++ b/ssl/domain/src/test/java/org/wildfly/security/ssl/DomainCipherSuiteSelectorTest.java @@ -0,0 +1,26 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016 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.ssl; + +/** + * Tests evaluation of {@link CipherSuiteSelector} from string. + * + * @author Ondrej Kotek + */ +public class DomainCipherSuiteSelectorTest extends CipherSuiteSelectorTest {} diff --git a/ssl/domain/src/test/java/org/wildfly/security/ssl/DomainMechanismDatabaseTest.java b/ssl/domain/src/test/java/org/wildfly/security/ssl/DomainMechanismDatabaseTest.java new file mode 100644 index 00000000000..d10d3a5a865 --- /dev/null +++ b/ssl/domain/src/test/java/org/wildfly/security/ssl/DomainMechanismDatabaseTest.java @@ -0,0 +1,21 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2014 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.ssl; + +public class DomainMechanismDatabaseTest extends MechanismDatabaseTest {} diff --git a/wildfly-elytron/pom.xml b/wildfly-elytron/pom.xml index d455ae968dd..54185cec2bb 100644 --- a/wildfly-elytron/pom.xml +++ b/wildfly-elytron/pom.xml @@ -477,6 +477,10 @@ org.wildfly.security wildfly-elytron-ssl
    + + org.wildfly.security + wildfly-elytron-ssl-base + org.wildfly.security wildfly-elytron-ssh-util @@ -858,6 +862,11 @@ wildfly-elytron-ssl ${project.version} + + org.wildfly.security + wildfly-elytron-ssl-base + ${project.version} + org.wildfly.security wildfly-elytron-tool