From 2b6c4fc5abebf7eb0df350d43d81e0021d50d271 Mon Sep 17 00:00:00 2001 From: Raheela Date: Tue, 15 Jan 2019 15:40:54 +0500 Subject: [PATCH] Unlike Jetty and Tomcat, Reactor Netty and Undertow do not cause a startup failure when SSL is enabled but no key store is configured issue fixed. --- .../embedded/netty/SslServerCustomizer.java | 32 ++++++++++++++++--- .../undertow/SslBuilderCustomizer.java | 31 +++++++++++++++--- .../netty/SslServerCustomizerTests.java | 17 ++++++++++ .../undertow/SslBuilderCustomizerTests.java | 21 ++++++++++++ 4 files changed, 91 insertions(+), 10 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/SslServerCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/SslServerCustomizer.java index 2d0e14ce9523..cb2fbfb36410 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/SslServerCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/SslServerCustomizer.java @@ -16,6 +16,7 @@ package org.springframework.boot.web.embedded.netty; +import java.io.FileNotFoundException; import java.net.URL; import java.security.KeyStore; import java.util.Arrays; @@ -31,6 +32,7 @@ import org.springframework.boot.web.server.Http2; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.SslStoreProvider; +import org.springframework.boot.web.server.WebServerException; import org.springframework.util.ResourceUtils; /** @@ -38,6 +40,7 @@ * instance. * * @author Brian Clozel + * @author Raheela Aslam */ public class SslServerCustomizer implements NettyServerCustomizer { @@ -135,21 +138,40 @@ private KeyStore getTrustStore(Ssl ssl, SslStoreProvider sslStoreProvider) if (sslStoreProvider != null) { return sslStoreProvider.getTrustStore(); } - return loadKeyStore(ssl.getTrustStoreType(), ssl.getTrustStoreProvider(), + return loadTrustStore(ssl.getTrustStoreType(), ssl.getTrustStoreProvider(), ssl.getTrustStore(), ssl.getTrustStorePassword()); } private KeyStore loadKeyStore(String type, String provider, String resource, String password) throws Exception { - type = (type != null) ? type : "JKS"; + + return loadStore(type, provider, resource, password); + } + + private KeyStore loadTrustStore(String type, String provider, String resource, + String password) throws Exception { if (resource == null) { return null; } + else { + return loadStore(type, provider, resource, password); + } + } + + private KeyStore loadStore(String type, String provider, String resource, + String password) throws Exception { + type = (type != null) ? type : "JKS"; KeyStore store = (provider != null) ? KeyStore.getInstance(type, provider) : KeyStore.getInstance(type); - URL url = ResourceUtils.getURL(resource); - store.load(url.openStream(), (password != null) ? password.toCharArray() : null); - return store; + try { + URL url = ResourceUtils.getURL(resource); + store.load(url.openStream(), + (password != null) ? password.toCharArray() : null); + return store; + } + catch (FileNotFoundException ex) { + throw new WebServerException("Could not load store: " + ex.getMessage(), ex); + } } } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java index bcc427de3ff1..8385fd7abd30 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizer.java @@ -16,6 +16,7 @@ package org.springframework.boot.web.embedded.undertow; +import java.io.FileNotFoundException; import java.net.InetAddress; import java.net.Socket; import java.net.URL; @@ -41,12 +42,14 @@ import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.SslStoreProvider; +import org.springframework.boot.web.server.WebServerException; import org.springframework.util.ResourceUtils; /** * {@link UndertowBuilderCustomizer} that configures SSL on the given builder instance. * * @author Brian Clozel + * @author Raheela Aslam */ class SslBuilderCustomizer implements UndertowBuilderCustomizer { @@ -166,21 +169,39 @@ private KeyStore getTrustStore(Ssl ssl, SslStoreProvider sslStoreProvider) if (sslStoreProvider != null) { return sslStoreProvider.getTrustStore(); } - return loadKeyStore(ssl.getTrustStoreType(), ssl.getTrustStoreProvider(), + return loadTrustStore(ssl.getTrustStoreType(), ssl.getTrustStoreProvider(), ssl.getTrustStore(), ssl.getTrustStorePassword()); } private KeyStore loadKeyStore(String type, String provider, String resource, String password) throws Exception { - type = (type != null) ? type : "JKS"; + return loadStore(type, provider, resource, password); + } + + private KeyStore loadTrustStore(String type, String provider, String resource, + String password) throws Exception { if (resource == null) { return null; } + else { + return loadStore(type, provider, resource, password); + } + } + + private KeyStore loadStore(String type, String provider, String resource, + String password) throws Exception { + type = (type != null) ? type : "JKS"; KeyStore store = (provider != null) ? KeyStore.getInstance(type, provider) : KeyStore.getInstance(type); - URL url = ResourceUtils.getURL(resource); - store.load(url.openStream(), (password != null) ? password.toCharArray() : null); - return store; + try { + URL url = ResourceUtils.getURL(resource); + store.load(url.openStream(), + (password != null) ? password.toCharArray() : null); + return store; + } + catch (FileNotFoundException ex) { + throw new WebServerException("Could not load store: " + ex.getMessage(), ex); + } } /** diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/netty/SslServerCustomizerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/netty/SslServerCustomizerTests.java index 17ed85276acf..4c61a6b39dec 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/netty/SslServerCustomizerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/netty/SslServerCustomizerTests.java @@ -29,6 +29,7 @@ * Tests for {@link SslServerCustomizer}. * * @author Andy Wilkinson + * @author Raheela Aslam */ public class SslServerCustomizerTests { @@ -68,4 +69,20 @@ public void trustStoreProviderIsUsedWhenCreatingTrustStore() throws Exception { } } + @Test + public void keyStoreProviderIsUsedWhenKeyStoreNotContaining() throws Exception { + Ssl ssl = new Ssl(); + ssl.setKeyPassword("password"); + SslServerCustomizer customizer = new SslServerCustomizer(ssl, null, null); + try { + customizer.getKeyManagerFactory(ssl, null); + fail(); + } + catch (IllegalStateException ex) { + Throwable cause = ex.getCause(); + assertThat(cause).isInstanceOf(IllegalArgumentException.class); + assertThat(cause).hasMessageContaining("Resource location must not be null"); + } + } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizerTests.java index bbf7c87e6734..7a4db1633033 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/SslBuilderCustomizerTests.java @@ -33,6 +33,7 @@ * Tests for {@link SslBuilderCustomizer} * * @author Brian Clozel + * @author Raheela Aslam */ public class SslBuilderCustomizerTests { @@ -88,4 +89,24 @@ public void trustStoreProviderIsUsedWhenCreatingTrustStore() throws Exception { } } + @Test + public void getKeyManagersWhenKeyStoreIsNotProvided() throws Exception { + Ssl ssl = new Ssl(); + ssl.setKeyPassword("password"); + SslBuilderCustomizer customizer = new SslBuilderCustomizer(8080, + InetAddress.getLocalHost(), ssl, null); + try { + KeyManager[] keyManagers = ReflectionTestUtils.invokeMethod(customizer, + "getKeyManagers", ssl, null); + Class name = Class.forName("org.springframework.boot.web.embedded.undertow" + + ".SslBuilderCustomizer$ConfigurableAliasKeyManager"); + assertThat(keyManagers[0]).isNotInstanceOf(name); + } + catch (IllegalStateException ex) { + Throwable cause = ex.getCause(); + assertThat(cause).isInstanceOf(IllegalArgumentException.class); + assertThat(cause).hasMessageContaining("Resource location must not be null"); + } + } + }