diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2019-07-02 16:38:19 +0200 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2019-07-03 15:15:56 +0200 |
commit | e79a7e85d8f79e2cbf1495a6da468b3009ea4d2c (patch) | |
tree | 85a1a75a52e05f5513299d699db753decba542a6 /jdisc_http_service/src | |
parent | e83bf77aeb2121cd710c7376de8b41646a6ef3f1 (diff) |
Add SslContextFactoryProvider that uses TlsContex
Diffstat (limited to 'jdisc_http_service/src')
4 files changed, 150 insertions, 51 deletions
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/DefaultSslContextFactoryProvider.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/DefaultSslContextFactoryProvider.java index a3c1c79fa76..bd814937ab9 100644 --- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/DefaultSslContextFactoryProvider.java +++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/DefaultSslContextFactoryProvider.java @@ -15,21 +15,38 @@ import org.eclipse.jetty.util.ssl.SslContextFactory; */ public class DefaultSslContextFactoryProvider extends AbstractComponent implements SslContextFactoryProvider { - private final TlsContext tlsContext = TransportSecurityUtils.getConfigFile() - .map(configFile -> new ConfigFiledBasedTlsContext(configFile, TransportSecurityUtils.getInsecureAuthorizationMode())) - .orElse(null); + private final SslContextFactoryProvider instance = TransportSecurityUtils.getConfigFile() + .map(configFile -> (SslContextFactoryProvider) new StaticTlsContextBasedProvider( + new ConfigFiledBasedTlsContext(configFile, TransportSecurityUtils.getInsecureAuthorizationMode()))) + .orElseGet(ThrowingSslContextFactoryProvider::new); @Override public SslContextFactory getInstance(String containerId, int port) { - if (tlsContext != null) { - return new TlsContextManagedSslContextFactory(tlsContext); - } else { - throw new UnsupportedOperationException(); - } + return instance.getInstance(containerId, port); } @Override public void deconstruct() { - if (tlsContext != null) tlsContext.close(); + instance.close(); + } + + private static class ThrowingSslContextFactoryProvider implements SslContextFactoryProvider { + @Override + public SslContextFactory getInstance(String containerId, int port) { + throw new UnsupportedOperationException(); + } + } + + private static class StaticTlsContextBasedProvider extends TlsContextBasedProvider { + final TlsContext tlsContext; + + StaticTlsContextBasedProvider(TlsContext tlsContext) { + this.tlsContext = tlsContext; + } + + @Override + protected TlsContext getTlsContext(String containerId, int port) { + return tlsContext; + } } }
\ No newline at end of file diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/TlsContextBasedProvider.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/TlsContextBasedProvider.java new file mode 100644 index 00000000000..e8ae13e48be --- /dev/null +++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/TlsContextBasedProvider.java @@ -0,0 +1,54 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.jdisc.http.ssl.impl; + +import com.yahoo.component.AbstractComponent; +import com.yahoo.jdisc.http.ssl.SslContextFactoryProvider; +import com.yahoo.security.tls.TlsContext; +import org.eclipse.jetty.util.ssl.SslContextFactory; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import java.util.Arrays; + +/** + * A {@link SslContextFactoryProvider} that creates {@link SslContextFactory} instances from {@link TlsContext} instances. + * + * @author bjorncs + */ +public abstract class TlsContextBasedProvider extends AbstractComponent implements SslContextFactoryProvider { + + protected abstract TlsContext getTlsContext(String containerId, int port); + + @Override + public final SslContextFactory getInstance(String containerId, int port) { + TlsContext tlsContext = getTlsContext(containerId, port); + SSLContext sslContext = tlsContext.context(); + SSLParameters parameters = tlsContext.parameters(); + + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setSslContext(sslContext); + + sslContextFactory.setNeedClientAuth(parameters.getNeedClientAuth()); + sslContextFactory.setWantClientAuth(parameters.getWantClientAuth()); + + String[] enabledProtocols = parameters.getProtocols(); + sslContextFactory.setIncludeProtocols(enabledProtocols); + String[] supportedProtocols = sslContext.getSupportedSSLParameters().getProtocols(); + sslContextFactory.setExcludeProtocols(createExclusionList(enabledProtocols, supportedProtocols)); + + String[] enabledCiphers = parameters.getCipherSuites(); + String[] supportedCiphers = sslContext.getSupportedSSLParameters().getCipherSuites(); + sslContextFactory.setIncludeCipherSuites(enabledCiphers); + sslContextFactory.setExcludeCipherSuites(createExclusionList(enabledCiphers, supportedCiphers)); + return sslContextFactory; + } + + private static String[] createExclusionList(String[] enabledValues, String[] supportedValues) { + return Arrays.stream(supportedValues) + .filter(supportedValue -> + Arrays.stream(enabledValues) + .noneMatch(enabledValue -> enabledValue.equals(supportedValue))) + .toArray(String[]::new); + } + +} diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/TlsContextManagedSslContextFactory.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/TlsContextManagedSslContextFactory.java deleted file mode 100644 index a5652042f9e..00000000000 --- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/ssl/impl/TlsContextManagedSslContextFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.ssl.impl; - -import com.yahoo.security.tls.TlsContext; -import org.eclipse.jetty.util.ssl.SslContextFactory; - -import javax.net.ssl.SSLEngine; -import java.net.InetSocketAddress; - -/** - * A Jetty {@link SslContextFactory} backed by {@link TlsContext}. - * Overrides methods that are used by Jetty to construct ssl sockets and ssl engines. - * - * @author bjorncs - */ -class TlsContextManagedSslContextFactory extends SslContextFactory.Server { - - private final TlsContext tlsContext; - - TlsContextManagedSslContextFactory(TlsContext tlsContext) { - this.tlsContext = tlsContext; - } - - @Override protected void doStart() { } // Override default behaviour - @Override protected void doStop() { } // Override default behaviour - - @Override - public SSLEngine newSSLEngine() { - return tlsContext.createSslEngine(); - } - - @Override - public SSLEngine newSSLEngine(InetSocketAddress address) { - return tlsContext.createSslEngine(address.getHostString(), address.getPort()); - } - - @Override - public SSLEngine newSSLEngine(String host, int port) { - return tlsContext.createSslEngine(host, port); - } - -} diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/ssl/impl/TlsContextBasedProviderTest.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/ssl/impl/TlsContextBasedProviderTest.java new file mode 100644 index 00000000000..88db5c99de9 --- /dev/null +++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/ssl/impl/TlsContextBasedProviderTest.java @@ -0,0 +1,70 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.jdisc.http.ssl.impl; + +import com.yahoo.security.KeyUtils; +import com.yahoo.security.X509CertificateBuilder; +import com.yahoo.security.tls.AuthorizationMode; +import com.yahoo.security.tls.DefaultTlsContext; +import com.yahoo.security.tls.PeerAuthentication; +import com.yahoo.security.tls.TlsContext; +import com.yahoo.security.tls.policy.AuthorizedPeers; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.junit.Test; + +import javax.security.auth.x500.X500Principal; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.cert.X509Certificate; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.Set; + +import static com.yahoo.security.KeyAlgorithm.EC; +import static com.yahoo.security.SignatureAlgorithm.SHA256_WITH_ECDSA; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author bjorncs + */ +public class TlsContextBasedProviderTest { + + @Test + public void creates_sslcontextfactory_from_tlscontext() { + TlsContext tlsContext = createTlsContext(); + var provider = new SimpleTlsContextBasedProvider(tlsContext); + SslContextFactory sslContextFactory = provider.getInstance("dummyContainerId", 8080); + assertNotNull(sslContextFactory); + assertArrayEquals(tlsContext.parameters().getCipherSuites(), sslContextFactory.getIncludeCipherSuites()); + } + + private static TlsContext createTlsContext() { + KeyPair keyPair = KeyUtils.generateKeypair(EC); + X509Certificate certificate = X509CertificateBuilder + .fromKeypair( + keyPair, + new X500Principal("CN=dummy"), + Instant.EPOCH, + Instant.EPOCH.plus(100000, ChronoUnit.DAYS), + SHA256_WITH_ECDSA, + BigInteger.ONE) + .build(); + return new DefaultTlsContext( + List.of(certificate), keyPair.getPrivate(), List.of(certificate), new AuthorizedPeers(Set.of()), AuthorizationMode.ENFORCE, PeerAuthentication.NEED); + } + + private static class SimpleTlsContextBasedProvider extends TlsContextBasedProvider { + final TlsContext tlsContext; + + SimpleTlsContextBasedProvider(TlsContext tlsContext) { + this.tlsContext = tlsContext; + } + + @Override + protected TlsContext getTlsContext(String containerId, int port) { + return tlsContext; + } + + } +}
\ No newline at end of file |