From 8d3e3ba920ab2668c2aeca05d56fc95e5f268e9f Mon Sep 17 00:00:00 2001 From: R Searls Date: Mon, 20 May 2024 12:04:16 -0400 Subject: [PATCH] [ELY-2517] Moved SSLContextBuilder and related files to new module wildfly-elytron-ssl-builder. --- auth/client/pom.xml | 4 + .../client/AuthenticationConfiguration.java | 2 +- .../auth/client/ElytronXmlParser.java | 2 +- .../client/AuthenticationContextTest.java | 2 +- pom.xml | 18 +- sasl/base/pom.xml | 4 + .../util/TrustManagerSaslServerFactory.java | 2 +- ssl/{ => base}/pom.xml | 1 + .../AbstractDelegatingSSLSessionContext.java | 0 .../security/ssl/AndCipherSuitePredicate.java | 0 .../wildfly/security/ssl/Authentication.java | 0 .../AuthenticationCipherSuitePredicate.java | 0 .../ssl/BooleanCipherSuitePredicate.java | 0 .../security/ssl/CipherSuitePredicate.java | 0 .../security/ssl/CipherSuiteSelector.java | 2 +- .../java/org/wildfly/security/ssl/Digest.java | 0 .../ssl/DigestCipherSuitePredicate.java | 0 .../wildfly/security/ssl/ElytronMessages.java | 169 ++++++ .../org/wildfly/security/ssl/Encryption.java | 0 .../ssl/EncryptionCipherSuitePredicate.java | 0 .../ssl/ExportCipherSuitePredicate.java | 0 .../ssl/FipsCipherSuitePredicate.java | 0 .../wildfly/security/ssl/KeyAgreement.java | 0 .../ssl/KeyAgreementCipherSuitePredicate.java | 0 .../ssl/LevelCipherSuitePredicate.java | 0 .../security/ssl/LinkedProperties.java | 0 .../security/ssl/MechanismDatabase.java | 16 +- .../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 | 2 +- .../security/ssl/SNIContextMatcher.java | 0 .../wildfly/security/ssl/SNISSLContext.java | 0 .../security/ssl/SNISSLContextSpi.java | 0 .../wildfly/security/ssl/SNISSLEngine.java | 0 .../wildfly/security/ssl/SNISSLExplorer.java | 0 .../wildfly/security/ssl/SSLConfigurator.java | 0 .../ssl/SSLConnectionInformation.java | 0 .../security/ssl/SSLContextSelector.java | 0 .../org/wildfly/security/ssl/SSLExplorer.java | 2 +- .../wildfly/security/ssl/SecurityLevel.java | 0 .../ssl/TLS13MechanismDatabase.properties | 0 .../ssl/X509CRLExtendedTrustManager.java | 0 .../ssl/X509RevocationTrustManager.java | 0 .../ssl/_private/SelectingContext.java | 0 .../org/wildfly/security/ssl/JDKSpecific.java | 0 .../security/ssl/CipherSuiteSelectorTest.java | 0 .../security/ssl/MechanismDatabaseTest.java | 0 ssl/builder/pom.xml | 134 +++++ .../AbstractDelegatingSSLContextSpi.java | 100 ++++ .../builder/AbstractDelegatingSSLEngine.java | 184 ++++++ .../AbstractDelegatingSSLParameters.java | 103 ++++ .../AbstractDelegatingSSLServerSocket.java | 186 ++++++ ...tractDelegatingSSLServerSocketFactory.java | 60 ++ .../builder/AbstractDelegatingSSLSocket.java | 314 ++++++++++ .../AbstractDelegatingSSLSocketFactory.java | 75 +++ .../ssl/builder/ConfiguredSSLContextSpi.java | 74 +++ .../ssl/builder/ConfiguredSSLEngine.java | 70 +++ .../builder/ConfiguredSSLServerSocket.java | 72 +++ .../ConfiguredSSLServerSocketFactory.java | 81 +++ .../ssl/builder/ConfiguredSSLSocket.java | 70 +++ .../builder/ConfiguredSSLSocketFactory.java | 95 +++ .../ssl/builder/DelegatingSSLContext.java | 38 ++ .../security/ssl/builder/ElytronMessages.java | 79 +++ .../security/ssl/builder/JDKSpecific.java | 229 +++++++ .../ssl/builder/SSLConfiguratorImpl.java | 202 +++++++ .../ssl/builder/SSLContextBuilder.java | 393 ++++++++++++ .../security/ssl/builder/SSLUtils.java | 480 +++++++++++++++ .../builder/SecurityDomainTrustManager.java | 161 +++++ .../ssl/builder/SelectingServerSSLEngine.java | 559 ++++++++++++++++++ .../WrappingX509ExtendedTrustManager.java | 67 +++ ssl/deprecated/pom.xml | 134 +++++ .../ssl/AbstractDelegatingSSLContextSpi.java | 1 + .../ssl/AbstractDelegatingSSLEngine.java | 1 + .../ssl/AbstractDelegatingSSLParameters.java | 1 + .../AbstractDelegatingSSLServerSocket.java | 1 + ...tractDelegatingSSLServerSocketFactory.java | 1 + .../ssl/AbstractDelegatingSSLSocket.java | 1 + .../AbstractDelegatingSSLSocketFactory.java | 1 + .../security/ssl/ConfiguredSSLContextSpi.java | 1 + .../security/ssl/ConfiguredSSLEngine.java | 1 + .../ssl/ConfiguredSSLServerSocket.java | 1 + .../ssl/ConfiguredSSLServerSocketFactory.java | 1 + .../security/ssl/ConfiguredSSLSocket.java | 1 + .../ssl/ConfiguredSSLSocketFactory.java | 1 + .../security/ssl/DelegatingSSLContext.java | 1 + .../wildfly/security/ssl/ElytronMessages.java | 3 +- .../org/wildfly/security/ssl/JDKSpecific.java | 1 + .../security/ssl/SSLConfiguratorImpl.java | 2 +- .../security/ssl/SSLContextBuilder.java | 3 +- .../org/wildfly/security/ssl/SSLUtils.java | 1 + .../ssl/SecurityDomainTrustManager.java | 1 + .../ssl/SelectingServerSSLEngine.java | 1 + .../ssl/WrappingX509ExtendedTrustManager.java | 1 + tests/base/pom.xml | 7 +- .../MaskedPasswordSSLAuthenticationTest.java | 4 +- .../realm/token/JwtSecurityRealmTest.java | 2 +- .../security/ssl/SSLAuthenticationTest.java | 2 + .../ssl/SSLv2HelloAuthenticationTest.java | 2 + .../security/ssl/TLS13AuthenticationTest.java | 2 + .../SSLConfiguratorImplTest.java | 2 +- wildfly-elytron/pom.xml | 18 + 104 files changed, 4227 insertions(+), 25 deletions(-) rename ssl/{ => base}/pom.xml (99%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSessionContext.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 (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/AuthenticationCipherSuitePredicate.java (100%) 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 (99%) 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%) create mode 100644 ssl/base/src/main/java/org/wildfly/security/ssl/ElytronMessages.java rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/Encryption.java (100%) 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/KeyAgreement.java (100%) 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 (94%) 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 (99%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SNIContextMatcher.java (100%) 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 (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SNISSLExplorer.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SSLConfigurator.java (100%) 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 (99%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/SecurityLevel.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/TLS13MechanismDatabase.properties (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/X509CRLExtendedTrustManager.java (100%) rename ssl/{ => base}/src/main/java/org/wildfly/security/ssl/X509RevocationTrustManager.java (100%) 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/builder/pom.xml create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLContextSpi.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLEngine.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLParameters.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLServerSocket.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLServerSocketFactory.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLSocket.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLSocketFactory.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLContextSpi.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLEngine.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLServerSocket.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLServerSocketFactory.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLSocket.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLSocketFactory.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/DelegatingSSLContext.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ElytronMessages.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/JDKSpecific.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLConfiguratorImpl.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLContextBuilder.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLUtils.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SecurityDomainTrustManager.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SelectingServerSSLEngine.java create mode 100644 ssl/builder/src/main/java/org/wildfly/security/ssl/builder/WrappingX509ExtendedTrustManager.java create mode 100644 ssl/deprecated/pom.xml rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLContextSpi.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLEngine.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocket.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocketFactory.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocket.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocketFactory.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/DelegatingSSLContext.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/ElytronMessages.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/JDKSpecific.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/SSLConfiguratorImpl.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/SSLUtils.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java (99%) rename ssl/{ => deprecated}/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java (99%) rename tests/base/src/test/java/org/wildfly/security/ssl/{ => builder}/SSLConfiguratorImplTest.java (99%) diff --git a/auth/client/pom.xml b/auth/client/pom.xml index 0065663bcb8..7fa2bcfcd77 100644 --- a/auth/client/pom.xml +++ b/auth/client/pom.xml @@ -80,6 +80,10 @@ org.wildfly.security wildfly-elytron-ssh-util + + org.wildfly.security + wildfly-elytron-ssl-builder + org.jboss.logging jboss-logging-annotations diff --git a/auth/client/src/main/java/org/wildfly/security/auth/client/AuthenticationConfiguration.java b/auth/client/src/main/java/org/wildfly/security/auth/client/AuthenticationConfiguration.java index d51880fb92c..b088c8f668b 100644 --- a/auth/client/src/main/java/org/wildfly/security/auth/client/AuthenticationConfiguration.java +++ b/auth/client/src/main/java/org/wildfly/security/auth/client/AuthenticationConfiguration.java @@ -125,7 +125,7 @@ import org.wildfly.security.sasl.util.SecurityProviderSaslClientFactory; import org.wildfly.security.sasl.util.ServerNameSaslClientFactory; import org.wildfly.security.ssl.SSLConnection; -import org.wildfly.security.ssl.SSLUtils; +import org.wildfly.security.ssl.builder.SSLUtils; import org.wildfly.security.x500.TrustedAuthority; /** diff --git a/auth/client/src/main/java/org/wildfly/security/auth/client/ElytronXmlParser.java b/auth/client/src/main/java/org/wildfly/security/auth/client/ElytronXmlParser.java index 967df3725b8..492a78ab254 100644 --- a/auth/client/src/main/java/org/wildfly/security/auth/client/ElytronXmlParser.java +++ b/auth/client/src/main/java/org/wildfly/security/auth/client/ElytronXmlParser.java @@ -127,7 +127,7 @@ import org.wildfly.security.sasl.util.ServiceLoaderSaslClientFactory; import org.wildfly.security.ssl.CipherSuiteSelector; import org.wildfly.security.ssl.ProtocolSelector; -import org.wildfly.security.ssl.SSLContextBuilder; +import org.wildfly.security.ssl.builder.SSLContextBuilder; import org.wildfly.security.ssl.X509RevocationTrustManager; import org.wildfly.security.ssh.util.SshUtil; diff --git a/auth/client/src/test/java/org/wildfly/security/auth/client/AuthenticationContextTest.java b/auth/client/src/test/java/org/wildfly/security/auth/client/AuthenticationContextTest.java index 7343dae4a53..0ba5ff4daa3 100644 --- a/auth/client/src/test/java/org/wildfly/security/auth/client/AuthenticationContextTest.java +++ b/auth/client/src/test/java/org/wildfly/security/auth/client/AuthenticationContextTest.java @@ -21,7 +21,7 @@ import org.junit.Test; import org.wildfly.security.SecurityFactory; -import org.wildfly.security.ssl.SSLContextBuilder; +import org.wildfly.security.ssl.builder.SSLContextBuilder; /** * @author Ondrej Lukas diff --git a/pom.xml b/pom.xml index 903e772f3f4..753748a1d88 100644 --- a/pom.xml +++ b/pom.xml @@ -432,7 +432,9 @@ ${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/deprecated/src/main/java/; + ${project.basedir}/ssl/builder/src/main/java/; ${project.basedir}/tests/base/src/main/java/; ${project.basedir}/tests/common/src/main/java/; ${project.basedir}/tool/src/main/java/; @@ -907,6 +909,16 @@ wildfly-elytron-ssl ${project.version} + + org.wildfly.security + wildfly-elytron-ssl-deprecated + ${project.version} + + + org.wildfly.security + wildfly-elytron-ssl-builder + ${project.version} + org.wildfly.security wildfly-elytron-ssh-util @@ -1553,7 +1565,9 @@ sasl/otp sasl/plain sasl/scram - ssl + ssl/base + ssl/deprecated + ssl/builder ssh/util tool util diff --git a/sasl/base/pom.xml b/sasl/base/pom.xml index 4e3cf94e504..3b5df2ed255 100644 --- a/sasl/base/pom.xml +++ b/sasl/base/pom.xml @@ -60,6 +60,10 @@ org.wildfly.security wildfly-elytron-ssl + + org.wildfly.security + wildfly-elytron-ssl-builder + org.wildfly.security wildfly-elytron-util diff --git a/sasl/base/src/main/java/org/wildfly/security/sasl/util/TrustManagerSaslServerFactory.java b/sasl/base/src/main/java/org/wildfly/security/sasl/util/TrustManagerSaslServerFactory.java index cff746cd1a0..4cdcfc35633 100644 --- a/sasl/base/src/main/java/org/wildfly/security/sasl/util/TrustManagerSaslServerFactory.java +++ b/sasl/base/src/main/java/org/wildfly/security/sasl/util/TrustManagerSaslServerFactory.java @@ -42,7 +42,7 @@ import org.wildfly.security.auth.callback.EvidenceVerifyCallback; import org.wildfly.security.auth.callback.TrustedAuthoritiesCallback; import org.wildfly.security.evidence.X509PeerCertificateChainEvidence; -import org.wildfly.security.ssl.SSLUtils; +import org.wildfly.security.ssl.builder.SSLUtils; import org.wildfly.security.x500.TrustedAuthority; import org.wildfly.security.x500.TrustedAuthority.CertificateTrustedAuthority; diff --git a/ssl/pom.xml b/ssl/base/pom.xml similarity index 99% rename from ssl/pom.xml rename to ssl/base/pom.xml index ca01f34fa0a..a1ef0a22efe 100644 --- a/ssl/pom.xml +++ b/ssl/base/pom.xml @@ -25,6 +25,7 @@ org.wildfly.security wildfly-elytron-parent 2.5.3.CR1-SNAPSHOT + ../../pom.xml 4.0.0 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/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 100% 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 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/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 99% 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..0f0899eb523 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/CipherSuiteSelector.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/CipherSuiteSelector.java @@ -39,7 +39,7 @@ public abstract class CipherSuiteSelector { final CipherSuiteSelector prev; - CipherSuiteSelector(final CipherSuiteSelector prev) { + public CipherSuiteSelector(final CipherSuiteSelector prev) { this.prev = prev; } diff --git a/ssl/src/main/java/org/wildfly/security/ssl/Digest.java b/ssl/base/src/main/java/org/wildfly/security/ssl/Digest.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/Digest.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/Digest.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/DigestCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/DigestCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/DigestCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/DigestCipherSuitePredicate.java diff --git a/ssl/base/src/main/java/org/wildfly/security/ssl/ElytronMessages.java b/ssl/base/src/main/java/org/wildfly/security/ssl/ElytronMessages.java new file mode 100644 index 00000000000..f2f2de7ddd1 --- /dev/null +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/ElytronMessages.java @@ -0,0 +1,169 @@ +/* + * 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 static org.jboss.logging.Logger.Level.WARN; + +import java.security.NoSuchAlgorithmException; + +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLProtocolException; + +import org.jboss.logging.BasicLogger; +import org.jboss.logging.Logger; +import org.jboss.logging.annotations.Cause; +import org.jboss.logging.annotations.LogMessage; +import org.jboss.logging.annotations.Message; +import org.jboss.logging.annotations.MessageLogger; +import org.jboss.logging.annotations.ValidIdRange; +import org.jboss.logging.annotations.ValidIdRanges; + +/** + * Log messages and exceptions for Elytron. + * + * @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) +}) +public interface ElytronMessages extends BasicLogger { + + ElytronMessages log = Logger.getMessageLogger(ElytronMessages.class, "org.wildfly.security"); + ElytronMessages tls = Logger.getMessageLogger(ElytronMessages.class, "org.wildfly.security.tls"); + + @LogMessage(level = WARN) + @Message(id = 1066, value = "Invalid string count for mechanism database entry \"%s\"") + void warnInvalidStringCountForMechanismDatabaseEntry(String name); + + @LogMessage(level = WARN) + @Message(id = 1067, value = "Invalid key exchange \"%s\" for mechanism database entry \"%s\"") + void warnInvalidKeyExchangeForMechanismDatabaseEntry(String value, String name); + + @LogMessage(level = WARN) + @Message(id = 1068, value = "Invalid authentication \"%s\" for mechanism database entry \"%s\"") + void warnInvalidAuthenticationForMechanismDatabaseEntry(String value, String name); + + @LogMessage(level = WARN) + @Message(id = 1069, value = "Invalid encryption \"%s\" for mechanism database entry \"%s\"") + void warnInvalidEncryptionForMechanismDatabaseEntry(String value, String name); + + @LogMessage(level = WARN) + @Message(id = 1070, value = "Invalid digest \"%s\" for mechanism database entry \"%s\"") + void warnInvalidDigestForMechanismDatabaseEntry(String value, String name); + + @LogMessage(level = WARN) + @Message(id = 1071, value = "Invalid protocol \"%s\" for mechanism database entry \"%s\"") + void warnInvalidProtocolForMechanismDatabaseEntry(String value, String name); + + @LogMessage(level = WARN) + @Message(id = 1072, value = "Invalid level \"%s\" for mechanism database entry \"%s\"") + void warnInvalidLevelForMechanismDatabaseEntry(String value, String name); + + @LogMessage(level = WARN) + @Message(id = 1073, value = "Invalid strength bits \"%s\" for mechanism database entry \"%s\"") + void warnInvalidStrengthBitsForMechanismDatabaseEntry(String value, String name); + + @LogMessage(level = WARN) + @Message(id = 1074, value = "Invalid algorithm bits \"%s\" for mechanism database entry \"%s\"") + void warnInvalidAlgorithmBitsForMechanismDatabaseEntry(String value, String name); + + @LogMessage(level = WARN) + @Message(id = 1075, value = "Invalid duplicate mechanism database entry \"%s\"") + void warnInvalidDuplicateMechanismDatabaseEntry(String name); + + @LogMessage(level = WARN) + @Message(id = 1076, value = "Invalid duplicate OpenSSL-style alias \"%s\" for mechanism database entry \"%s\" (original is \"%s\")") + void warnInvalidDuplicateOpenSslStyleAliasForMechanismDatabaseEntry(String alias, String name, String originalName); + + @LogMessage(level = WARN) + @Message(id = 1077, value = "Invalid alias \"%s\" for missing mechanism database entry \"%s\"") + void warnInvalidAliasForMissingMechanismDatabaseEntry(String value, String name); + + @Message(id = 4001, value = "No algorithm found matching TLS/SSL protocol selection criteria") + NoSuchAlgorithmException noAlgorithmForSslProtocol(); + + @Message(id = 4005, value = "No default trust manager available") + NoSuchAlgorithmException noDefaultTrustManager(); + + @Message(id = 4008, value = "Initial SSL/TLS data is not a handshake record") + SSLHandshakeException notHandshakeRecord(); + + @Message(id = 4009, value = "Initial SSL/TLS handshake record is invalid") + SSLHandshakeException invalidHandshakeRecord(); + + @Message(id = 4010, value = "Initial SSL/TLS handshake spans multiple records") + SSLHandshakeException multiRecordSSLHandshake(); + + @Message(id = 4011, value = "Expected \"client hello\" record") + SSLHandshakeException expectedClientHello(); + + @Message(id = 4012, value = "Unsupported SSL/TLS record") + SSLHandshakeException unsupportedSslRecord(); + + @Message(id = 4013, value = "Invalid TLS extension data") + SSLProtocolException invalidTlsExt(); + + @Message(id = 4014, value = "Not enough data in record to fill declared item size") + SSLProtocolException notEnoughData(); + + @Message(id = 4015, value = "Empty host name in SNI record data") + SSLProtocolException emptyHostNameSni(); + + @Message(id = 4016, value = "Duplicated SNI server name of type %d") + SSLProtocolException duplicatedSniServerName(int type); + + @Message(id = 4017, value = "Unknown authentication name \"%s\"") + IllegalArgumentException unknownAuthenticationName(String name); + + @Message(id = 4018, value = "Unknown encryption name \"%s\"") + IllegalArgumentException unknownEncryptionName(String name); + + @Message(id = 4019, value = "Unknown key exchange name \"%s\"") + IllegalArgumentException unknownKeyExchangeName(String name); + + @Message(id = 4026, value = "Could not create trust manager [%s]") + IllegalStateException sslErrorCreatingTrustManager(String name, @Cause Throwable cause); + + @Message(id = 4029, value = "Default context cannot be null") + IllegalStateException defaultContextCannotBeNull(); + + @Message(id = 4030, value = "No context for SSL connection") + SSLException noSNIContextForSslConnection(); // TODO Compare with noContextForSslConnection. + + @Message(id = 4031, value = "TrustManagerFactory algorithm [%s] does not support certificate revocation") + IllegalStateException sslErrorCreatingRevocationTrustManager(String name, @Cause Throwable cause); + + @Message(id = 5015, value = "Unexpected character U+%04x at offset %d of mechanism selection string \"%s\"") + IllegalArgumentException mechSelectorUnexpectedChar(int codePoint, long offset, String string); + + @Message(id = 5016, value = "Unrecognized token \"%s\" in mechanism selection string \"%s\"") + IllegalArgumentException mechSelectorUnknownToken(String word, String string); + + @Message(id = 5017, value = "Token \"%s\" not allowed at offset %d of mechanism selection string \"%s\"") + IllegalArgumentException mechSelectorTokenNotAllowed(String token, long offset, String string); + + @Message(id = 15000, value = "Unknown cipher suite name '%s' in names string '%s'") + IllegalArgumentException unknownCipherSuiteName(String name, String string); +} diff --git a/ssl/src/main/java/org/wildfly/security/ssl/Encryption.java b/ssl/base/src/main/java/org/wildfly/security/ssl/Encryption.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/Encryption.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/Encryption.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/EncryptionCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/EncryptionCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/EncryptionCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/EncryptionCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ExportCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/ExportCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/ExportCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/ExportCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/FipsCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/FipsCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/FipsCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/FipsCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/KeyAgreement.java b/ssl/base/src/main/java/org/wildfly/security/ssl/KeyAgreement.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/KeyAgreement.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/KeyAgreement.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/KeyAgreementCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/KeyAgreementCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/KeyAgreementCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/KeyAgreementCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/LevelCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/LevelCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/LevelCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/LevelCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/LinkedProperties.java b/ssl/base/src/main/java/org/wildfly/security/ssl/LinkedProperties.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/LinkedProperties.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/LinkedProperties.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/MechanismDatabase.java b/ssl/base/src/main/java/org/wildfly/security/ssl/MechanismDatabase.java similarity index 94% rename from ssl/src/main/java/org/wildfly/security/ssl/MechanismDatabase.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/MechanismDatabase.java index ae857041f91..85b6ab36636 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/MechanismDatabase.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/MechanismDatabase.java @@ -34,7 +34,7 @@ import java.util.Map; import java.util.regex.Pattern; -class MechanismDatabase { +public class MechanismDatabase { private static final MechanismDatabase INSTANCE = new MechanismDatabase("MechanismDatabase.properties"); private static final MechanismDatabase TLS13_INSTANCE = new MechanismDatabase("TLS13MechanismDatabase.properties", true); @@ -43,19 +43,19 @@ class MechanismDatabase { private final Entry[][] algorithmsById; private final boolean isTLS13; - static MechanismDatabase getInstance() { + public static MechanismDatabase getInstance() { return INSTANCE; } - static MechanismDatabase getTLS13Instance() { + public static MechanismDatabase getTLS13Instance() { return TLS13_INSTANCE; } - MechanismDatabase(String databaseFileName) { + public MechanismDatabase(String databaseFileName) { this(databaseFileName, false); } - MechanismDatabase(String databaseFileName, boolean isTLS13) { + public MechanismDatabase(String databaseFileName, boolean isTLS13) { this.isTLS13 = isTLS13; // load and initialize database properties final LinkedProperties properties = new LinkedProperties(); @@ -263,7 +263,7 @@ Entry getCipherSuiteOpenSSLName(final String cipherSuite) { return entriesByOSSLName.get(cipherSuite); } - Entry getCipherSuiteById(final int byte1, final int byte2) { + public Entry getCipherSuiteById(final int byte1, final int byte2) { if (byte1 < 0 || byte1 > 255 || byte2 < 0 || byte2 > 255) { return null; } @@ -278,7 +278,7 @@ boolean isTLS13() { return isTLS13; } - static final class Entry { + public static final class Entry { private final String name; private final List openSslNames; private final List aliases; @@ -293,7 +293,7 @@ static final class Entry { private final int strengthBits; private final int algorithmBits; - Entry(final String name, final List openSslNames, final List aliases, final KeyAgreement keyAgreement, final Authentication authentication, final Encryption encryption, final Digest digest, final Protocol protocol, final boolean export, final SecurityLevel level, final boolean fips, final int strengthBits, final int algorithmBits) { + public Entry(final String name, final List openSslNames, final List aliases, final KeyAgreement keyAgreement, final Authentication authentication, final Encryption encryption, final Digest digest, final Protocol protocol, final boolean export, final SecurityLevel level, final boolean fips, final int strengthBits, final int algorithmBits) { this.name = name; this.openSslNames = openSslNames; this.aliases = aliases; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/MechanismDatabase.properties b/ssl/base/src/main/java/org/wildfly/security/ssl/MechanismDatabase.properties similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/MechanismDatabase.properties rename to ssl/base/src/main/java/org/wildfly/security/ssl/MechanismDatabase.properties diff --git a/ssl/src/main/java/org/wildfly/security/ssl/NotCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/NotCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/NotCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/NotCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/OrCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/OrCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/OrCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/OrCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/Protocol.java b/ssl/base/src/main/java/org/wildfly/security/ssl/Protocol.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/Protocol.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/Protocol.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ProtocolCipherSuitePredicate.java b/ssl/base/src/main/java/org/wildfly/security/ssl/ProtocolCipherSuitePredicate.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/ProtocolCipherSuitePredicate.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/ProtocolCipherSuitePredicate.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ProtocolSelector.java b/ssl/base/src/main/java/org/wildfly/security/ssl/ProtocolSelector.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/ProtocolSelector.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/ProtocolSelector.java index 2ee4094dde0..687a931be42 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/ProtocolSelector.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/ProtocolSelector.java @@ -36,7 +36,7 @@ public abstract class ProtocolSelector { final ProtocolSelector prev; - ProtocolSelector(final ProtocolSelector prev) { + public ProtocolSelector(final ProtocolSelector prev) { this.prev = prev; } diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SNIContextMatcher.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SNIContextMatcher.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SNIContextMatcher.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SNIContextMatcher.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SNISSLContext.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SNISSLContext.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SNISSLContext.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SNISSLContext.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SNISSLContextSpi.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SNISSLContextSpi.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SNISSLContextSpi.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SNISSLContextSpi.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SNISSLEngine.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SNISSLEngine.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SNISSLEngine.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SNISSLEngine.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SNISSLExplorer.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SNISSLExplorer.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SNISSLExplorer.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SNISSLExplorer.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SSLConfigurator.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SSLConfigurator.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SSLConfigurator.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SSLConfigurator.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SSLConnectionInformation.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SSLConnectionInformation.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SSLConnectionInformation.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SSLConnectionInformation.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SSLContextSelector.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SSLContextSelector.java similarity index 100% rename from ssl/src/main/java/org/wildfly/security/ssl/SSLContextSelector.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SSLContextSelector.java diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SSLExplorer.java b/ssl/base/src/main/java/org/wildfly/security/ssl/SSLExplorer.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/SSLExplorer.java rename to ssl/base/src/main/java/org/wildfly/security/ssl/SSLExplorer.java index 26a2cf0229d..0d53a374ee5 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/SSLExplorer.java +++ b/ssl/base/src/main/java/org/wildfly/security/ssl/SSLExplorer.java @@ -51,7 +51,7 @@ * Instances of this class acts as an explorer of the network data of an * SSL/TLS connection. */ -final class SSLExplorer { +public final class SSLExplorer { // Private constructor prevents construction outside this class. private SSLExplorer() { 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/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/X509CRLExtendedTrustManager.java b/ssl/base/src/main/java/org/wildfly/security/ssl/X509CRLExtendedTrustManager.java similarity index 100% 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 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 100% 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 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/builder/pom.xml b/ssl/builder/pom.xml new file mode 100644 index 00000000000..bdf5acdf930 --- /dev/null +++ b/ssl/builder/pom.xml @@ -0,0 +1,134 @@ + + + + + + + org.wildfly.security + wildfly-elytron-parent + 2.5.3.CR1-SNAPSHOT + ../../pom.xml + + + 4.0.0 + + wildfly-elytron-ssl-builder + + WildFly Elytron - SSL + WildFly Security SSL + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0-jboss-1 + + + default-compile + compile + + compile + + + 8 + ${project.build.directory} + ${project.compileSourceRoots} + ${project.build.outputDirectory} + + ${project.build.directory}/jdk-misc.jar + + + + + compile-java9 + compile + + compile + + + 9 + ${project.build.directory} + ${project.basedir}/src/main/java9 + ${project.build.directory}/classes/META-INF/versions/9 + + ${project.build.outputDirectory} + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${version.jar.plugin} + + + + true + ${project.version} + ${project.artifactId} + + + + + + + + + + org.wildfly.security + wildfly-elytron-auth-server + + + org.wildfly.security + wildfly-elytron-base + + + org.wildfly.security + wildfly-elytron-credential + + + org.wildfly.security + wildfly-elytron-ssl + + + org.wildfly.security + wildfly-elytron-x500 + + + + org.jboss.logging + jboss-logging + + + org.jboss.logging + jboss-logging-annotations + provided + + + org.jboss.logging + jboss-logging-processor + provided + + + + diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLContextSpi.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLContextSpi.java new file mode 100644 index 00000000000..4cdba30d51b --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLContextSpi.java @@ -0,0 +1,100 @@ +/* + * 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.builder; + +import java.security.KeyManagementException; +import java.security.SecureRandom; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLContextSpi; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSessionContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; + +/** + * An SSL context SPI implementation which delegates to another SSL context. + * + * @author David M. Lloyd + */ +abstract class AbstractDelegatingSSLContextSpi extends SSLContextSpi { + private final SSLContext delegate; + + /** + * Construct a new instance. + * + * @param delegate the SSL context to delegate + */ + protected AbstractDelegatingSSLContextSpi(final SSLContext delegate) { + this.delegate = delegate; + } + + protected void engineInit(final KeyManager[] km, final TrustManager[] tm, final SecureRandom sr) throws KeyManagementException { + delegate.init(km, tm, sr); + } + + protected SSLSocketFactory engineGetSocketFactory() { + return delegate.getSocketFactory(); + } + + protected SSLServerSocketFactory engineGetServerSocketFactory() { + return delegate.getServerSocketFactory(); + } + + protected SSLEngine engineCreateSSLEngine() { + return delegate.createSSLEngine(); + } + + protected SSLEngine engineCreateSSLEngine(final String host, final int port) { + return delegate.createSSLEngine(host, port); + } + + protected SSLSessionContext engineGetServerSessionContext() { + return delegate.getServerSessionContext(); + } + + protected SSLSessionContext engineGetClientSessionContext() { + return delegate.getClientSessionContext(); + } + + protected SSLParameters engineGetDefaultSSLParameters() { + return delegate.getDefaultSSLParameters(); + } + + protected SSLParameters engineGetSupportedSSLParameters() { + return delegate.getSupportedSSLParameters(); + } + + /** + * Get the delegate SSL context. + * + * @return the delegate SSL context + */ + protected SSLContext getDelegate() { + return delegate; + } + + @Override + public String toString() { + return super.toString() + "->" + delegate.toString(); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLEngine.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLEngine.java new file mode 100644 index 00000000000..842a8c2aafd --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLEngine.java @@ -0,0 +1,184 @@ +/* + * 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.builder; + +import java.nio.ByteBuffer; +import java.util.List; +import java.util.function.BiFunction; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSession; + +/** + * @author David M. Lloyd + */ +abstract class AbstractDelegatingSSLEngine extends SSLEngine { + private final SSLEngine delegate; + + protected AbstractDelegatingSSLEngine(final SSLEngine delegate) { + this.delegate = delegate; + } + + public String getPeerHost() { + return delegate.getPeerHost(); + } + + public int getPeerPort() { + return delegate.getPeerPort(); + } + + public SSLEngineResult wrap(final ByteBuffer src, final ByteBuffer dst) throws SSLException { + return delegate.wrap(src, dst); + } + + public SSLEngineResult wrap(final ByteBuffer[] srcs, final int offset, final int length, final ByteBuffer dst) throws SSLException { + return delegate.wrap(srcs, offset, length, dst); + } + + public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer dst) throws SSLException { + return delegate.unwrap(src, dst); + } + + public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts, final int offset, final int length) throws SSLException { + return delegate.unwrap(src, dsts, offset, length); + } + + public Runnable getDelegatedTask() { + return delegate.getDelegatedTask(); + } + + public void closeInbound() throws SSLException { + delegate.closeInbound(); + } + + public boolean isInboundDone() { + return delegate.isInboundDone(); + } + + public void closeOutbound() { + delegate.closeOutbound(); + } + + public boolean isOutboundDone() { + return delegate.isOutboundDone(); + } + + public String[] getSupportedCipherSuites() { + return delegate.getSupportedCipherSuites(); + } + + public String[] getEnabledCipherSuites() { + return delegate.getEnabledCipherSuites(); + } + + public void setEnabledCipherSuites(final String[] suites) { + delegate.setEnabledCipherSuites(suites); + } + + public String[] getSupportedProtocols() { + return delegate.getSupportedProtocols(); + } + + public String[] getEnabledProtocols() { + return delegate.getEnabledProtocols(); + } + + public void setEnabledProtocols(final String[] protocols) { + delegate.setEnabledProtocols(protocols); + } + + public SSLSession getSession() { + return delegate.getSession(); + } + + public SSLSession getHandshakeSession() { + return delegate.getHandshakeSession(); + } + + public void beginHandshake() throws SSLException { + delegate.beginHandshake(); + } + + public SSLEngineResult.HandshakeStatus getHandshakeStatus() { + return delegate.getHandshakeStatus(); + } + + public void setUseClientMode(final boolean mode) { + delegate.setUseClientMode(mode); + } + + public boolean getUseClientMode() { + return delegate.getUseClientMode(); + } + + public void setNeedClientAuth(final boolean need) { + delegate.setNeedClientAuth(need); + } + + public boolean getNeedClientAuth() { + return delegate.getNeedClientAuth(); + } + + public void setWantClientAuth(final boolean want) { + delegate.setWantClientAuth(want); + } + + public boolean getWantClientAuth() { + return delegate.getWantClientAuth(); + } + + public void setEnableSessionCreation(final boolean flag) { + delegate.setEnableSessionCreation(flag); + } + + public boolean getEnableSessionCreation() { + return delegate.getEnableSessionCreation(); + } + + public SSLParameters getSSLParameters() { + return delegate.getSSLParameters(); + } + + public void setSSLParameters(final SSLParameters params) { + delegate.setSSLParameters(params); + } + + public String getApplicationProtocol() { + return JDKSpecific.getApplicationProtocol(delegate); + } + + public String getHandshakeApplicationProtocol() { + return JDKSpecific.getApplicationProtocol(delegate); + } + + public void setHandshakeApplicationProtocolSelector(BiFunction, String> selector) { + JDKSpecific.setHandshakeApplicationProtocolSelector(delegate, selector); + } + + public BiFunction, String> getHandshakeApplicationProtocolSelector() { + return JDKSpecific.getHandshakeApplicationProtocolSelector(delegate); + } + + protected SSLEngine getDelegate() { + return delegate; + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLParameters.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLParameters.java new file mode 100644 index 00000000000..c26e7a2ea89 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLParameters.java @@ -0,0 +1,103 @@ +/* + * 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.builder; + +import java.security.AlgorithmConstraints; + +import javax.net.ssl.SSLParameters; + +/** + * @author David M. Lloyd + */ +abstract class AbstractDelegatingSSLParameters extends SSLParameters { + private final SSLParameters delegate; + + protected AbstractDelegatingSSLParameters(final SSLParameters delegate) { + this.delegate = delegate; + } + + public String[] getCipherSuites() { + return delegate.getCipherSuites(); + } + + public void setCipherSuites(final String[] cipherSuites) { + delegate.setCipherSuites(cipherSuites); + } + + public String[] getProtocols() { + return delegate.getProtocols(); + } + + public void setProtocols(final String[] protocols) { + delegate.setProtocols(protocols); + } + + public boolean getWantClientAuth() { + return delegate.getWantClientAuth(); + } + + public void setWantClientAuth(final boolean wantClientAuth) { + delegate.setWantClientAuth(wantClientAuth); + } + + public boolean getNeedClientAuth() { + return delegate.getNeedClientAuth(); + } + + public void setNeedClientAuth(final boolean needClientAuth) { + delegate.setNeedClientAuth(needClientAuth); + } + + /*===== since 1.7 =====*/ + + public AlgorithmConstraints getAlgorithmConstraints() { + return delegate.getAlgorithmConstraints(); + } + + public void setAlgorithmConstraints(final AlgorithmConstraints constraints) { + delegate.setAlgorithmConstraints(constraints); + } + + public String getEndpointIdentificationAlgorithm() { + return delegate.getEndpointIdentificationAlgorithm(); + } + + public void setEndpointIdentificationAlgorithm(final String algorithm) { + delegate.setEndpointIdentificationAlgorithm(algorithm); + } + + /*===== since Java 8u251 JEP-244 =====*/ + + public String[] getApplicationProtocols() { + return JDKSpecific.getApplicationProtocols(delegate); + } + + public void setApplicationProtocols(String[] protocols) { + JDKSpecific.setApplicationProtocols(delegate, protocols); + } + + /*==== 1.8 special ====*/ + + protected void copyJdk8FinalParameters() { + setServerNames(delegate.getServerNames()); + setSNIMatchers(delegate.getSNIMatchers()); + setUseCipherSuitesOrder(delegate.getUseCipherSuitesOrder()); + } + +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLServerSocket.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLServerSocket.java new file mode 100644 index 00000000000..ba450c99444 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLServerSocket.java @@ -0,0 +1,186 @@ +/* + * 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.builder; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketImplFactory; +import java.nio.channels.ServerSocketChannel; + +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLServerSocket; + +/** + * @author David M. Lloyd + */ +abstract class AbstractDelegatingSSLServerSocket extends SSLServerSocket { + private final SSLServerSocket delegate; + + AbstractDelegatingSSLServerSocket(final SSLServerSocket delegate) throws IOException { + this.delegate = delegate; + } + + public void bind(final SocketAddress endpoint) throws IOException { + delegate.bind(endpoint); + } + + public void bind(final SocketAddress endpoint, final int backlog) throws IOException { + delegate.bind(endpoint, backlog); + } + + public InetAddress getInetAddress() { + return delegate.getInetAddress(); + } + + public int getLocalPort() { + return delegate.getLocalPort(); + } + + public SocketAddress getLocalSocketAddress() { + return delegate.getLocalSocketAddress(); + } + + public Socket accept() throws IOException { + return delegate.accept(); + } + + public void close() throws IOException { + delegate.close(); + } + + public ServerSocketChannel getChannel() { + return delegate.getChannel(); + } + + public boolean isBound() { + return delegate.isBound(); + } + + public boolean isClosed() { + return delegate.isClosed(); + } + + public void setSoTimeout(final int timeout) throws SocketException { + delegate.setSoTimeout(timeout); + } + + public int getSoTimeout() throws IOException { + return delegate.getSoTimeout(); + } + + public void setReuseAddress(final boolean on) throws SocketException { + delegate.setReuseAddress(on); + } + + public boolean getReuseAddress() throws SocketException { + return delegate.getReuseAddress(); + } + + public String toString() { + return delegate.toString(); + } + + public static void setSocketFactory(final SocketImplFactory fac) throws IOException { + ServerSocket.setSocketFactory(fac); + } + + public void setReceiveBufferSize(final int size) throws SocketException { + delegate.setReceiveBufferSize(size); + } + + public int getReceiveBufferSize() throws SocketException { + return delegate.getReceiveBufferSize(); + } + + public void setPerformancePreferences(final int connectionTime, final int latency, final int bandwidth) { + delegate.setPerformancePreferences(connectionTime, latency, bandwidth); + } + + public String[] getEnabledCipherSuites() { + return delegate.getEnabledCipherSuites(); + } + + public void setEnabledCipherSuites(final String[] names) throws IllegalArgumentException { + delegate.setEnabledCipherSuites(names); + } + + public String[] getSupportedCipherSuites() { + return delegate.getSupportedCipherSuites(); + } + + public String[] getSupportedProtocols() { + return delegate.getSupportedProtocols(); + } + + public String[] getEnabledProtocols() { + return delegate.getEnabledProtocols(); + } + + public void setEnabledProtocols(final String[] names) throws IllegalArgumentException { + delegate.setEnabledProtocols(names); + } + + public void setNeedClientAuth(final boolean need) { + delegate.setNeedClientAuth(need); + } + + public boolean getNeedClientAuth() { + return delegate.getNeedClientAuth(); + } + + public void setWantClientAuth(final boolean want) { + delegate.setWantClientAuth(want); + } + + public boolean getWantClientAuth() { + return delegate.getWantClientAuth(); + } + + public void setUseClientMode(final boolean clientMode) { + delegate.setUseClientMode(clientMode); + } + + public boolean getUseClientMode() { + return delegate.getUseClientMode(); + } + + public void setEnableSessionCreation(final boolean enabled) { + delegate.setEnableSessionCreation(enabled); + } + + public boolean getEnableSessionCreation() { + return delegate.getEnableSessionCreation(); + } + + public SSLParameters getSSLParameters() { + return delegate.getSSLParameters(); + } + + public void setSSLParameters(final SSLParameters parameters) { + delegate.setSSLParameters(parameters); + } + + protected SSLServerSocket getDelegate() { + return delegate; + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLServerSocketFactory.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLServerSocketFactory.java new file mode 100644 index 00000000000..19f42d6e671 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLServerSocketFactory.java @@ -0,0 +1,60 @@ +/* + * 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.builder; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; + +import javax.net.ssl.SSLServerSocketFactory; + +/** + * @author David M. Lloyd + */ +abstract class AbstractDelegatingSSLServerSocketFactory extends SSLServerSocketFactory { + private final SSLServerSocketFactory delegate; + + AbstractDelegatingSSLServerSocketFactory(final SSLServerSocketFactory delegate) { + this.delegate = delegate; + } + + public String[] getDefaultCipherSuites() { + return delegate.getDefaultCipherSuites(); + } + + public String[] getSupportedCipherSuites() { + return delegate.getSupportedCipherSuites(); + } + + public ServerSocket createServerSocket() throws IOException { + return delegate.createServerSocket(); + } + + public ServerSocket createServerSocket(final int port) throws IOException { + return delegate.createServerSocket(port); + } + + public ServerSocket createServerSocket(final int port, final int backlog) throws IOException { + return delegate.createServerSocket(port, backlog); + } + + public ServerSocket createServerSocket(final int port, final int backlog, final InetAddress ifAddress) throws IOException { + return delegate.createServerSocket(port, backlog, ifAddress); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLSocket.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLSocket.java new file mode 100644 index 00000000000..f19b852afaa --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLSocket.java @@ -0,0 +1,314 @@ +/* + * 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.builder; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.SocketAddress; +import java.net.SocketException; +import java.nio.channels.SocketChannel; +import java.util.List; +import java.util.function.BiFunction; + +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; + +/** + * @author David M. Lloyd + */ +abstract class AbstractDelegatingSSLSocket extends SSLSocket { + + private final SSLSocket delegate; + + AbstractDelegatingSSLSocket(final SSLSocket delegate) { + this.delegate = delegate; + } + + public String getApplicationProtocol() { + return JDKSpecific.getApplicationProtocol(delegate); + } + + public String getHandshakeApplicationProtocol() { + return JDKSpecific.getHandshakeApplicationProtocol(delegate); + } + + public void setHandshakeApplicationProtocolSelector(BiFunction, String> selector) { + JDKSpecific.setHandshakeApplicationProtocolSelector(delegate, selector); + } + + public BiFunction, String> getHandshakeApplicationProtocolSelector() { + return JDKSpecific.getHandshakeApplicationProtocolSelector(delegate); + } + + public String[] getSupportedCipherSuites() { + return delegate.getSupportedCipherSuites(); + } + + public String[] getEnabledCipherSuites() { + return delegate.getEnabledCipherSuites(); + } + + public void setEnabledCipherSuites(final String[] suites) { + delegate.setEnabledCipherSuites(suites); + } + + public String[] getSupportedProtocols() { + return delegate.getSupportedProtocols(); + } + + public String[] getEnabledProtocols() { + return delegate.getEnabledProtocols(); + } + + public void setEnabledProtocols(final String[] protocols) { + delegate.setEnabledProtocols(protocols); + } + + public SSLSession getSession() { + return delegate.getSession(); + } + + public SSLSession getHandshakeSession() { + return delegate.getHandshakeSession(); + } + + public void addHandshakeCompletedListener(final HandshakeCompletedListener listener) { + delegate.addHandshakeCompletedListener(listener); + } + + public void removeHandshakeCompletedListener(final HandshakeCompletedListener listener) { + delegate.removeHandshakeCompletedListener(listener); + } + + public void startHandshake() throws IOException { + delegate.startHandshake(); + } + + public void setUseClientMode(final boolean mode) { + delegate.setUseClientMode(mode); + } + + public boolean getUseClientMode() { + return delegate.getUseClientMode(); + } + + public void setNeedClientAuth(final boolean need) { + delegate.setNeedClientAuth(need); + } + + public boolean getNeedClientAuth() { + return delegate.getNeedClientAuth(); + } + + public void setWantClientAuth(final boolean want) { + delegate.setWantClientAuth(want); + } + + public boolean getWantClientAuth() { + return delegate.getWantClientAuth(); + } + + public void setEnableSessionCreation(final boolean flag) { + delegate.setEnableSessionCreation(flag); + } + + public boolean getEnableSessionCreation() { + return delegate.getEnableSessionCreation(); + } + + public SSLParameters getSSLParameters() { + return delegate.getSSLParameters(); + } + + public void setSSLParameters(final SSLParameters params) { + delegate.setSSLParameters(params); + } + + public void connect(final SocketAddress endpoint) throws IOException { + delegate.connect(endpoint); + } + + public void connect(final SocketAddress endpoint, final int timeout) throws IOException { + delegate.connect(endpoint, timeout); + } + + public void bind(final SocketAddress bindpoint) throws IOException { + delegate.bind(bindpoint); + } + + public InetAddress getInetAddress() { + return delegate.getInetAddress(); + } + + public InetAddress getLocalAddress() { + return delegate.getLocalAddress(); + } + + public int getPort() { + return delegate.getPort(); + } + + public int getLocalPort() { + return delegate.getLocalPort(); + } + + public SocketAddress getRemoteSocketAddress() { + return delegate.getRemoteSocketAddress(); + } + + public SocketAddress getLocalSocketAddress() { + return delegate.getLocalSocketAddress(); + } + + public SocketChannel getChannel() { + return delegate.getChannel(); + } + + public InputStream getInputStream() throws IOException { + return delegate.getInputStream(); + } + + public OutputStream getOutputStream() throws IOException { + return delegate.getOutputStream(); + } + + public void setTcpNoDelay(final boolean on) throws SocketException { + delegate.setTcpNoDelay(on); + } + + public boolean getTcpNoDelay() throws SocketException { + return delegate.getTcpNoDelay(); + } + + public void setSoLinger(final boolean on, final int linger) throws SocketException { + delegate.setSoLinger(on, linger); + } + + public int getSoLinger() throws SocketException { + return delegate.getSoLinger(); + } + + public void sendUrgentData(final int data) throws IOException { + delegate.sendUrgentData(data); + } + + public void setOOBInline(final boolean on) throws SocketException { + delegate.setOOBInline(on); + } + + public boolean getOOBInline() throws SocketException { + return delegate.getOOBInline(); + } + + public void setSoTimeout(final int timeout) throws SocketException { + delegate.setSoTimeout(timeout); + } + + public int getSoTimeout() throws SocketException { + return delegate.getSoTimeout(); + } + + public void setSendBufferSize(final int size) throws SocketException { + delegate.setSendBufferSize(size); + } + + public int getSendBufferSize() throws SocketException { + return delegate.getSendBufferSize(); + } + + public void setReceiveBufferSize(final int size) throws SocketException { + delegate.setReceiveBufferSize(size); + } + + public int getReceiveBufferSize() throws SocketException { + return delegate.getReceiveBufferSize(); + } + + public void setKeepAlive(final boolean on) throws SocketException { + delegate.setKeepAlive(on); + } + + public boolean getKeepAlive() throws SocketException { + return delegate.getKeepAlive(); + } + + public void setTrafficClass(final int tc) throws SocketException { + delegate.setTrafficClass(tc); + } + + public int getTrafficClass() throws SocketException { + return delegate.getTrafficClass(); + } + + public void setReuseAddress(final boolean on) throws SocketException { + delegate.setReuseAddress(on); + } + + public boolean getReuseAddress() throws SocketException { + return delegate.getReuseAddress(); + } + + public void close() throws IOException { + delegate.close(); + } + + public void shutdownInput() throws IOException { + delegate.shutdownInput(); + } + + public void shutdownOutput() throws IOException { + delegate.shutdownOutput(); + } + + public String toString() { + return delegate.toString(); + } + + public boolean isConnected() { + return delegate.isConnected(); + } + + public boolean isBound() { + return delegate.isBound(); + } + + public boolean isClosed() { + return delegate.isClosed(); + } + + public boolean isInputShutdown() { + return delegate.isInputShutdown(); + } + + public boolean isOutputShutdown() { + return delegate.isOutputShutdown(); + } + + public void setPerformancePreferences(final int connectionTime, final int latency, final int bandwidth) { + delegate.setPerformancePreferences(connectionTime, latency, bandwidth); + } + + protected SSLSocket getDelegate() { + return delegate; + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLSocketFactory.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLSocketFactory.java new file mode 100644 index 00000000000..266d9206a70 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/AbstractDelegatingSSLSocketFactory.java @@ -0,0 +1,75 @@ +/* + * 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.builder; + +import java.io.IOException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.Socket; + +import javax.net.ssl.SSLSocketFactory; + +/** + * @author David M. Lloyd + */ +abstract class AbstractDelegatingSSLSocketFactory extends SSLSocketFactory { + private final SSLSocketFactory delegate; + + AbstractDelegatingSSLSocketFactory(final SSLSocketFactory delegate) { + this.delegate = delegate; + } + + public String[] getDefaultCipherSuites() { + return delegate.getDefaultCipherSuites(); + } + + public String[] getSupportedCipherSuites() { + return delegate.getSupportedCipherSuites(); + } + + public Socket createSocket(final Socket s, final String host, final int port, final boolean autoClose) throws IOException { + return delegate.createSocket(s, host, port, autoClose); + } + + public Socket createSocket() throws IOException { + return delegate.createSocket(); + } + + public Socket createSocket(final String host, final int port) throws IOException { + return delegate.createSocket(host, port); + } + + public Socket createSocket(final String host, final int port, final InetAddress localHost, final int localPort) throws IOException { + return delegate.createSocket(host, port, localHost, localPort); + } + + public Socket createSocket(final InetAddress host, final int port) throws IOException { + return delegate.createSocket(host, port); + } + + public Socket createSocket(final InetAddress address, final int port, final InetAddress localAddress, final int localPort) throws IOException { + return delegate.createSocket(address, port, localAddress, localPort); + } + + /*===== since 1.8 =====*/ + + public Socket createSocket(final Socket socket, final InputStream inputStream, final boolean autoClose) throws IOException { + return delegate.createSocket(socket, inputStream, autoClose); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLContextSpi.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLContextSpi.java new file mode 100644 index 00000000000..2bac93bfc35 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLContextSpi.java @@ -0,0 +1,74 @@ +/* + * 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.builder; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSocketFactory; + +import org.wildfly.security.ssl.SSLConfigurator; + +/** + * @author David M. Lloyd + */ +final class ConfiguredSSLContextSpi extends AbstractDelegatingSSLContextSpi { + + private final SSLConfigurator sslConfigurator; + private final boolean wrap; + + ConfiguredSSLContextSpi(final SSLContext delegate, final SSLConfigurator sslConfigurator, final boolean wrap) { + super(delegate); + this.sslConfigurator = sslConfigurator; + this.wrap = wrap; + } + + protected SSLSocketFactory engineGetSocketFactory() { + return new ConfiguredSSLSocketFactory(super.engineGetSocketFactory(), getDelegate(), sslConfigurator, wrap); + } + + protected SSLServerSocketFactory engineGetServerSocketFactory() { + return new ConfiguredSSLServerSocketFactory(super.engineGetServerSocketFactory(), getDelegate(), sslConfigurator, wrap); + } + + protected SSLEngine engineCreateSSLEngine() { + final SSLEngine sslEngine = super.engineCreateSSLEngine(); + final SSLConfigurator sslConfigurator = this.sslConfigurator; + sslConfigurator.configure(getDelegate(), sslEngine); + return wrap ? new ConfiguredSSLEngine(sslEngine, getDelegate(), sslConfigurator) : sslEngine; + } + + protected SSLEngine engineCreateSSLEngine(final String host, final int port) { + final SSLEngine sslEngine = super.engineCreateSSLEngine(host, port); + final SSLConfigurator sslConfigurator = this.sslConfigurator; + sslConfigurator.configure(getDelegate(), sslEngine); + return wrap ? new ConfiguredSSLEngine(sslEngine, getDelegate(), sslConfigurator) : sslEngine; + } + + protected SSLParameters engineGetDefaultSSLParameters() { + final SSLContext delegate = getDelegate(); + return sslConfigurator.getDefaultSSLParameters(delegate, delegate.getDefaultSSLParameters()); + } + + protected SSLParameters engineGetSupportedSSLParameters() { + final SSLContext delegate = getDelegate(); + return sslConfigurator.getSupportedSSLParameters(delegate, delegate.getSupportedSSLParameters()); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLEngine.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLEngine.java new file mode 100644 index 00000000000..5f7aeb96b4b --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLEngine.java @@ -0,0 +1,70 @@ +/* + * 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.builder; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; + +import org.wildfly.security.ssl.SSLConfigurator; + +/** + * An SSL engine which is pre-configured with a specific protocol and cipher suite selection. + * + * @author David M. Lloyd + */ +final class ConfiguredSSLEngine extends AbstractDelegatingSSLEngine { + + private final SSLContext sslContext; + private final SSLConfigurator sslConfigurator; + + ConfiguredSSLEngine(final SSLEngine delegate, final SSLContext sslContext, final SSLConfigurator sslConfigurator) { + super(delegate); + this.sslContext = sslContext; + this.sslConfigurator = sslConfigurator; + } + + public void setEnabledCipherSuites(final String[] suites) { + sslConfigurator.setEnabledCipherSuites(sslContext, getDelegate(), suites); + } + + public void setEnabledProtocols(final String[] protocols) { + sslConfigurator.setEnabledProtocols(sslContext, getDelegate(), protocols); + } + + public void setSSLParameters(final SSLParameters params) { + sslConfigurator.setSSLParameters(sslContext, getDelegate(), params); + } + + public void setUseClientMode(final boolean mode) { + sslConfigurator.setUseClientMode(sslContext, getDelegate(), mode); + } + + public void setNeedClientAuth(final boolean need) { + sslConfigurator.setNeedClientAuth(sslContext, getDelegate(), need); + } + + public void setWantClientAuth(final boolean want) { + sslConfigurator.setWantClientAuth(sslContext, getDelegate(), want); + } + + public void setEnableSessionCreation(final boolean flag) { + sslConfigurator.setEnableSessionCreation(sslContext, getDelegate(), flag); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLServerSocket.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLServerSocket.java new file mode 100644 index 00000000000..b4c9adcb0fd --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLServerSocket.java @@ -0,0 +1,72 @@ +/* + * 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.builder; + +import java.io.IOException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLServerSocket; + +import org.wildfly.security.ssl.SSLConfigurator; + +/** + * An SSL server socket which is pre-configured with a specific protocol and cipher suite selection. + * + * @author David M. Lloyd + */ +final class ConfiguredSSLServerSocket extends AbstractDelegatingSSLServerSocket { + + private final SSLContext sslContext; + private final SSLConfigurator sslConfigurator; + + ConfiguredSSLServerSocket(final SSLServerSocket delegate, final SSLContext sslContext, final SSLConfigurator sslConfigurator) throws IOException { + super(delegate); + this.sslContext = sslContext; + this.sslConfigurator = sslConfigurator; + } + + public void setEnabledCipherSuites(final String[] suites) { + sslConfigurator.setEnabledCipherSuites(sslContext, getDelegate(), suites); + } + + public void setEnabledProtocols(final String[] protocols) { + sslConfigurator.setEnabledProtocols(sslContext, getDelegate(), protocols); + } + + public void setSSLParameters(final SSLParameters params) { + sslConfigurator.setSSLParameters(sslContext, getDelegate(), params); + } + + public void setNeedClientAuth(final boolean need) { + sslConfigurator.setNeedClientAuth(sslContext, getDelegate(), need); + } + + public void setWantClientAuth(final boolean want) { + sslConfigurator.setWantClientAuth(sslContext, getDelegate(), want); + } + + public void setUseClientMode(final boolean clientMode) { + sslConfigurator.setUseClientMode(sslContext, getDelegate(), clientMode); + } + + public void setEnableSessionCreation(final boolean enabled) { + sslConfigurator.setEnableSessionCreation(sslContext, getDelegate(), enabled); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLServerSocketFactory.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLServerSocketFactory.java new file mode 100644 index 00000000000..8bc3e86bb88 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLServerSocketFactory.java @@ -0,0 +1,81 @@ +/* + * 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.builder; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; + +import org.wildfly.security.ssl.SSLConfigurator; + +/** + * @author David M. Lloyd + */ +final class ConfiguredSSLServerSocketFactory extends AbstractDelegatingSSLServerSocketFactory { + private final SSLContext sslContext; + private final SSLConfigurator sslConfigurator; + private final boolean wrap; + + ConfiguredSSLServerSocketFactory(final SSLServerSocketFactory delegate, final SSLContext sslContext, final SSLConfigurator sslConfigurator, final boolean wrap) { + super(delegate); + this.sslContext = sslContext; + this.sslConfigurator = sslConfigurator; + this.wrap = wrap; + } + + public ServerSocket createServerSocket() throws IOException { + return wrap(super.createServerSocket()); + } + + public ServerSocket createServerSocket(final int port) throws IOException { + return wrap(super.createServerSocket(port)); + } + + public ServerSocket createServerSocket(final int port, final int backlog) throws IOException { + return wrap(super.createServerSocket(port, backlog)); + } + + public ServerSocket createServerSocket(final int port, final int backlog, final InetAddress ifAddress) throws IOException { + return wrap(super.createServerSocket(port, backlog, ifAddress)); + } + + public String[] getDefaultCipherSuites() { + return sslConfigurator.getDefaultSSLParameters(sslContext, sslContext.getDefaultSSLParameters()).getCipherSuites(); + } + + public String[] getSupportedCipherSuites() { + return sslConfigurator.getSupportedSSLParameters(sslContext, sslContext.getSupportedSSLParameters()).getCipherSuites(); + } + + private ServerSocket wrap(ServerSocket original) throws IOException { + if (original instanceof SSLServerSocket) { + final SSLServerSocket sslServerSocket = (SSLServerSocket) original; + final SSLContext sslContext = this.sslContext; + final SSLConfigurator sslConfigurator = this.sslConfigurator; + sslConfigurator.configure(sslContext, sslServerSocket); + return wrap ? new ConfiguredSSLServerSocket(sslServerSocket, sslContext, sslConfigurator) : sslServerSocket; + } else { + return original; + } + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLSocket.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLSocket.java new file mode 100644 index 00000000000..aec4f8605c7 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLSocket.java @@ -0,0 +1,70 @@ +/* + * 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.builder; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSocket; + +import org.wildfly.security.ssl.SSLConfigurator; + +/** + * An SSL socket which is pre-configured. + * + * @author David M. Lloyd + */ +final class ConfiguredSSLSocket extends AbstractDelegatingSSLSocket { + + private final SSLContext sslContext; + private final SSLConfigurator sslConfigurator; + + ConfiguredSSLSocket(final SSLSocket delegate, final SSLContext sslContext, final SSLConfigurator sslConfigurator) { + super(delegate); + this.sslContext = sslContext; + this.sslConfigurator = sslConfigurator; + } + + public void setUseClientMode(final boolean mode) { + sslConfigurator.setUseClientMode(sslContext, getDelegate(), mode); + } + + public void setNeedClientAuth(final boolean need) { + sslConfigurator.setNeedClientAuth(sslContext, getDelegate(), need); + } + + public void setWantClientAuth(final boolean want) { + sslConfigurator.setWantClientAuth(sslContext, getDelegate(), want); + } + + public void setEnableSessionCreation(final boolean flag) { + sslConfigurator.setEnableSessionCreation(sslContext, getDelegate(), flag); + } + + public void setEnabledCipherSuites(final String[] suites) { + sslConfigurator.setEnabledCipherSuites(sslContext, getDelegate(), suites); + } + + public void setEnabledProtocols(final String[] protocols) { + sslConfigurator.setEnabledProtocols(sslContext, getDelegate(), protocols); + } + + public void setSSLParameters(final SSLParameters params) { + sslConfigurator.setSSLParameters(sslContext, getDelegate(), params); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLSocketFactory.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLSocketFactory.java new file mode 100644 index 00000000000..e2743aa50ad --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ConfiguredSSLSocketFactory.java @@ -0,0 +1,95 @@ +/* + * 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.builder; + +import java.io.IOException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.Socket; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +import org.wildfly.security.ssl.SSLConfigurator; + +/** + * @author David M. Lloyd + */ +final class ConfiguredSSLSocketFactory extends AbstractDelegatingSSLSocketFactory { + + private final SSLContext sslContext; + private final SSLConfigurator sslConfigurator; + private final boolean wrap; + + ConfiguredSSLSocketFactory(final SSLSocketFactory delegate, final SSLContext sslContext, final SSLConfigurator sslConfigurator, final boolean wrap) { + super(delegate); + this.sslContext = sslContext; + this.sslConfigurator = sslConfigurator; + this.wrap = wrap; + } + + public Socket createSocket(final Socket s, final String host, final int port, final boolean autoClose) throws IOException { + return wrap(super.createSocket(s, host, port, autoClose)); + } + + public Socket createSocket() throws IOException { + return wrap(super.createSocket()); + } + + public Socket createSocket(final String host, final int port) throws IOException { + return wrap(super.createSocket(host, port)); + } + + public Socket createSocket(final String host, final int port, final InetAddress localHost, final int localPort) throws IOException { + return wrap(super.createSocket(host, port, localHost, localPort)); + } + + public Socket createSocket(final InetAddress host, final int port) throws IOException { + return wrap(super.createSocket(host, port)); + } + + public Socket createSocket(final InetAddress address, final int port, final InetAddress localAddress, final int localPort) throws IOException { + return wrap(super.createSocket(address, port, localAddress, localPort)); + } + + public Socket createSocket(final Socket socket, final InputStream inputStream, final boolean autoClose) throws IOException { + return wrap(super.createSocket(socket, inputStream, autoClose)); + } + + public String[] getDefaultCipherSuites() { + return sslConfigurator.getDefaultSSLParameters(sslContext, sslContext.getDefaultSSLParameters()).getCipherSuites(); + } + + public String[] getSupportedCipherSuites() { + return sslConfigurator.getSupportedSSLParameters(sslContext, sslContext.getSupportedSSLParameters()).getCipherSuites(); + } + + private Socket wrap(Socket orig) { + if (orig instanceof SSLSocket) { + final SSLSocket sslSocket = (SSLSocket) orig; + final SSLContext sslContext = this.sslContext; + final SSLConfigurator sslConfigurator = this.sslConfigurator; + sslConfigurator.configure(sslContext, sslSocket); + return wrap ? new ConfiguredSSLSocket(sslSocket, sslContext, sslConfigurator) : sslSocket; + } else { + return orig; + } + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/DelegatingSSLContext.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/DelegatingSSLContext.java new file mode 100644 index 00000000000..ebb421b8600 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/DelegatingSSLContext.java @@ -0,0 +1,38 @@ +/* + * 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.builder; + +import javax.net.ssl.SSLContext; + +/** + * An SSL context which delegates to a customized SPI implementation. + * + * @author David M. Lloyd + */ +final class DelegatingSSLContext extends SSLContext { + + /** + * Construct a new instance. + * + * @param contextSpi the SSL context SPI to delegate to + */ + DelegatingSSLContext(final AbstractDelegatingSSLContextSpi contextSpi) { + super(contextSpi, contextSpi.getDelegate().getProvider(), contextSpi.getDelegate().getProtocol()); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ElytronMessages.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ElytronMessages.java new file mode 100644 index 00000000000..ba4701b81e1 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/ElytronMessages.java @@ -0,0 +1,79 @@ +/* + * 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.builder; + +import java.security.NoSuchAlgorithmException; +import java.security.Principal; +import java.security.cert.CertificateException; + +import org.jboss.logging.BasicLogger; +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 javax.net.ssl.SSLException; +import javax.net.ssl.SSLHandshakeException; + +/** + * Log messages and exceptions for Elytron. + * + * @author David M. Lloyd + * @author Darran Lofthouse + */ +@MessageLogger(projectCode = "ELY", length = 5) +@ValidIdRanges({ + @ValidIdRange(min = 4001, max = 4031), + @ValidIdRange(min = 15000, max = 15999) +}) +interface ElytronMessages extends BasicLogger { + + 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 = 4005, value = "No default trust manager available") + NoSuchAlgorithmException noDefaultTrustManager(); + + @Message(id = 4006, value = "No context for SSL connection") + SSLHandshakeException noContextForSslConnection(); + + @Message(id = 4007, value = "SSL channel is closed") + SSLException sslClosed(); + + @Message(id = 4024, value = "Invalid client mode, expected %s, got %s") + IllegalArgumentException invalidClientMode(boolean expectedMode, boolean givenMode); + + @Message(id = 4027, value = "SecurityDomain of SSLContext does not support X509PeerCertificateChainEvidence verification") + IllegalArgumentException securityDomainOfSSLContextDoesNotSupportX509(); + + @Message(id = 15001, value = "No '%s' provided by the configured providers") + NoSuchAlgorithmException noSslContextProvided(String type); +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/JDKSpecific.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/JDKSpecific.java new file mode 100644 index 00000000000..36143556914 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/JDKSpecific.java @@ -0,0 +1,229 @@ +/* + * 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.ssl.builder; + +import static org.wildfly.security.ssl.ElytronMessages.tls; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.function.BiFunction; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSocket; + +final class JDKSpecific { + + // SSLEngine Methods + + private static final Method SSLENGINE_GET_APPLICATION_PROTOCOL = getMethodOrNull(SSLEngine.class, "getApplicationProtocol"); + private static final Method SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL = getMethodOrNull(SSLEngine.class, "getHandshakeApplicationProtocol"); + private static final Method SSLENGINE_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getMethodOrNull(SSLEngine.class, "setHandshakeApplicationProtocolSelector", BiFunction.class); + private static final Method SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getMethodOrNull(SSLEngine.class, "getHandshakeApplicationProtocolSelector"); + + // SSLParameters Methods + + private static final Method SSLPARAMETERS_GET_APPLICATION_PROTOCOLS = getMethodOrNull(SSLParameters.class, "getApplicationProtocols"); + private static final Method SSLPARAMETERS_SET_APPLICATION_PROTOCOLS = getMethodOrNull(SSLParameters.class, "setApplicationProtocols", String[].class); + + // SSLSocket Methods + + private static final Method SSLSOCKET_GET_APPLICATION_PROTOCOL = getMethodOrNull(SSLSocket.class, "getApplicationProtocol"); + private static final Method SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL = getMethodOrNull(SSLSocket.class, "getHandshakeApplicationProtocol"); + private static final Method SSLSOCKET_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getMethodOrNull(SSLSocket.class, "setHandshakeApplicationProtocolSelector", BiFunction.class); + private static final Method SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getMethodOrNull(SSLSocket.class, "getHandshakeApplicationProtocolSelector"); + + private static Method getMethodOrNull(Class clazz, String methodName, Class... parameterTypes) { + try { + return clazz.getMethod(methodName, parameterTypes); + } catch (Exception e) { + if (tls.isTraceEnabled()) { + tls.tracef(e, "Unable to getMethod %s on class %s", methodName, clazz.getName()); + } else if (tls.isDebugEnabled()) { + tls.debugf("Unable to getMethod %s on class %s", methodName, clazz.getName()); + } + + return null; + } + } + + /* + * SSLEngine + */ + + static String getApplicationProtocol(SSLEngine sslEngine) { + if (SSLENGINE_GET_APPLICATION_PROTOCOL != null) { + try { + return (String) SSLENGINE_GET_APPLICATION_PROTOCOL.invoke(sslEngine); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + + static String getHandshakeApplicationProtocol(SSLEngine sslEngine) { + if (SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL != null) { + try { + return (String) SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL.invoke(sslEngine); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + + static void setHandshakeApplicationProtocolSelector(SSLEngine sslEngine, BiFunction, String> selector) { + if (SSLENGINE_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR != null) { + try { + SSLENGINE_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(sslEngine, selector); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + + static BiFunction, String> getHandshakeApplicationProtocolSelector(SSLEngine sslEngine) { + if (SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR != null) { + try { + return (BiFunction, String>) SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(sslEngine); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + + /* + * SSLParameters + */ + + static String[] getApplicationProtocols(SSLParameters parameters) { + if (SSLPARAMETERS_GET_APPLICATION_PROTOCOLS != null) { + try { + return (String[]) SSLPARAMETERS_GET_APPLICATION_PROTOCOLS.invoke(parameters); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + + static void setApplicationProtocols(SSLParameters parameters, String[] protocols) { + if (SSLPARAMETERS_SET_APPLICATION_PROTOCOLS != null) { + try { + SSLPARAMETERS_SET_APPLICATION_PROTOCOLS.invoke(parameters, (Object) protocols); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + + /** + * Copies SSLParameters' fields available in java 8. + * + * @param original SSLParameters that should be applied to new instance + * @return instance of SSLParameters with fields copied from original + */ + static SSLParameters setSSLParameters(SSLParameters original) { + SSLParameters params = new SSLParameters(); + params.setProtocols(original.getProtocols()); + params.setCipherSuites(original.getCipherSuites()); + params.setUseCipherSuitesOrder(original.getUseCipherSuitesOrder()); + params.setServerNames(original.getServerNames()); + params.setSNIMatchers(original.getSNIMatchers()); + params.setAlgorithmConstraints(original.getAlgorithmConstraints()); + params.setEndpointIdentificationAlgorithm(original.getEndpointIdentificationAlgorithm()); + if (original.getWantClientAuth()) { + params.setWantClientAuth(original.getWantClientAuth()); + } else if (original.getNeedClientAuth()) { + params.setNeedClientAuth(original.getNeedClientAuth()); + } + + try { + if (SSLPARAMETERS_GET_APPLICATION_PROTOCOLS != null && SSLPARAMETERS_SET_APPLICATION_PROTOCOLS != null) { + setApplicationProtocols(params, getApplicationProtocols(original)); + } + } catch (Exception ignored) {} + + return params; + } + + /* + * SSLSocket + */ + + static String getApplicationProtocol(SSLSocket socket) { + if (SSLSOCKET_GET_APPLICATION_PROTOCOL != null) { + try { + return (String) SSLSOCKET_GET_APPLICATION_PROTOCOL.invoke(socket); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + + static String getHandshakeApplicationProtocol(SSLSocket socket) { + if (SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL != null) { + try { + return (String) SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL.invoke(socket); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + + static void setHandshakeApplicationProtocolSelector(SSLSocket socket, BiFunction, String> selector) { + if (SSLSOCKET_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR != null) { + try { + SSLSOCKET_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(socket, selector); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + + static BiFunction, String> getHandshakeApplicationProtocolSelector(SSLSocket socket) { + if (SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR != null) { + try { + return (BiFunction, String>) SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(socket); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new UnsupportedOperationException(e); + } + } + + throw new UnsupportedOperationException(); + } + +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLConfiguratorImpl.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLConfiguratorImpl.java new file mode 100644 index 00000000000..badcc5c3f3a --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLConfiguratorImpl.java @@ -0,0 +1,202 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2015 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.builder; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLSocket; + +import org.wildfly.common.Assert; + +import org.wildfly.security.ssl.CipherSuiteSelector; +import org.wildfly.security.ssl.ProtocolSelector; +import org.wildfly.security.ssl.SSLConfigurator; + +final class SSLConfiguratorImpl implements SSLConfigurator { + + private final ProtocolSelector protocolSelector; + private final CipherSuiteSelector cipherSuiteSelector; + private final boolean wantClientAuth; + private final boolean needClientAuth; + private final boolean useCipherSuitesOrder; + private final boolean clientMode; + + /** + * Construct a new instance in server mode. + * + * @param protocolSelector the protocol selector (must not be {@code null}) + * @param cipherSuiteSelector the cipher suite selector (must not be {@code null}) + * @param wantClientAuth {@code true} to request client authentication + * @param needClientAuth {@code true} to require client authentication + */ + SSLConfiguratorImpl(final ProtocolSelector protocolSelector, final CipherSuiteSelector cipherSuiteSelector, final boolean wantClientAuth, final boolean needClientAuth, final boolean useCipherSuitesOrder) { + this.protocolSelector = protocolSelector; + this.cipherSuiteSelector = cipherSuiteSelector; + this.useCipherSuitesOrder = useCipherSuitesOrder; + this.wantClientAuth = wantClientAuth; + this.needClientAuth = needClientAuth; + clientMode = false; + } + + /** + * Construct a new instance in client mode. + * + * @param protocolSelector the protocol selector (must not be {@code null}) + * @param cipherSuiteSelector the cipher suite selector (must not be {@code null}) + */ + SSLConfiguratorImpl(final ProtocolSelector protocolSelector, final CipherSuiteSelector cipherSuiteSelector, final boolean useCipherSuitesOrder) { + this.protocolSelector = protocolSelector; + this.cipherSuiteSelector = cipherSuiteSelector; + this.useCipherSuitesOrder = useCipherSuitesOrder; + this.wantClientAuth = false; + this.needClientAuth = false; + clientMode = true; + } + + void configure(SSLParameters params, String[] supportedProtocols, String[] supportedCipherSuites) { + Assert.checkNotNullParam("supportedProtocols", supportedProtocols); + Assert.checkNotNullParam("supportedCipherSuites", supportedCipherSuites); + params.setProtocols(protocolSelector.evaluate(supportedProtocols)); + params.setCipherSuites(cipherSuiteSelector.evaluate(supportedCipherSuites)); + params.setUseCipherSuitesOrder(useCipherSuitesOrder); + params.setWantClientAuth(wantClientAuth); // unsets need + if (needClientAuth) params.setNeedClientAuth(needClientAuth); // unsets want + } + + public void configure(final SSLContext context, final SSLServerSocket sslServerSocket) { + sslServerSocket.setUseClientMode(clientMode); + final SSLParameters sslParameters = sslServerSocket.getSSLParameters(); + configure(sslParameters, sslServerSocket.getSupportedProtocols(), sslServerSocket.getSupportedCipherSuites()); + sslServerSocket.setSSLParameters(sslParameters); + } + + public void configure(final SSLContext context, final SSLSocket sslSocket) { + sslSocket.setUseClientMode(clientMode); + final SSLParameters sslParameters = sslSocket.getSSLParameters(); + configure(sslParameters, sslSocket.getSupportedProtocols(), sslSocket.getSupportedCipherSuites()); + sslSocket.setSSLParameters(sslParameters); + } + + public void configure(final SSLContext context, final SSLEngine sslEngine) { + sslEngine.setUseClientMode(clientMode); + final SSLParameters sslParameters = sslEngine.getSSLParameters(); + configure(sslParameters, sslEngine.getSupportedProtocols(), sslEngine.getSupportedCipherSuites()); + sslEngine.setSSLParameters(sslParameters); + } + + public SSLParameters getDefaultSSLParameters(final SSLContext sslContext, final SSLParameters original) { + final SSLParameters supportedSSLParameters = sslContext.getSupportedSSLParameters(); + configure(original, supportedSSLParameters.getProtocols(), supportedSSLParameters.getCipherSuites()); + return original; + } + + public SSLParameters getSupportedSSLParameters(final SSLContext sslContext, final SSLParameters original) { + return getDefaultSSLParameters(sslContext, original); + } + + public void setWantClientAuth(final SSLContext context, final SSLSocket sslSocket, final boolean value) { + if (value) sslSocket.setWantClientAuth(value); + } + + public void setWantClientAuth(final SSLContext context, final SSLEngine sslEngine, final boolean value) { + if (value) sslEngine.setWantClientAuth(value); + } + + public void setWantClientAuth(final SSLContext sslContext, final SSLServerSocket sslServerSocket, final boolean value) { + if (value) sslServerSocket.setWantClientAuth(value); + } + + public void setNeedClientAuth(final SSLContext context, final SSLSocket sslSocket, final boolean value) { + if (value) sslSocket.setNeedClientAuth(value); + } + + public void setNeedClientAuth(final SSLContext context, final SSLEngine sslEngine, final boolean value) { + if (value) sslEngine.setNeedClientAuth(value); + } + + public void setNeedClientAuth(final SSLContext sslContext, final SSLServerSocket sslServerSocket, final boolean value) { + if (value) sslServerSocket.setNeedClientAuth(value); + } + + public void setEnabledCipherSuites(final SSLContext sslContext, final SSLSocket sslSocket, final String[] cipherSuites) { + sslSocket.setEnabledCipherSuites(cipherSuiteSelector.evaluate(cipherSuites)); + } + + public void setEnabledCipherSuites(final SSLContext sslContext, final SSLEngine sslEngine, final String[] cipherSuites) { + sslEngine.setEnabledCipherSuites(cipherSuiteSelector.evaluate(cipherSuites)); + } + + public void setEnabledCipherSuites(final SSLContext sslContext, final SSLServerSocket sslServerSocket, final String[] cipherSuites) { + sslServerSocket.setEnabledCipherSuites(cipherSuiteSelector.evaluate(cipherSuites)); + } + + public void setEnabledProtocols(final SSLContext sslContext, final SSLSocket sslSocket, final String[] protocols) { + sslSocket.setEnabledProtocols(protocolSelector.evaluate(protocols)); + } + + public void setEnabledProtocols(final SSLContext sslContext, final SSLEngine sslEngine, final String[] protocols) { + sslEngine.setEnabledProtocols(protocolSelector.evaluate(protocols)); + } + + public void setEnabledProtocols(final SSLContext sslContext, final SSLServerSocket sslServerSocket, final String[] protocols) { + sslServerSocket.setEnabledProtocols(protocolSelector.evaluate(protocols)); + } + + private SSLParameters redefine(SSLParameters original) { + SSLParameters params = JDKSpecific.setSSLParameters(original); + params.setProtocols(protocolSelector.evaluate(params.getProtocols())); + params.setCipherSuites(cipherSuiteSelector.evaluate(params.getCipherSuites())); + return params; + } + + public void setSSLParameters(final SSLContext sslContext, final SSLSocket sslSocket, final SSLParameters parameters) { + sslSocket.setSSLParameters(redefine(parameters)); + } + + public void setSSLParameters(final SSLContext sslContext, final SSLEngine sslEngine, final SSLParameters parameters) { + sslEngine.setSSLParameters(redefine(parameters)); + } + + public void setSSLParameters(final SSLContext sslContext, final SSLServerSocket sslServerSocket, final SSLParameters parameters) { + sslServerSocket.setSSLParameters(redefine(parameters)); + } + + public void setUseClientMode(final SSLContext sslContext, final SSLSocket sslSocket, final boolean mode) { + if (mode != clientMode) { + throw ElytronMessages.log.invalidClientMode(clientMode, mode); + } + // ignored + } + + public void setUseClientMode(final SSLContext sslContext, final SSLEngine sslEngine, final boolean mode) { + if (mode != clientMode) { + throw ElytronMessages.log.invalidClientMode(clientMode, mode); + } + // ignored + } + + public void setUseClientMode(final SSLContext sslContext, final SSLServerSocket sslServerSocket, final boolean mode) { + if (mode != clientMode) { + throw ElytronMessages.log.invalidClientMode(clientMode, mode); + } + // ignored + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLContextBuilder.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLContextBuilder.java new file mode 100644 index 00000000000..f989acb419d --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLContextBuilder.java @@ -0,0 +1,393 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2015 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.builder; + +import static org.wildfly.security.provider.util.ProviderUtil.INSTALLED_PROVIDERS; + +import java.security.Provider; +import java.security.Security; +import java.util.function.Supplier; + +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 org.wildfly.common.Assert; +import org.wildfly.security.FixedSecurityFactory; +import org.wildfly.security.OneTimeSecurityFactory; +import org.wildfly.security.SecurityFactory; +import org.wildfly.security.auth.server.MechanismConfiguration; +import org.wildfly.security.auth.server.MechanismConfigurationSelector; +import org.wildfly.security.auth.server.SecurityDomain; +import org.wildfly.security.auth.server.PrincipalDecoder; +import org.wildfly.security.auth.server.ServerAuthenticationContext; +import org.wildfly.security.evidence.X509PeerCertificateChainEvidence; +import org.wildfly.security.ssl.CipherSuiteSelector; +import org.wildfly.security.ssl.ProtocolSelector; +import org.wildfly.security.ssl.SSLConfigurator; + +/** + * 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 security domain defaults to being empty (no client authentication possible)
  • + *
  • The principal decoder defaults to the {@linkplain PrincipalDecoder#DEFAULT default principal decoder}
  • + *
  • 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}
  • + *
+ * + * @author David M. Lloyd + */ +public final class SSLContextBuilder { + + private SecurityDomain securityDomain; + // 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.defaultProtocols(); + 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; + private MechanismConfigurationSelector mechanismConfigurationSelector; + + /** + * Set the security domain to use to authenticate clients. + * + * @param securityDomain the security domain to use to authenticate clients, or {@code null} to disable client + * certificate authentication + */ + public SSLContextBuilder setSecurityDomain(final SecurityDomain securityDomain) { + + if (securityDomain != null && securityDomain.getEvidenceVerifySupport(X509PeerCertificateChainEvidence.class).isNotSupported()) { + throw ElytronMessages.tls.securityDomainOfSSLContextDoesNotSupportX509(); + } + + this.securityDomain = securityDomain; + + return this; + } + + /** + * Set the cipher suite selector to use for this context. + * + * @param cipherSuiteSelector the cipher suite selector (not {@code null}) + */ + public SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder} to allow chaining of method calls. + */ + public SSLContextBuilder 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 SSLContextBuilder} to allow chaining of method calls. + */ + public SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder 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 SSLContextBuilder setWrap(final boolean wrap) { + this.wrap = wrap; + return this; + } + + /** + * Set selector of mechanism configuration for {@link ServerAuthenticationContext}, which will be used for SSL client authentication. + * + * @param mechanismConfigurationSelector mechanism configuration selector to be used by {@link ServerAuthenticationContext} in SSL authentication. + * @return this builder + */ + public SSLContextBuilder setMechanismConfigurationSelector(final MechanismConfigurationSelector mechanismConfigurationSelector) { + this.mechanismConfigurationSelector = mechanismConfigurationSelector; + 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 SecurityDomain securityDomain = this.securityDomain; + 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; + final MechanismConfigurationSelector mechanismConfigurationSelector = this.mechanismConfigurationSelector != null ? + this.mechanismConfigurationSelector : + MechanismConfigurationSelector.constantSelector(MechanismConfiguration.EMPTY); + + 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(); + final boolean canAuthPeers = securityDomain != null && securityDomain.getEvidenceVerifySupport(X509PeerCertificateChainEvidence.class).mayBeSupported(); + + if (ElytronMessages.tls.isTraceEnabled()) { + ElytronMessages.tls.tracef("SSLContext initialization:%n" + + " securityDomain = %s%n" + + " canAuthPeers = %s%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", + securityDomain, canAuthPeers, cipherSuiteSelector, protocolSelector, x509TrustManager, + x509KeyManager, providerSupplier, clientMode, authenticationOptional, sessionCacheSize, + sessionTimeout, wantClientAuth, needClientAuth, useCipherSuitesOrder, wrap); + } + + sslContext.init(x509KeyManager == null ? null : new KeyManager[]{ + x509KeyManager + }, new TrustManager[]{ + canAuthPeers ? + new SecurityDomainTrustManager(x509TrustManager, securityDomain, authenticationOptional, mechanismConfigurationSelector) : + 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 || canAuthPeers, needClientAuth, useCipherSuitesOrder); + final ConfiguredSSLContextSpi contextSpi = new ConfiguredSSLContextSpi(sslContext, sslConfigurator, wrap); + return new DelegatingSSLContext(contextSpi); + }); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLUtils.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLUtils.java new file mode 100644 index 00000000000..bd59cbd237f --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SSLUtils.java @@ -0,0 +1,480 @@ +/* + * 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.builder; + +import java.net.IDN; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Provider.Service; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIMatcher; +import javax.net.ssl.SNIServerName; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLSession; +import javax.net.ssl.StandardConstants; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +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 org.wildfly.security.ssl.ProtocolSelector; +import org.wildfly.security.ssl.SSLConfigurator; +import org.wildfly.security.ssl.SSLContextSelector; + +/** + * SSL factories and utilities. + * + * @author David M. Lloyd + */ +public final class SSLUtils { + + private static final String[] NO_STRINGS = new String[0]; + + private SSLUtils() {} + + private static final String SERVICE_TYPE = SSLContext.class.getSimpleName(); + + /** + * The key used to store the authenticated {@link SecurityIdentity} onto the {@link SSLSession}. + */ + public static final String SSL_SESSION_IDENTITY_KEY = "org.wildfly.security.ssl.identity"; + + /** + * Create an SSL context factory which locates the best context by searching the preferred providers in order using + * the rules established in the given protocol selector. If there are no matches, a factory is returned which + * + * @param protocolSelector the protocol selector + * @param providerSupplier the provider supplier + * @return the SSL context factory + */ + public static SecurityFactory createSslContextFactory(ProtocolSelector protocolSelector, Supplier providerSupplier) { + return createSslContextFactory(protocolSelector, providerSupplier, null); + } + + /** + * Create an SSL context factory which locates the best context by searching the preferred providers in order using + * the rules established in the given protocol selector. If there are no matches, a factory is returned which + * + * @param protocolSelector the protocol selector + * @param providerSupplier the provider supplier + * @param providerName the provider name to select, or {@code null} to allow any + * @return the SSL context factory + */ + public static SecurityFactory createSslContextFactory(ProtocolSelector protocolSelector, Supplier providerSupplier, String providerName) { + final Map> preferredProviderByAlgorithm = new HashMap<>(); + + // compile all the providers that support SSLContext. + + for (Provider provider : providerSupplier.get()) { + // if a provider name was given, filter by it + if (providerName != null && ! providerName.equals(provider.getName())) { + continue; + } + Set services = provider.getServices(); + if (services != null) { + for (Provider.Service service : services) { + if (SERVICE_TYPE.equals(service.getType())) { + String protocolName = service.getAlgorithm(); + List providerList = preferredProviderByAlgorithm.computeIfAbsent(protocolName.toUpperCase(Locale.ENGLISH), s -> new ArrayList<>()); + providerList.add(provider); + + if (log.isTraceEnabled()) { + log.tracef("Provider %s was added for algorithm %s", provider, protocolName.toUpperCase(Locale.ENGLISH)); + } + } + } + } + } + + // now return a factory that will return the best match is can create. + final String[] supportedProtocols = protocolSelector.evaluate(preferredProviderByAlgorithm.keySet().toArray(NO_STRINGS)); + if (log.isTraceEnabled()) { + log.tracef("Supported protocols are: %s", Arrays.toString(supportedProtocols)); + } + if (supportedProtocols.length > 0) { + return () -> { + for (String protocol : supportedProtocols) { + List providerList = preferredProviderByAlgorithm.getOrDefault(protocol.toUpperCase(Locale.ENGLISH), Collections.emptyList()); + if (log.isTraceEnabled() && providerList.isEmpty()) { + log.tracef("No providers are available for protocol %s", protocol); + } + for (Provider provider : providerList) { + try { + if (log.isTraceEnabled()) { + log.tracef("Attempting to get an SSLContext instance using protocol %s and provider %s", protocol, provider); + } + return SSLContext.getInstance(protocol, provider); + } catch (NoSuchAlgorithmException ignored) { + if (log.isTraceEnabled()) { + log.tracef(ignored, "Provider %s has no such protocol %s", provider, protocol); + } + } + } + } + + if (log.isTraceEnabled()) { + 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); + }; + } + + if (log.isTraceEnabled()) { + log.tracef("No %s provided by providers in %s: %s", SERVICE_TYPE, SSLUtils.class.getSimpleName(), Arrays.toString(providerSupplier.get())); + } + + return SSLUtils::throwIt; + } + + private static SSLContext throwIt() throws NoSuchAlgorithmException { + throw ElytronMessages.log.noSslContextProvided(SERVICE_TYPE); + } + + /** + * Create a simple security factory for SSL contexts. + * + * @param protocol the protocol name + * @param provider the provider to use + * @return the SSL context factory + */ + public static SecurityFactory createSimpleSslContextFactory(String protocol, Provider provider) { + return () -> SSLContext.getInstance(protocol, provider); + } + + /** + * Create a configured SSL context from an outside SSL context. + * + * @param original the original SSL context + * @param sslConfigurator the SSL configurator + * @return the configured SSL context + */ + public static SSLContext createConfiguredSslContext(SSLContext original, final SSLConfigurator sslConfigurator) { + return createConfiguredSslContext(original, sslConfigurator, true); + } + + /** + * Create a configured SSL context from an outside SSL context. + * + * @param original the original SSL context + * @param sslConfigurator the SSL configurator + * @param wrap should the resulting SSLEngine, SSLSocket, and SSLServerSocket instances be wrapped using the configurator. + * @return the configured SSL context + */ + public static SSLContext createConfiguredSslContext(SSLContext original, final SSLConfigurator sslConfigurator, final boolean wrap) { + return new DelegatingSSLContext(new ConfiguredSSLContextSpi(original, sslConfigurator, wrap)); + } + + /** + * Create a configured SSL context factory from an outside SSL context. The returned factory will create new instances + * for every call, so it might be necessary to wrap with a {@link OneTimeSecurityFactory} instance. + * + * @param originalFactory the original SSL context factory + * @param sslConfigurator the SSL configurator + * @return the configured SSL context + */ + public static SecurityFactory createConfiguredSslContextFactory(SecurityFactory originalFactory, final SSLConfigurator sslConfigurator) { + return () -> createConfiguredSslContext(originalFactory.create(), sslConfigurator); + } + + private static final SecurityFactory DEFAULT_TRUST_MANAGER_SECURITY_FACTORY = new OneTimeSecurityFactory<>(() -> { + final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init((KeyStore) null); + for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { + if (trustManager instanceof X509TrustManager) { + return (X509TrustManager) trustManager; + } + } + throw ElytronMessages.log.noDefaultTrustManager(); + }); + + /** + * Get the platform's default X.509 trust manager security factory. The factory caches the instance. + * + * @return the security factory for the default trust manager + */ + public static SecurityFactory getDefaultX509TrustManagerSecurityFactory() { + return DEFAULT_TRUST_MANAGER_SECURITY_FACTORY; + } + + /** + * Get a server SSL engine which dispatches to the appropriate SSL context based on the information in the + * SSL greeting. + * + * @param selector the context selector to use (cannot be {@code null}) + * @return the SSL engine (not {@code null}) + */ + public static SSLEngine createSelectingSSLEngine(SSLContextSelector selector) { + Assert.checkNotNullParam("selector", selector); + return new SelectingServerSSLEngine(selector); + } + + /** + * Get a server SSL engine which dispatches to the appropriate SSL context based on the information in the + * SSL greeting. + * + * @param selector the context selector to use (cannot be {@code null}) + * @param host the advisory host name + * @param port the advisory port number + * @return the SSL engine (not {@code null}) + */ + public static SSLEngine createSelectingSSLEngine(SSLContextSelector selector, String host, int port) { + Assert.checkNotNullParam("selector", selector); + return new SelectingServerSSLEngine(selector, host, port); + } + + /** + * Create an {@code SNIMatcher} which matches SNI host names that satisfy the given predicate. + * + * @param predicate the predicate (must not be {@code null}) + * @return the SNI matcher (not {@code null}) + */ + public static SNIMatcher createHostNamePredicateSNIMatcher(Predicate predicate) { + Assert.checkNotNullParam("predicate", predicate); + return new SNIMatcher(StandardConstants.SNI_HOST_NAME) { + public boolean matches(final SNIServerName sniServerName) { + return sniServerName instanceof SNIHostName && predicate.test((SNIHostName) sniServerName); + } + }; + } + + /** + * Create an {@code SNIMatcher} which matches SNI host name strings that satisfy the given predicate. + * + * @param predicate the predicate (must not be {@code null}) + * @return the SNI matcher (not {@code null}) + * @see IDN + */ + public static SNIMatcher createHostNameStringPredicateSNIMatcher(Predicate predicate) { + Assert.checkNotNullParam("predicate", predicate); + return new SNIMatcher(StandardConstants.SNI_HOST_NAME) { + public boolean matches(final SNIServerName sniServerName) { + return sniServerName instanceof SNIHostName && predicate.test(((SNIHostName) sniServerName).getAsciiName()); + } + }; + } + + /** + * Create an {@code SNIMatcher} which matches SNI host names that are equal to the given (ASCII) string. + * + * @param string the host name string (must not be {@code null}) + * @return the SNI matcher (not {@code null}) + * @see IDN + */ + public static SNIMatcher createHostNameStringSNIMatcher(String string) { + Assert.checkNotNullParam("string", string); + return createHostNameStringPredicateSNIMatcher(string::equals); + } + + /** + * Create an {@code SNIMatcher} which matches SNI host name strings which end with the given suffix. + * + * @param suffix the suffix to match (must not be {@code null} or empty) + * @return the SNI matcher (not {@code null}) + */ + public static SNIMatcher createHostNameSuffixSNIMatcher(String suffix) { + Assert.checkNotNullParam("suffix", suffix); + Assert.checkNotEmptyParam("suffix", suffix); + final String finalSuffix = suffix.startsWith(".") ? suffix : "." + suffix; + return createHostNameStringPredicateSNIMatcher(n -> n.endsWith(finalSuffix)); + } + + /** + * Get a factory which produces SSL engines which dispatch to the appropriate SSL context based on the information + * in the SSL greeting. + * + * @param selector the context selector to use (cannot be {@code null}) + * @return the SSL engine factory (not {@code null}) + */ + public static SecurityFactory createDispatchingSSLEngineFactory(SSLContextSelector selector) { + Assert.checkNotNullParam("selector", selector); + return () -> new SelectingServerSSLEngine(selector); + } + + /** + * Get the value of the given key from the SSL session, or a default value if the key is not set. + * + * @param sslSession the SSL session (must not be {@code null}) + * @param key the key to retrieve (must not be {@code null}) + * @param defaultValue the value to return if the key is not present + * @return the session value or the default value + */ + public static Object getOrDefault(SSLSession sslSession, String key, Object defaultValue) { + Assert.checkNotNullParam("sslSession", sslSession); + Assert.checkNotNullParam("key", key); + final Object value = sslSession.getValue(key); + return value != null ? value : defaultValue; + } + + /** + * Put a value on the session if the value is not yet set. This method is atomic with respect to other methods + * on this class. + * + * @param sslSession the SSL session (must not be {@code null}) + * @param key the key to retrieve (must not be {@code null}) + * @param newValue the value to set (must not be {@code null}) + * @return the existing value, or {@code null} if the value was successfully set + */ + public static Object putSessionValueIfAbsent(SSLSession sslSession, String key, Object newValue) { + Assert.checkNotNullParam("sslSession", sslSession); + Assert.checkNotNullParam("key", key); + Assert.checkNotNullParam("newValue", newValue); + synchronized (sslSession) { + final Object existing = sslSession.getValue(key); + if (existing == null) { + sslSession.putValue(key, newValue); + return null; + } else { + return existing; + } + } + } + + /** + * Remove and return a value on the session. This method is atomic with respect to other methods on this class. + * + * @param sslSession the SSL session (must not be {@code null}) + * @param key the key to retrieve (must not be {@code null}) + * @return the existing value, or {@code null} if no such value was set + */ + public static Object removeSessionValue(SSLSession sslSession, String key) { + Assert.checkNotNullParam("sslSession", sslSession); + Assert.checkNotNullParam("key", key); + synchronized (sslSession) { + final Object existing = sslSession.getValue(key); + sslSession.removeValue(key); + return existing; + } + } + + /** + * Remove the given key-value pair on the session. This method is atomic with respect to other methods on this class. + * + * @param sslSession the SSL session (must not be {@code null}) + * @param key the key to remove (must not be {@code null}) + * @param value the value to remove (must not be {@code null}) + * @return {@code true} if the key/value pair was removed, {@code false} if the key was not present or the value was not equal to the given value + */ + public static boolean removeSessionValue(SSLSession sslSession, String key, Object value) { + Assert.checkNotNullParam("sslSession", sslSession); + Assert.checkNotNullParam("key", key); + Assert.checkNotNullParam("value", value); + synchronized (sslSession) { + final Object existing = sslSession.getValue(key); + if (Objects.equals(existing, value)) { + sslSession.removeValue(key); + return true; + } else { + return false; + } + } + } + + /** + * Replace the given key's value with a new value. If there is no value for the given key, no action is performed. + * This method is atomic with respect to other methods on this class. + * + * @param sslSession the SSL session (must not be {@code null}) + * @param key the key to retrieve (must not be {@code null}) + * @param newValue the value to set (must not be {@code null}) + * @return the existing value, or {@code null} if the value was not set + */ + public static Object replaceSessionValue(SSLSession sslSession, String key, Object newValue) { + Assert.checkNotNullParam("sslSession", sslSession); + Assert.checkNotNullParam("key", key); + Assert.checkNotNullParam("newValue", newValue); + synchronized (sslSession) { + final Object existing = sslSession.getValue(key); + if (existing != null) sslSession.putValue(key, newValue); + return existing; + } + } + + /** + * Replace the given key's value with a new value if (and only if) it is mapped to the given existing value. + * This method is atomic with respect to other methods on this class. + * + * @param sslSession the SSL session (must not be {@code null}) + * @param key the key to retrieve (must not be {@code null}) + * @param oldValue the value to match (must not be {@code null}) + * @param newValue the value to set (must not be {@code null}) + * @return {@code true} if the value was matched and replaced, or {@code false} if the value did not match and no action was taken + */ + public static boolean replaceSessionValue(SSLSession sslSession, String key, Object oldValue, Object newValue) { + Assert.checkNotNullParam("sslSession", sslSession); + Assert.checkNotNullParam("key", key); + Assert.checkNotNullParam("oldValue", oldValue); + Assert.checkNotNullParam("newValue", newValue); + synchronized (sslSession) { + final Object existing = sslSession.getValue(key); + if (Objects.equals(existing, oldValue)) { + sslSession.putValue(key, newValue); + return true; + } else { + return false; + } + } + } + + /** + * Get or compute the value for the given key, storing the computed value (if one is generated). The function + * must not generate a {@code null} value or an unspecified exception will result. + * + * @param sslSession the SSL session (must not be {@code null}) + * @param key the key to retrieve (must not be {@code null}) + * @param mappingFunction the function to apply to acquire the value (must not be {@code null}) + * @return the stored or new value (not {@code null}) + */ + public static R computeIfAbsent(SSLSession sslSession, String key, Function mappingFunction) { + Assert.checkNotNullParam("sslSession", sslSession); + Assert.checkNotNullParam("key", key); + Assert.checkNotNullParam("mappingFunction", mappingFunction); + synchronized (sslSession) { + final R existing = (R) sslSession.getValue(key); + if (existing == null) { + R newValue = mappingFunction.apply(key); + Assert.assertNotNull(newValue); + sslSession.putValue(key, newValue); + return newValue; + } else { + return existing; + } + } + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SecurityDomainTrustManager.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SecurityDomainTrustManager.java new file mode 100644 index 00000000000..ba910e9fafa --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SecurityDomainTrustManager.java @@ -0,0 +1,161 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2015 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.builder; + +import java.net.Socket; +import java.security.Principal; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.X509ExtendedTrustManager; +import javax.net.ssl.X509TrustManager; + +import org.wildfly.common.Assert; +import org.wildfly.security.auth.server.MechanismConfigurationSelector; +import org.wildfly.security.auth.server.SecurityDomain; +import org.wildfly.security.auth.server.ServerAuthenticationContext; +import org.wildfly.security.auth.server.RealmUnavailableException; +import org.wildfly.security.credential.X509CertificateChainCredential; +import org.wildfly.security.evidence.X509PeerCertificateChainEvidence; +import org.wildfly.security.x500.util.X500PrincipalUtil; + +/** + * @author David M. Lloyd + */ +class SecurityDomainTrustManager extends X509ExtendedTrustManager { + + private final X509ExtendedTrustManager delegate; + private final SecurityDomain securityDomain; + private final boolean authenticationOptional; + private final MechanismConfigurationSelector mechanismConfigurationSelector; + + SecurityDomainTrustManager(final X509ExtendedTrustManager delegate, final SecurityDomain securityDomain, final boolean authenticationOptional, final MechanismConfigurationSelector mechanismConfigurationSelector) { + this.delegate = delegate; + this.securityDomain = securityDomain; + this.authenticationOptional = authenticationOptional; + this.mechanismConfigurationSelector = mechanismConfigurationSelector; + } + + SecurityDomainTrustManager(final X509TrustManager delegate, final SecurityDomain securityDomain, final boolean authenticationOptional, final MechanismConfigurationSelector mechanismConfigurationSelector) { + this(delegate instanceof X509ExtendedTrustManager ? + (X509ExtendedTrustManager) delegate : + new WrappingX509ExtendedTrustManager(delegate), securityDomain, authenticationOptional, mechanismConfigurationSelector); + } + + public void checkClientTrusted(final X509Certificate[] chain, final String authType, final Socket socket) throws CertificateException { + delegate.checkClientTrusted(chain, authType, socket); + doClientTrustCheck(chain, authType, ((SSLSocket) socket).getHandshakeSession()); + } + + public void checkClientTrusted(final X509Certificate[] chain, final String authType, final SSLEngine sslEngine) throws CertificateException { + delegate.checkClientTrusted(chain, authType, sslEngine); + doClientTrustCheck(chain, authType, sslEngine.getHandshakeSession()); + } + + public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { + delegate.checkClientTrusted(chain, authType); + doClientTrustCheck(chain, authType, null); + } + + private void doClientTrustCheck(final X509Certificate[] chain, final String authType, final SSLSession handshakeSession) throws CertificateException { + Assert.checkNotNullParam("chain", chain); + Assert.checkNotNullParam("authType", authType); + if (chain.length == 0) { + throw ElytronMessages.log.emptyChainNotTrusted(); + } + Principal principal = X500PrincipalUtil.asX500Principal(chain[0].getSubjectX500Principal()); + if (principal == null) { + throw ElytronMessages.log.notTrusted(null); + } + try (final ServerAuthenticationContext authenticationContext = securityDomain.createNewAuthenticationContext(mechanismConfigurationSelector)) { + authenticationContext.setAuthenticationPrincipal(principal); + if (! authenticationContext.exists()) { + if (authenticationOptional) { + ElytronMessages.log.tracef("Credential validation failed: no identity found for principal [%s], ignoring as authentication is optional", principal); + return; + } else { + throw ElytronMessages.log.notTrusted(principal); + } + } + if (authenticationContext.getCredentialAcquireSupport(X509CertificateChainCredential.class).mayBeSupported()) { + X509CertificateChainCredential credential = authenticationContext.getCredential(X509CertificateChainCredential.class); + if (credential == null) { + if (authenticationOptional) { + ElytronMessages.log.tracef("Credential validation failed: no trusted certificate found for principal [%s], ignoring as authentication is optional", principal); + return; + } else { + throw ElytronMessages.log.notTrusted(principal); + } + } + if (! credential.getFirstCertificate().equals(chain[0])) { + if (authenticationOptional) { + ElytronMessages.log.tracef("Credential validation failed: certificate does not match for principal [%s], ignoring as authentication is optional", principal); + return; + } else { + throw ElytronMessages.log.notTrusted(principal); + } + } + } else if (authenticationContext.getEvidenceVerifySupport(X509PeerCertificateChainEvidence.class).mayBeSupported()) { + final X509PeerCertificateChainEvidence evidence = new X509PeerCertificateChainEvidence(chain); + if (! authenticationContext.verifyEvidence(evidence)) { + if (authenticationOptional) { + ElytronMessages.log.tracef("Credential validation failed: no trusted certificate found for principal [%s], ignoring as authentication is optional", principal); + return; + } else { + throw ElytronMessages.log.notTrusted(principal); + } + } + } + if (! authenticationContext.authorize()) { + if (authenticationOptional) { + ElytronMessages.log.tracef("Credential validation failed: identity is not authorized principal [%s], ignoring as authentication is optional", principal); + return; + } else { + throw ElytronMessages.log.notTrusted(principal); + } + } + ElytronMessages.log.tracef("Authentication succeed for principal [%s]", principal); + authenticationContext.succeed(); + if (handshakeSession != null) { + handshakeSession.putValue(SSLUtils.SSL_SESSION_IDENTITY_KEY, authenticationContext.getAuthorizedIdentity()); + } + } catch (RealmUnavailableException e) { + throw ElytronMessages.log.notTrustedRealmProblem(e, principal); + } + } + + public void checkServerTrusted(final X509Certificate[] chain, final String authType, final Socket socket) throws CertificateException { + delegate.checkServerTrusted(chain, authType, socket); + } + + public void checkServerTrusted(final X509Certificate[] chain, final String authType, final SSLEngine sslEngine) throws CertificateException { + delegate.checkServerTrusted(chain, authType, sslEngine); + } + + public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { + delegate.checkServerTrusted(chain, authType); + } + + public X509Certificate[] getAcceptedIssuers() { + return delegate.getAcceptedIssuers(); + } +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SelectingServerSSLEngine.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SelectingServerSSLEngine.java new file mode 100644 index 00000000000..b890007bd44 --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/SelectingServerSSLEngine.java @@ -0,0 +1,559 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2015 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.builder; + +import java.nio.ByteBuffer; +import java.security.Principal; +import java.security.cert.Certificate; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiFunction; +import java.util.function.Function; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSessionContext; +import javax.security.cert.X509Certificate; + +import org.wildfly.common.Assert; +import org.wildfly.security.ssl.SSLContextSelector; +import org.wildfly.security.ssl.SSLExplorer; + +/** + * @author David M. Lloyd + */ +class SelectingServerSSLEngine extends SSLEngine { + + private static final SSLEngineResult UNDERFLOW_UNWRAP = new SSLEngineResult(SSLEngineResult.Status.BUFFER_UNDERFLOW, SSLEngineResult.HandshakeStatus.NEED_UNWRAP, 0, 0); + private static final SSLEngineResult OK_UNWRAP = new SSLEngineResult(SSLEngineResult.Status.OK, SSLEngineResult.HandshakeStatus.NEED_UNWRAP, 0, 0); + private final AtomicReference currentRef; + + SelectingServerSSLEngine(final SSLContextSelector selector) { + currentRef = new AtomicReference<>(new InitialState(selector, SSLContext::createSSLEngine)); + } + + SelectingServerSSLEngine(final SSLContextSelector selector, final String host, final int port) { + super(host, port); + currentRef = new AtomicReference<>(new InitialState(selector, sslContext -> sslContext.createSSLEngine(host, port))); + } + + public SSLEngineResult wrap(final ByteBuffer[] srcs, final int offset, final int length, final ByteBuffer dst) throws SSLException { + return currentRef.get().wrap(srcs, offset, length, dst); + } + + public SSLEngineResult wrap(final ByteBuffer src, final ByteBuffer dst) throws SSLException { + return currentRef.get().wrap(src, dst); + } + + public SSLEngineResult wrap(final ByteBuffer[] srcs, final ByteBuffer dst) throws SSLException { + return currentRef.get().wrap(srcs, dst); + } + + public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts, final int offset, final int length) throws SSLException { + return currentRef.get().unwrap(src, dsts, offset, length); + } + + public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer dst) throws SSLException { + return currentRef.get().unwrap(src, dst); + } + + public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts) throws SSLException { + return currentRef.get().unwrap(src, dsts); + } + + public String getPeerHost() { + return currentRef.get().getPeerHost(); + } + + public int getPeerPort() { + return currentRef.get().getPeerPort(); + } + + public SSLSession getHandshakeSession() { + return currentRef.get().getHandshakeSession(); + } + + public SSLParameters getSSLParameters() { + return currentRef.get().getSSLParameters(); + } + + public void setSSLParameters(final SSLParameters params) { + currentRef.get().setSSLParameters(params); + } + + public Runnable getDelegatedTask() { + return currentRef.get().getDelegatedTask(); + } + + public void closeInbound() throws SSLException { + currentRef.get().closeInbound(); + } + + public boolean isInboundDone() { + return currentRef.get().isInboundDone(); + } + + public void closeOutbound() { + currentRef.get().closeOutbound(); + } + + public boolean isOutboundDone() { + return currentRef.get().isOutboundDone(); + } + + public String[] getSupportedCipherSuites() { + return currentRef.get().getSupportedCipherSuites(); + } + + public String[] getEnabledCipherSuites() { + return currentRef.get().getEnabledCipherSuites(); + } + + public void setEnabledCipherSuites(final String[] cipherSuites) { + currentRef.get().setEnabledCipherSuites(cipherSuites); + } + + public String[] getSupportedProtocols() { + return currentRef.get().getSupportedProtocols(); + } + + public String[] getEnabledProtocols() { + return currentRef.get().getEnabledProtocols(); + } + + public void setEnabledProtocols(final String[] protocols) { + currentRef.get().setEnabledProtocols(protocols); + } + + public SSLSession getSession() { + return currentRef.get().getSession(); + } + + public void beginHandshake() throws SSLException { + currentRef.get().beginHandshake(); + } + + public SSLEngineResult.HandshakeStatus getHandshakeStatus() { + return currentRef.get().getHandshakeStatus(); + } + + public void setUseClientMode(final boolean clientMode) { + currentRef.get().setUseClientMode(clientMode); + } + + public boolean getUseClientMode() { + return currentRef.get().getUseClientMode(); + } + + public void setNeedClientAuth(final boolean clientAuth) { + currentRef.get().setNeedClientAuth(clientAuth); + } + + public boolean getNeedClientAuth() { + return currentRef.get().getNeedClientAuth(); + } + + public void setWantClientAuth(final boolean want) { + currentRef.get().setWantClientAuth(want); + } + + public boolean getWantClientAuth() { + return currentRef.get().getWantClientAuth(); + } + + public void setEnableSessionCreation(final boolean flag) { + currentRef.get().setEnableSessionCreation(flag); + } + + public boolean getEnableSessionCreation() { + return currentRef.get().getEnableSessionCreation(); + } + + public String getApplicationProtocol() { + return JDKSpecific.getApplicationProtocol(currentRef.get()); + } + + public String getHandshakeApplicationProtocol() { + return JDKSpecific.getHandshakeApplicationProtocol(currentRef.get()); + } + + public void setHandshakeApplicationProtocolSelector(BiFunction, String> selector) { + JDKSpecific.setHandshakeApplicationProtocolSelector(currentRef.get(), selector); + } + + public BiFunction, String> getHandshakeApplicationProtocolSelector() { + return JDKSpecific.getHandshakeApplicationProtocolSelector(currentRef.get()); + } + + static final int FL_WANT_C_AUTH = 1 << 0; + static final int FL_NEED_C_AUTH = 1 << 1; + static final int FL_SESSION_CRE = 1 << 2; + + class InitialState extends SSLEngine { + + private final SSLContextSelector selector; + private final AtomicInteger flags = new AtomicInteger(FL_SESSION_CRE); + private final Function engineFunction; + private int packetBufferSize = SSLExplorer.RECORD_HEADER_SIZE; + private final SSLSession handshakeSession = new SSLSession() { + public byte[] getId() { + throw Assert.unsupported(); + } + + public SSLSessionContext getSessionContext() { + throw Assert.unsupported(); + } + + public long getCreationTime() { + throw Assert.unsupported(); + } + + public long getLastAccessedTime() { + throw Assert.unsupported(); + } + + public void invalidate() { + throw Assert.unsupported(); + } + + public boolean isValid() { + return false; + } + + public void putValue(final String s, final Object o) { + throw Assert.unsupported(); + } + + public Object getValue(final String s) { + return null; + } + + public void removeValue(final String s) { + } + + public String[] getValueNames() { + throw Assert.unsupported(); + } + + public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { + throw Assert.unsupported(); + } + + public Certificate[] getLocalCertificates() { + return null; + } + + public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException { + throw Assert.unsupported(); + } + + public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { + throw Assert.unsupported(); + } + + public Principal getLocalPrincipal() { + throw Assert.unsupported(); + } + + public String getCipherSuite() { + throw Assert.unsupported(); + } + + public String getProtocol() { + throw Assert.unsupported(); + } + + public String getPeerHost() { + return SelectingServerSSLEngine.this.getPeerHost(); + } + + public int getPeerPort() { + return SelectingServerSSLEngine.this.getPeerPort(); + } + + public int getPacketBufferSize() { + return packetBufferSize; + } + + public int getApplicationBufferSize() { + throw Assert.unsupported(); + } + }; + + InitialState(final SSLContextSelector selector, final Function engineFunction) { + this.selector = selector; + this.engineFunction = engineFunction; + } + + public SSLSession getHandshakeSession() { + return handshakeSession; + } + + public SSLEngineResult wrap(final ByteBuffer[] srcs, final int offset, final int length, final ByteBuffer dst) throws SSLException { + return OK_UNWRAP; + } + + public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts, final int offset, final int length) throws SSLException { + SSLEngine next; + final int mark = src.position(); + try { + if (src.remaining() < SSLExplorer.RECORD_HEADER_SIZE) { + packetBufferSize = SSLExplorer.RECORD_HEADER_SIZE; + return UNDERFLOW_UNWRAP; + } + final int requiredSize = SSLExplorer.getRequiredSize(src); + if (src.remaining() < requiredSize) { + packetBufferSize = requiredSize; + return UNDERFLOW_UNWRAP; + } + SSLContext sslContext = selector.selectContext(SSLExplorer.explore(src)); + if (sslContext == null) { + // no SSL context is available + throw ElytronMessages.log.noContextForSslConnection(); + } + next = engineFunction.apply(sslContext); + next.setUseClientMode(false); + final int flagsVal = flags.get(); + if ((flagsVal & FL_WANT_C_AUTH) != 0) { + next.setWantClientAuth(true); + } else if ((flagsVal & FL_NEED_C_AUTH) != 0) { + next.setNeedClientAuth(true); + } + if ((flagsVal & FL_SESSION_CRE) != 0) { + next.setEnableSessionCreation(true); + } + currentRef.set(next); + } finally { + src.position(mark); + } + return next.unwrap(src, dsts, offset, length); + } + + public Runnable getDelegatedTask() { + return null; + } + + public void closeInbound() throws SSLException { + currentRef.set(CLOSED_STATE); + } + + public boolean isInboundDone() { + return false; + } + + public void closeOutbound() { + currentRef.set(CLOSED_STATE); + } + + public boolean isOutboundDone() { + return false; + } + + public String[] getSupportedCipherSuites() { + throw Assert.unsupported(); + } + + public String[] getEnabledCipherSuites() { + throw Assert.unsupported(); + } + + public void setEnabledCipherSuites(final String[] suites) { + throw Assert.unsupported(); + } + + public String[] getSupportedProtocols() { + throw Assert.unsupported(); + } + + public String[] getEnabledProtocols() { + throw Assert.unsupported(); + } + + public void setEnabledProtocols(final String[] protocols) { + throw Assert.unsupported(); + } + + public SSLSession getSession() { + return null; + } + + public void beginHandshake() throws SSLException { + } + + public SSLEngineResult.HandshakeStatus getHandshakeStatus() { + return SSLEngineResult.HandshakeStatus.NEED_UNWRAP; + } + + public void setUseClientMode(final boolean mode) { + if (mode) throw Assert.unsupported(); + } + + public boolean getUseClientMode() { + return false; + } + + public void setNeedClientAuth(final boolean need) { + final AtomicInteger flags = this.flags; + int oldVal, newVal; + do { + oldVal = flags.get(); + if (((oldVal & FL_NEED_C_AUTH) != 0) == need) { + return; + } + newVal = oldVal & FL_SESSION_CRE | FL_NEED_C_AUTH; + } while (! flags.compareAndSet(oldVal, newVal)); + } + + public boolean getNeedClientAuth() { + return (flags.get() & FL_NEED_C_AUTH) != 0; + } + + public void setWantClientAuth(final boolean want) { + final AtomicInteger flags = this.flags; + int oldVal, newVal; + do { + oldVal = flags.get(); + if (((oldVal & FL_WANT_C_AUTH) != 0) == want) { + return; + } + newVal = oldVal & FL_SESSION_CRE | FL_WANT_C_AUTH; + } while (! flags.compareAndSet(oldVal, newVal)); + } + + public boolean getWantClientAuth() { + return (flags.get() & FL_WANT_C_AUTH) != 0; + } + + public void setEnableSessionCreation(final boolean flag) { + final AtomicInteger flags = this.flags; + int oldVal, newVal; + do { + oldVal = flags.get(); + if (((oldVal & FL_SESSION_CRE) != 0) == flag) { + return; + } + newVal = oldVal ^ FL_SESSION_CRE; + } while (! flags.compareAndSet(oldVal, newVal)); + } + + public boolean getEnableSessionCreation() { + return (flags.get() & FL_SESSION_CRE) != 0; + } + } + + 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(); + } + + public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts, final int offset, final int length) throws SSLException { + throw ElytronMessages.log.sslClosed(); + } + + public Runnable getDelegatedTask() { + return null; + } + + public void closeInbound() throws SSLException { + } + + public boolean isInboundDone() { + return true; + } + + public void closeOutbound() { + + } + + public boolean isOutboundDone() { + return true; + } + + public String[] getSupportedCipherSuites() { + throw Assert.unsupported(); + } + + public String[] getEnabledCipherSuites() { + throw Assert.unsupported(); + } + + public void setEnabledCipherSuites(final String[] suites) { + throw Assert.unsupported(); + } + + public String[] getSupportedProtocols() { + throw Assert.unsupported(); + } + + public String[] getEnabledProtocols() { + throw Assert.unsupported(); + } + + public void setEnabledProtocols(final String[] protocols) { + throw Assert.unsupported(); + } + + public SSLSession getSession() { + return null; + } + + public void beginHandshake() throws SSLException { + throw ElytronMessages.log.sslClosed(); + } + + public SSLEngineResult.HandshakeStatus getHandshakeStatus() { + return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING; + } + + public void setUseClientMode(final boolean mode) { + throw Assert.unsupported(); + } + + public boolean getUseClientMode() { + return false; + } + + public void setNeedClientAuth(final boolean need) { + } + + public boolean getNeedClientAuth() { + return false; + } + + public void setWantClientAuth(final boolean want) { + } + + public boolean getWantClientAuth() { + return false; + } + + public void setEnableSessionCreation(final boolean flag) { + } + + public boolean getEnableSessionCreation() { + return false; + } + }; +} diff --git a/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/WrappingX509ExtendedTrustManager.java b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/WrappingX509ExtendedTrustManager.java new file mode 100644 index 00000000000..ed18947f7bc --- /dev/null +++ b/ssl/builder/src/main/java/org/wildfly/security/ssl/builder/WrappingX509ExtendedTrustManager.java @@ -0,0 +1,67 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2015 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.builder; + +import java.net.Socket; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.X509ExtendedTrustManager; +import javax.net.ssl.X509TrustManager; + +/** + * @author David M. Lloyd + */ +final class WrappingX509ExtendedTrustManager extends X509ExtendedTrustManager implements X509TrustManager { + + private final X509TrustManager delegate; + + WrappingX509ExtendedTrustManager(final X509TrustManager delegate) { + this.delegate = delegate; + } + + public void checkClientTrusted(final X509Certificate[] x509Certificates, final String s, final Socket socket) throws CertificateException { + delegate.checkClientTrusted(x509Certificates, s); + } + + public void checkServerTrusted(final X509Certificate[] x509Certificates, final String s, final Socket socket) throws CertificateException { + delegate.checkServerTrusted(x509Certificates, s); + } + + public void checkClientTrusted(final X509Certificate[] x509Certificates, final String s, final SSLEngine sslEngine) throws CertificateException { + delegate.checkClientTrusted(x509Certificates, s); + } + + public void checkServerTrusted(final X509Certificate[] x509Certificates, final String s, final SSLEngine sslEngine) throws CertificateException { + delegate.checkServerTrusted(x509Certificates, s); + } + + public void checkClientTrusted(final X509Certificate[] x509Certificates, final String s) throws CertificateException { + delegate.checkClientTrusted(x509Certificates, s); + } + + public void checkServerTrusted(final X509Certificate[] x509Certificates, final String s) throws CertificateException { + delegate.checkServerTrusted(x509Certificates, s); + } + + public X509Certificate[] getAcceptedIssuers() { + return delegate.getAcceptedIssuers(); + } +} diff --git a/ssl/deprecated/pom.xml b/ssl/deprecated/pom.xml new file mode 100644 index 00000000000..1bf289a341b --- /dev/null +++ b/ssl/deprecated/pom.xml @@ -0,0 +1,134 @@ + + + + + + + org.wildfly.security + wildfly-elytron-parent + 2.5.3.CR1-SNAPSHOT + ../../pom.xml + + + 4.0.0 + + wildfly-elytron-ssl-deprecated + + WildFly Elytron - SSL + WildFly Security SSL + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0-jboss-1 + + + default-compile + compile + + compile + + + 8 + ${project.build.directory} + ${project.compileSourceRoots} + ${project.build.outputDirectory} + + ${project.build.directory}/jdk-misc.jar + + + + + compile-java9 + compile + + compile + + + 9 + ${project.build.directory} + ${project.basedir}/src/main/java9 + ${project.build.directory}/classes/META-INF/versions/9 + + ${project.build.outputDirectory} + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${version.jar.plugin} + + + + true + ${project.version} + ${project.artifactId} + + + + + + + + + + org.wildfly.security + wildfly-elytron-auth-server + + + org.wildfly.security + wildfly-elytron-ssl + + + org.wildfly.security + wildfly-elytron-base + + + org.wildfly.security + wildfly-elytron-credential + + + org.wildfly.security + wildfly-elytron-x500 + + + + org.jboss.logging + jboss-logging + + + org.jboss.logging + jboss-logging-annotations + provided + + + org.jboss.logging + jboss-logging-processor + provided + + + + diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java index 178d85c9d70..2927bb40135 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLContextSpi.java @@ -36,6 +36,7 @@ * * @author David M. Lloyd */ +@Deprecated abstract class AbstractDelegatingSSLContextSpi extends SSLContextSpi { private final SSLContext delegate; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java index 10e0073b8c5..e9ef0162eb9 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLEngine.java @@ -31,6 +31,7 @@ /** * @author David M. Lloyd */ +@Deprecated abstract class AbstractDelegatingSSLEngine extends SSLEngine { private final SSLEngine delegate; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java index a74edb07e78..121dde03f90 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLParameters.java @@ -25,6 +25,7 @@ /** * @author David M. Lloyd */ +@Deprecated abstract class AbstractDelegatingSSLParameters extends SSLParameters { private final SSLParameters delegate; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java index aaac2a9fe78..4fc9afebfb0 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocket.java @@ -33,6 +33,7 @@ /** * @author David M. Lloyd */ +@Deprecated abstract class AbstractDelegatingSSLServerSocket extends SSLServerSocket { private final SSLServerSocket delegate; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java index dac284cafa3..90e9cfc9966 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLServerSocketFactory.java @@ -27,6 +27,7 @@ /** * @author David M. Lloyd */ +@Deprecated abstract class AbstractDelegatingSSLServerSocketFactory extends SSLServerSocketFactory { private final SSLServerSocketFactory delegate; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java index 88cbc3232d8..3edc8b3465f 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocket.java @@ -36,6 +36,7 @@ /** * @author David M. Lloyd */ +@Deprecated abstract class AbstractDelegatingSSLSocket extends SSLSocket { private final SSLSocket delegate; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java index fc5b093063a..8f18017466d 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/AbstractDelegatingSSLSocketFactory.java @@ -28,6 +28,7 @@ /** * @author David M. Lloyd */ +@Deprecated abstract class AbstractDelegatingSSLSocketFactory extends SSLSocketFactory { private final SSLSocketFactory delegate; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLContextSpi.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLContextSpi.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLContextSpi.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLContextSpi.java index 1553892d718..387c2b74f0c 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLContextSpi.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLContextSpi.java @@ -27,6 +27,7 @@ /** * @author David M. Lloyd */ +@Deprecated final class ConfiguredSSLContextSpi extends AbstractDelegatingSSLContextSpi { private final SSLConfigurator sslConfigurator; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLEngine.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLEngine.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLEngine.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLEngine.java index e490234a20c..33e401a0235 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLEngine.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLEngine.java @@ -27,6 +27,7 @@ * * @author David M. Lloyd */ +@Deprecated final class ConfiguredSSLEngine extends AbstractDelegatingSSLEngine { private final SSLContext sslContext; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocket.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocket.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocket.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocket.java index aa7c2a49daa..e60a44561be 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocket.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocket.java @@ -29,6 +29,7 @@ * * @author David M. Lloyd */ +@Deprecated final class ConfiguredSSLServerSocket extends AbstractDelegatingSSLServerSocket { private final SSLContext sslContext; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocketFactory.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocketFactory.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocketFactory.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocketFactory.java index 9c69debf3be..b310ac1f4d2 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocketFactory.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLServerSocketFactory.java @@ -29,6 +29,7 @@ /** * @author David M. Lloyd */ +@Deprecated final class ConfiguredSSLServerSocketFactory extends AbstractDelegatingSSLServerSocketFactory { private final SSLContext sslContext; private final SSLConfigurator sslConfigurator; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocket.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocket.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocket.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocket.java index b035d303b97..2213e0b4330 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocket.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocket.java @@ -27,6 +27,7 @@ * * @author David M. Lloyd */ +@Deprecated final class ConfiguredSSLSocket extends AbstractDelegatingSSLSocket { private final SSLContext sslContext; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocketFactory.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocketFactory.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocketFactory.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocketFactory.java index 315799dc8a5..fa77a4d193b 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocketFactory.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ConfiguredSSLSocketFactory.java @@ -30,6 +30,7 @@ /** * @author David M. Lloyd */ +@Deprecated final class ConfiguredSSLSocketFactory extends AbstractDelegatingSSLSocketFactory { private final SSLContext sslContext; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/DelegatingSSLContext.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/DelegatingSSLContext.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/DelegatingSSLContext.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/DelegatingSSLContext.java index 240728a75e4..a3c68ea8d47 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/DelegatingSSLContext.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/DelegatingSSLContext.java @@ -25,6 +25,7 @@ * * @author David M. Lloyd */ +@Deprecated final class DelegatingSSLContext extends SSLContext { /** diff --git a/ssl/src/main/java/org/wildfly/security/ssl/ElytronMessages.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ElytronMessages.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/ElytronMessages.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/ElytronMessages.java index 3f9efdbf2e7..226cec362b2 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/ElytronMessages.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/ElytronMessages.java @@ -51,7 +51,8 @@ @ValidIdRange(min = 5015, max = 5017), @ValidIdRange(min = 15000, max = 15999) }) -interface ElytronMessages extends BasicLogger { +@Deprecated +public interface ElytronMessages extends BasicLogger { ElytronMessages log = Logger.getMessageLogger(ElytronMessages.class, "org.wildfly.security"); ElytronMessages tls = Logger.getMessageLogger(ElytronMessages.class, "org.wildfly.security.tls"); diff --git a/ssl/src/main/java/org/wildfly/security/ssl/JDKSpecific.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/JDKSpecific.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/JDKSpecific.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/JDKSpecific.java index b3b0ababdb0..e342a5ce1a0 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/JDKSpecific.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/JDKSpecific.java @@ -29,6 +29,7 @@ import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSocket; +@Deprecated final class JDKSpecific { // SSLEngine Methods diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SSLConfiguratorImpl.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/SSLConfiguratorImpl.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/SSLConfiguratorImpl.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/SSLConfiguratorImpl.java index d3bff2dc58e..44bae86bf84 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/SSLConfiguratorImpl.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/SSLConfiguratorImpl.java @@ -25,7 +25,7 @@ import javax.net.ssl.SSLSocket; import org.wildfly.common.Assert; - +@Deprecated final class SSLConfiguratorImpl implements SSLConfigurator { private final ProtocolSelector protocolSelector; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java b/ssl/deprecated/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/deprecated/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java index 5ca5e0e24be..575fd1f6e2a 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/SSLContextBuilder.java @@ -57,13 +57,14 @@ * * @author David M. Lloyd */ +@Deprecated public final class SSLContextBuilder { private SecurityDomain securityDomain; // 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 ProtocolSelector protocolSelector = ProtocolSelector.defaultProtocols(); private boolean useCipherSuitesOrder = true; private boolean wantClientAuth; private boolean needClientAuth; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SSLUtils.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/SSLUtils.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/SSLUtils.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/SSLUtils.java index 4377fed8663..caa4ab1a44d 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/SSLUtils.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/SSLUtils.java @@ -59,6 +59,7 @@ * * @author David M. Lloyd */ +@Deprecated public final class SSLUtils { private static final String[] NO_STRINGS = new String[0]; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java index 0a7c9fb4549..a8ec969f90b 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/SecurityDomainTrustManager.java @@ -41,6 +41,7 @@ /** * @author David M. Lloyd */ +@Deprecated class SecurityDomainTrustManager extends X509ExtendedTrustManager { private final X509ExtendedTrustManager delegate; diff --git a/ssl/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java index 57a4b1b9188..871772b6e5a 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/SelectingServerSSLEngine.java @@ -42,6 +42,7 @@ /** * @author David M. Lloyd */ +@Deprecated class SelectingServerSSLEngine extends SSLEngine { private static final SSLEngineResult UNDERFLOW_UNWRAP = new SSLEngineResult(SSLEngineResult.Status.BUFFER_UNDERFLOW, SSLEngineResult.HandshakeStatus.NEED_UNWRAP, 0, 0); diff --git a/ssl/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java similarity index 99% rename from ssl/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java rename to ssl/deprecated/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java index b523ad045c7..9e8740c35bb 100644 --- a/ssl/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java +++ b/ssl/deprecated/src/main/java/org/wildfly/security/ssl/WrappingX509ExtendedTrustManager.java @@ -29,6 +29,7 @@ /** * @author David M. Lloyd */ +@Deprecated final class WrappingX509ExtendedTrustManager extends X509ExtendedTrustManager implements X509TrustManager { private final X509TrustManager delegate; diff --git a/tests/base/pom.xml b/tests/base/pom.xml index b16c213f2da..4c1b348734d 100644 --- a/tests/base/pom.xml +++ b/tests/base/pom.xml @@ -507,7 +507,12 @@ org.wildfly.security wildfly-elytron-sasl-scram
- + + + org.wildfly.security + wildfly-elytron-ssl-builder + + org.wildfly.security wildfly-elytron-x500 diff --git a/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java index 0ba8e2713a1..67bbf91250f 100644 --- a/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/auth/client/MaskedPasswordSSLAuthenticationTest.java @@ -51,8 +51,8 @@ import org.wildfly.security.auth.server.SecurityRealm; import org.wildfly.security.password.WildFlyElytronPasswordProvider; import org.wildfly.security.permission.PermissionVerifier; -import org.wildfly.security.ssl.SSLContextBuilder; -import org.wildfly.security.ssl.SSLUtils; +import org.wildfly.security.ssl.builder.SSLContextBuilder; +import org.wildfly.security.ssl.builder.SSLUtils; import org.wildfly.security.ssl.test.util.CAGenerationTool; import org.wildfly.security.ssl.test.util.CAGenerationTool.Identity; import org.wildfly.security.ssl.test.util.DefinedCAIdentity; diff --git a/tests/base/src/test/java/org/wildfly/security/auth/realm/token/JwtSecurityRealmTest.java b/tests/base/src/test/java/org/wildfly/security/auth/realm/token/JwtSecurityRealmTest.java index 917fb30cc47..adb71708476 100644 --- a/tests/base/src/test/java/org/wildfly/security/auth/realm/token/JwtSecurityRealmTest.java +++ b/tests/base/src/test/java/org/wildfly/security/auth/realm/token/JwtSecurityRealmTest.java @@ -71,7 +71,7 @@ import org.wildfly.security.evidence.Evidence; import org.wildfly.security.pem.Pem; import org.wildfly.security.realm.token.test.util.RsaJwk; -import org.wildfly.security.ssl.SSLContextBuilder; +import org.wildfly.security.ssl.builder.SSLContextBuilder; import org.wildfly.security.x500.cert.SelfSignedX509CertificateAndSigningKey; import static org.junit.Assert.assertEquals; diff --git a/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java index b1005514045..fb8a0a28dd7 100644 --- a/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/ssl/SSLAuthenticationTest.java @@ -81,6 +81,8 @@ import org.wildfly.security.auth.server.SecurityRealm; import org.wildfly.security.password.WildFlyElytronPasswordProvider; import org.wildfly.security.permission.PermissionVerifier; +import org.wildfly.security.ssl.builder.SSLContextBuilder; +import org.wildfly.security.ssl.builder.SSLUtils; import org.wildfly.security.ssl.test.util.CAGenerationTool; import org.wildfly.security.ssl.test.util.CAGenerationTool.Identity; import org.wildfly.security.ssl.test.util.CustomIdentity; diff --git a/tests/base/src/test/java/org/wildfly/security/ssl/SSLv2HelloAuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/ssl/SSLv2HelloAuthenticationTest.java index 392b291de8d..bcc42d64a66 100644 --- a/tests/base/src/test/java/org/wildfly/security/ssl/SSLv2HelloAuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/ssl/SSLv2HelloAuthenticationTest.java @@ -76,6 +76,8 @@ import org.wildfly.security.auth.server.SecurityIdentity; import org.wildfly.security.auth.server.SecurityRealm; import org.wildfly.security.permission.PermissionVerifier; +import org.wildfly.security.ssl.builder.SSLContextBuilder; +import org.wildfly.security.ssl.builder.SSLUtils; import org.wildfly.security.x500.principal.X500AttributePrincipalDecoder; import org.wildfly.security.x500.cert.BasicConstraintsExtension; import org.wildfly.security.x500.cert.SelfSignedX509CertificateAndSigningKey; diff --git a/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java b/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java index 826916e29ca..babdc778782 100644 --- a/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java +++ b/tests/base/src/test/java/org/wildfly/security/ssl/TLS13AuthenticationTest.java @@ -50,6 +50,8 @@ import org.wildfly.security.auth.server.SecurityIdentity; import org.wildfly.security.auth.server.SecurityRealm; import org.wildfly.security.permission.PermissionVerifier; +import org.wildfly.security.ssl.builder.SSLContextBuilder; +import org.wildfly.security.ssl.builder.SSLUtils; import org.wildfly.security.ssl.test.util.CAGenerationTool; import org.wildfly.security.ssl.test.util.CAGenerationTool.Identity; import org.wildfly.security.ssl.test.util.DefinedCAIdentity; diff --git a/tests/base/src/test/java/org/wildfly/security/ssl/SSLConfiguratorImplTest.java b/tests/base/src/test/java/org/wildfly/security/ssl/builder/SSLConfiguratorImplTest.java similarity index 99% rename from tests/base/src/test/java/org/wildfly/security/ssl/SSLConfiguratorImplTest.java rename to tests/base/src/test/java/org/wildfly/security/ssl/builder/SSLConfiguratorImplTest.java index 75a44dedadb..1479da7cea3 100644 --- a/tests/base/src/test/java/org/wildfly/security/ssl/SSLConfiguratorImplTest.java +++ b/tests/base/src/test/java/org/wildfly/security/ssl/builder/SSLConfiguratorImplTest.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.wildfly.security.ssl; +package org.wildfly.security.ssl.builder; import org.junit.Test; diff --git a/wildfly-elytron/pom.xml b/wildfly-elytron/pom.xml index a9f39f0c20b..9cbdf214736 100644 --- a/wildfly-elytron/pom.xml +++ b/wildfly-elytron/pom.xml @@ -481,6 +481,14 @@ org.wildfly.security wildfly-elytron-ssl + + org.wildfly.security + wildfly-elytron-ssl-deprecated + + + org.wildfly.security + wildfly-elytron-ssl-builder + org.wildfly.security wildfly-elytron-ssh-util @@ -867,6 +875,16 @@ wildfly-elytron-ssl ${project.version} + + org.wildfly.security + wildfly-elytron-ssl-deprecated + ${project.version} + + + org.wildfly.security + wildfly-elytron-ssl-builder + ${project.version} + org.wildfly.security wildfly-elytron-tool