diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java index 496d5cdb109..10356fcdf33 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -190,9 +190,9 @@ class SslServerCustomizer implements JettyServerCustomizer { URL url = ResourceUtils.getURL(ssl.getKeyStore()); factory.setKeyStoreResource(Resource.newResource(url)); } - catch (IOException ex) { + catch (Exception ex) { throw new WebServerException( - "Could not find key store '" + ssl.getKeyStore() + "'", ex); + "Could not load key store '" + ssl.getKeyStore() + "'", ex); } if (ssl.getKeyStoreType() != null) { factory.setKeyStoreType(ssl.getKeyStoreType()); 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 cb2fbfb3641..5ea9c6df47b 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.boot.web.embedded.netty; -import java.io.FileNotFoundException; import java.net.URL; import java.security.KeyStore; import java.util.Arrays; @@ -169,9 +168,11 @@ public class SslServerCustomizer implements NettyServerCustomizer { (password != null) ? password.toCharArray() : null); return store; } - catch (FileNotFoundException ex) { - throw new WebServerException("Could not load store: " + ex.getMessage(), ex); + catch (Exception ex) { + throw new WebServerException("Could not load key store '" + resource + "'", + ex); } + } } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java index 3e10360b05b..d26ba86fb9a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -132,9 +132,9 @@ class SslConnectorCustomizer implements TomcatConnectorCustomizer { try { protocol.setKeystoreFile(ResourceUtils.getURL(ssl.getKeyStore()).toString()); } - catch (FileNotFoundException ex) { - throw new WebServerException("Could not load key store: " + ex.getMessage(), - ex); + catch (Exception ex) { + throw new WebServerException( + "Could not load key store '" + ssl.getKeyStore() + "'", ex); } if (ssl.getKeyStoreType() != null) { protocol.setKeystoreType(ssl.getKeyStoreType()); 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 8385fd7abd3..2408cab336a 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.boot.web.embedded.undertow; -import java.io.FileNotFoundException; import java.net.InetAddress; import java.net.Socket; import java.net.URL; @@ -199,8 +198,9 @@ class SslBuilderCustomizer implements UndertowBuilderCustomizer { (password != null) ? password.toCharArray() : null); return store; } - catch (FileNotFoundException ex) { - throw new WebServerException("Could not load store: " + ex.getMessage(), ex); + catch (Exception ex) { + throw new WebServerException("Could not load key store '" + resource + "'", + ex); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizerTests.java index a89a8e41ee3..24dd45ad065 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,10 +26,12 @@ import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.Test; import org.springframework.boot.web.server.Http2; import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.WebServerException; import static org.assertj.core.api.Assertions.assertThat; @@ -78,6 +80,20 @@ public class SslServerCustomizerTests { .isNull(); } + @Test + public void configureSslWhenSslIsEnabledWithNoKeyStoreThrowsWebServerException() + throws Exception { + Ssl ssl = new Ssl(); + SslServerCustomizer customizer = new SslServerCustomizer(null, ssl, null, null); + try { + customizer.configureSsl(new SslContextFactory(), ssl, null); + } + catch (Exception ex) { + assertThat(ex).isInstanceOf(WebServerException.class); + assertThat(ex).hasMessageContaining("Could not load key store 'null'"); + } + } + private Server createCustomizedServer() { return createCustomizedServer(new Http2()); } 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 4c61a6b39de..e785577fd53 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import java.security.NoSuchProviderException; import org.junit.Test; import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.WebServerException; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @@ -70,9 +71,9 @@ public class SslServerCustomizerTests { } @Test - public void keyStoreProviderIsUsedWhenKeyStoreNotContaining() throws Exception { + public void getKeyManagerFactoryWhenSslIsEnabledWithNoKeyStoreThrowsWebServerException() + throws Exception { Ssl ssl = new Ssl(); - ssl.setKeyPassword("password"); SslServerCustomizer customizer = new SslServerCustomizer(ssl, null, null); try { customizer.getKeyManagerFactory(ssl, null); @@ -80,8 +81,8 @@ public class SslServerCustomizerTests { } catch (IllegalStateException ex) { Throwable cause = ex.getCause(); - assertThat(cause).isInstanceOf(IllegalArgumentException.class); - assertThat(cause).hasMessageContaining("Resource location must not be null"); + assertThat(cause).isInstanceOf(WebServerException.class); + assertThat(cause).hasMessageContaining("Could not load key store 'null'"); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java index 286f9417b3b..db7d130c6ab 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/SslConnectorCustomizerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,11 +37,13 @@ import org.junit.Test; import org.springframework.boot.testsupport.rule.OutputCapture; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.SslStoreProvider; +import org.springframework.boot.web.server.WebServerException; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; @@ -189,6 +191,19 @@ public class SslConnectorCustomizerTests { assertThat(this.output.toString()).doesNotContain("Password verification failed"); } + @Test + public void customizeWhenSslIsEnabledWithNoKeyStoreThrowsWebServerException() { + try { + new SslConnectorCustomizer(new Ssl(), null) + .customize(this.tomcat.getConnector()); + fail(); + } + catch (Exception ex) { + assertThat(ex).isInstanceOf(WebServerException.class); + assertThat(ex).hasMessageContaining("Could not load key store 'null'"); + } + } + private KeyStore loadStore() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { KeyStore keyStore = KeyStore.getInstance("JKS"); 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 7a4db163303..e385705eb8d 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import javax.net.ssl.KeyManager; import org.junit.Test; import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.WebServerException; import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -90,22 +91,19 @@ public class SslBuilderCustomizerTests { } @Test - public void getKeyManagersWhenKeyStoreIsNotProvided() throws Exception { + public void getKeyManagersWhenSslIsEnabledWithNoKeyStoreThrowsWebServerException() + 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); + ReflectionTestUtils.invokeMethod(customizer, "getKeyManagers", ssl, null); + fail(); } catch (IllegalStateException ex) { Throwable cause = ex.getCause(); - assertThat(cause).isInstanceOf(IllegalArgumentException.class); - assertThat(cause).hasMessageContaining("Resource location must not be null"); + assertThat(cause).isInstanceOf(WebServerException.class); + assertThat(cause).hasMessageContaining("Could not load key store 'null'"); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java index 9eefb072bf1..a64959a1124 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,6 +62,7 @@ import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Base for testing classes that extends {@link AbstractReactiveWebServerFactory}. @@ -291,6 +292,12 @@ public abstract class AbstractReactiveWebServerFactoryTests { assertResponseIsNotCompressed(response); } + @Test + public void whenSslIsEnabledAndNoKeyStoreIsConfiguredThenServerFailsToStart() { + assertThatThrownBy(() -> testBasicSslWithKeyStore(null, null)) + .hasMessageContaining("Could not load key store 'null'"); + } + protected WebClient prepareCompressionTest() { Compression compression = new Compression(); compression.setEnabled(true);