From 258c6f116a24f107ba1eb06420d8be1cff1ff36e Mon Sep 17 00:00:00 2001 From: Vladimir Tsanev Date: Thu, 11 Sep 2014 01:20:03 +0300 Subject: [PATCH] Add store type and store provider properties to SSL configuration Closes gh-1545 --- .../appendix-application-properties.adoc | 4 ++ .../boot/context/embedded/Ssl.java | 40 ++++++++++++++++++ .../JettyEmbeddedServletContainerFactory.java | 12 ++++++ ...TomcatEmbeddedServletContainerFactory.java | 12 ++++++ ...tEmbeddedServletContainerFactoryTests.java | 40 ++++++++++++++++++ spring-boot/src/test/resources/test.p12 | Bin 0 -> 2336 bytes 6 files changed, 108 insertions(+) create mode 100644 spring-boot/src/test/resources/test.p12 diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index e9b0bba440f..1f08b411959 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -61,9 +61,13 @@ content into your application; rather pick only the properties that you need. server.ssl.key-password= server.ssl.key-store= server.ssl.key-store-password= + server.ssl.key-store-provider= + server.ssl.key-store-type= server.ssl.protocol=TLS server.ssl.trust-store= server.ssl.trust-store-password= + server.ssl.trust-store-provider= + server.ssl.trust-store-type= server.tomcat.access-log-pattern= # log pattern of the access log server.tomcat.access-log-enabled=false # is access logging enabled server.tomcat.protocol-header=x-forwarded-proto # ssl forward headers diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java index b8726771434..1bed8222221 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/Ssl.java @@ -36,10 +36,18 @@ public class Ssl { private String keyStorePassword; + private String keyStoreType; + + private String keyStoreProvider; + private String trustStore; private String trustStorePassword; + private String trustStoreType; + + private String trustStoreProvider; + private String protocol = "TLS"; public ClientAuth getClientAuth() { @@ -90,6 +98,22 @@ public class Ssl { this.keyStorePassword = keyStorePassword; } + public String getKeyStoreType() { + return this.keyStoreType; + } + + public void setKeyStoreType(String keyStoreType) { + this.keyStoreType = keyStoreType; + } + + public String getKeyStoreProvider() { + return this.keyStoreProvider; + } + + public void setKeyStoreProvider(String keyStoreProvider) { + this.keyStoreProvider = keyStoreProvider; + } + public String getTrustStore() { return this.trustStore; } @@ -106,6 +130,22 @@ public class Ssl { this.trustStorePassword = trustStorePassword; } + public String getTrustStoreType() { + return this.trustStoreType; + } + + public void setTrustStoreType(String trustStoreType) { + this.trustStoreType = trustStoreType; + } + + public String getTrustStoreProvider() { + return this.trustStoreProvider; + } + + public void setTrustStoreProvider(String trustStoreProvider) { + this.trustStoreProvider = trustStoreProvider; + } + public String getProtocol() { return this.protocol; } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java index 5268dc1ee5d..8e228cedf68 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java @@ -175,6 +175,12 @@ public class JettyEmbeddedServletContainerFactory extends throw new EmbeddedServletContainerException("Could not find key store '" + ssl.getKeyStore() + "'", ex); } + if (ssl.getKeyStoreType() != null) { + factory.setKeyStoreType(ssl.getKeyStoreType()); + } + if (ssl.getKeyStoreProvider() != null) { + factory.setKeyStoreProvider(ssl.getKeyStoreProvider()); + } } private void configureSslTrustStore(SslContextFactory factory, Ssl ssl) { @@ -191,6 +197,12 @@ public class JettyEmbeddedServletContainerFactory extends "Could not find trust store '" + ssl.getTrustStore() + "'", ex); } } + if (ssl.getTrustStoreType() != null) { + factory.setTrustStoreType(ssl.getTrustStoreType()); + } + if (ssl.getTrustStoreProvider() != null) { + factory.setTrustStoreProvider(ssl.getTrustStoreProvider()); + } } /** diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index b1385094679..51fa948a82e 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -290,6 +290,12 @@ public class TomcatEmbeddedServletContainerFactory extends throw new EmbeddedServletContainerException("Could not find key store " + ssl.getKeyStore(), ex); } + if (ssl.getKeyStoreType() != null) { + protocol.setKeystoreType(ssl.getKeyStoreType()); + } + if (ssl.getKeyStoreProvider() != null) { + protocol.setKeystoreProvider(ssl.getKeyStoreProvider()); + } } private void configureSslTrustStore(AbstractHttp11JsseProtocol protocol, Ssl ssl) { @@ -304,6 +310,12 @@ public class TomcatEmbeddedServletContainerFactory extends } } protocol.setTruststorePass(ssl.getTrustStorePassword()); + if (ssl.getTrustStoreType() != null) { + protocol.setTruststoreType(ssl.getTrustStoreType()); + } + if (ssl.getTrustStoreProvider() != null) { + protocol.setTruststoreProvider(ssl.getTrustStoreProvider()); + } } /** diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java index 74bbd7aab93..2850624d4dd 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java @@ -341,6 +341,46 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests { equalTo("test")); } + @Test + public void pkcs12KeyStoreAndTrustStore() throws Exception { + FileCopyUtils.copy("test", + new FileWriter(this.temporaryFolder.newFile("test.txt"))); + + AbstractEmbeddedServletContainerFactory factory = getFactory(); + factory.setDocumentRoot(this.temporaryFolder.getRoot()); + + Ssl ssl = new Ssl(); + ssl.setKeyStore("src/test/resources/test.p12"); + ssl.setKeyStorePassword("secret"); + ssl.setKeyStoreType("pkcs12"); + ssl.setTrustStore("src/test/resources/test.p12"); + ssl.setTrustStorePassword("secret"); + ssl.setTrustStoreType("pkcs12"); + ssl.setClientAuth(ClientAuth.NEED); + factory.setSsl(ssl); + + this.container = factory.getEmbeddedServletContainer(); + this.container.start(); + + KeyStore keyStore = KeyStore.getInstance("pkcs12"); + keyStore.load(new FileInputStream(new File("src/test/resources/test.p12")), + "secret".toCharArray()); + + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( + new SSLContextBuilder() + .loadTrustMaterial(null, new TrustSelfSignedStrategy()) + .loadKeyMaterial(keyStore, "secret".toCharArray()).build()); + + HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory) + .build(); + + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory( + httpClient); + + assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory), + equalTo("test")); + } + @Test public void sslNeedsClientAuthenticationSucceedsWithClientCertificate() throws Exception { diff --git a/spring-boot/src/test/resources/test.p12 b/spring-boot/src/test/resources/test.p12 new file mode 100644 index 0000000000000000000000000000000000000000..5726ff02f4bec25e4f8cab48aa6f300694ec010e GIT binary patch literal 2336 zcmZXUcTf`u8pYE|Lhma|QIuX16qa@@RVh-X*8tLmAjQzd& z84n+a;Nio^_5cbG4)`a6k?~;XW6K@{1ROuhe-a?-6b$+A2Cm~q9tb?g`eL(8AbSb~ zf&-HAU@4!5v2>nz&p&M_l@Zd(aBvlct9$7PnbahqnEbcln3h`DNbsUzni*b_YAo*|?hL z`78Jda%ysM#wzLTtjc|D0kKV0R5k?&Plr-eGWRVn+MMpErBZXB92iMs~)ia2Uegoq>XA|zxUp1{XlWt33QwH*Seq0bcyEA$s z>an9^a!Tp^nGY_fjnN=4Em~?QE`!^pzxD|GBymz0Jc#rKNHGh5>Zwn-2@D z3aYIfPzVOWyhHjQ0Zf6nBh*|$qqZnwq|^;U1a!^9PjbezoT!KH+LISHeZEZHWL35-dc*sNpZqIVc@mk{lbq_3V@Iu7gDN?M5+j zM6YWSQTJ2P;?uA%`&w$%dAmJvJZhA&Ex9@`LqV*q_vxat{z)yNOWFtT9}LQn#@Z6E zNe$wIwdqHgP{P(TY@oHdgyCcNmEh&7`;n(aTIzEJt39jFxjn&JIVJDI`7GX?pUk}l zwIe&o2}S6efW+V8%I_;AXY8OmoZNWgvQc=b`~Lt%#zQS3c&OR2ZE`FF80UZRLIOc# zJY*e(hkX5i>b}vdH_(W5$G@qA;32HXzp8aF;5hTplF{TP(YCnwAO-&AtS?g#*vYvw zyjf3vk-f-4Oat2$`W8>@bcAoM-tS+hZ7*{hwUQj zLz^&*Zu*o+T|r?AY+l)U^_J&z*lORCsc~LOHOD0`Upn0DM4)-=l=;o0&x)e}Wu<1w zFBBYY-=TN2k5l=#+4Z<0Azf$|_WEnb&!biORXLu>R--Plw3N9Mt`41rBk*b)#!9wxCeB zGiJ7~am@H6=Ydwz)7t3!CaxFFc$vU`113wZ&BZ<#|FCR{+;y}vrAp+sez)`nb2UB1 zIjMV}FI{(hC^!d^VN=xo1mWOy{e#VUhEM*Lf3exUE{;xBcixx07GmJ5OGS6DGJMR}R9g|TJC}i;toJ*6PR#6I7xM>#3%oZT7{`9~3(x%Q zL9q;%LLT zG}zppdwhy}L+#i#xeR#9`+P28-g&sK{n_?qY#J7bcYDjQnT|jJ* zgwYoStET5&h+RPr%mY@@I)B;l1Mg7aCF80r(}cWl*_qh&8+jl3Dl`Z!-#J9}!e=Jj zI7anjC(XFpfK(g$gN*Z3p`7(5MtZ;0<&%M$T2r+lE_qaE@v~`|KXI;$%O0ZNH2=8! z;B;x1*M6>IeXJJmUm zY}3%|b~i2c4@x-K>Xa9gW1YOymeuYV-~A?ikE-I0DcI7CY?s ztg~hDx~g(X&vwZqgJc4T-}C5S^w18!w)^nqyzHai$o+&m;opOnHCA!&fX{Gs255cM ziT|!6LI}+zfdm8t`~XqM7mJeqClW@BK!ohQ2d+mq$rIu=L6@x7hxFHISI*mfW upo%