Merge branch '1.5.x'

pull/8601/head
Madhura Bhave 8 years ago
commit cb1096dc7f

@ -19,12 +19,16 @@ package org.springframework.boot.web.embedded.undertow;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -37,8 +41,10 @@ import java.util.Set;
import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.servlet.ServletContainerInitializer; import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -309,13 +315,23 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
keyPassword = ssl.getKeyStorePassword().toCharArray(); keyPassword = ssl.getKeyStorePassword().toCharArray();
} }
keyManagerFactory.init(keyStore, keyPassword); keyManagerFactory.init(keyStore, keyPassword);
return keyManagerFactory.getKeyManagers(); return getConfigurableAliasKeyManagers(ssl, keyManagerFactory.getKeyManagers());
} }
catch (Exception ex) { catch (Exception ex) {
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
} }
private KeyManager[] getConfigurableAliasKeyManagers(Ssl ssl, KeyManager[] keyManagers) {
for (int i = 0; i < keyManagers.length; i++) {
if (keyManagers[i] instanceof X509ExtendedKeyManager) {
keyManagers[i] = new ConfigurableAliasKeyManager((X509ExtendedKeyManager) keyManagers[i],
ssl.getKeyAlias());
}
}
return keyManagers;
}
private KeyStore getKeyStore() throws Exception { private KeyStore getKeyStore() throws Exception {
if (getSslStoreProvider() != null) { if (getSslStoreProvider() != null) {
return getSslStoreProvider().getKeyStore(); return getSslStoreProvider().getKeyStore();
@ -691,6 +707,57 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
initializer.onStartup(servletContext); initializer.onStartup(servletContext);
} }
} }
}
private static class ConfigurableAliasKeyManager extends X509ExtendedKeyManager {
private final X509ExtendedKeyManager sourceKeyManager;
private final String alias;
ConfigurableAliasKeyManager(X509ExtendedKeyManager keyManager, String alias) {
this.sourceKeyManager = keyManager;
this.alias = alias;
}
@Override
public String chooseEngineClientAlias(String[] strings, Principal[] principals, SSLEngine sslEngine) {
return this.sourceKeyManager.chooseEngineClientAlias(strings, principals, sslEngine);
}
@Override
public String chooseEngineServerAlias(String s, Principal[] principals, SSLEngine sslEngine) {
if (this.alias == null) {
return this.sourceKeyManager.chooseEngineServerAlias(s, principals, sslEngine);
}
return this.alias;
}
public String chooseClientAlias(String[] keyType, Principal[] issuers,
Socket socket) {
return this.sourceKeyManager.chooseClientAlias(keyType, issuers, socket);
}
public String chooseServerAlias(String keyType, Principal[] issuers,
Socket socket) {
return this.sourceKeyManager.chooseServerAlias(keyType, issuers, socket);
}
public X509Certificate[] getCertificateChain(String alias) {
return this.sourceKeyManager.getCertificateChain(alias);
}
public String[] getClientAliases(String keyType, Principal[] issuers) {
return this.sourceKeyManager.getClientAliases(keyType, issuers);
}
public PrivateKey getPrivateKey(String alias) {
return this.sourceKeyManager.getPrivateKey(alias);
}
public String[] getServerAliases(String keyType, Principal[] issuers) {
return this.sourceKeyManager.getServerAliases(keyType, issuers);
}
} }

@ -34,6 +34,7 @@ import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -446,6 +447,24 @@ public abstract class AbstractServletWebServerFactoryTests {
.contains("scheme=https"); .contains("scheme=https");
} }
@Test
public void sslKeyAlias() throws Exception {
AbstractEmbeddedServletContainerFactory factory = getFactory();
factory.setSsl(getSsl(null, "password", "test-alias", "src/test/resources/test.jks"));
this.container = factory.getEmbeddedServletContainer(
new ServletRegistrationBean(new ExampleServlet(true, false), "/hello"));
this.container.start();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
new SSLContextBuilder()
.loadTrustMaterial(null, new SerialNumberValidatingTrustSelfSignedStrategy("77e7c302")).build());
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
httpClient);
assertThat(getResponse(getLocalUrl("https", "/hello"), requestFactory))
.contains("scheme=https");
}
@Test @Test
public void serverHeaderIsDisabledByDefaultWhenUsingSsl() throws Exception { public void serverHeaderIsDisabledByDefaultWhenUsingSsl() throws Exception {
AbstractServletWebServerFactory factory = getFactory(); AbstractServletWebServerFactory factory = getFactory();
@ -659,13 +678,25 @@ public abstract class AbstractServletWebServerFactoryTests {
return getSsl(clientAuth, keyPassword, keyStore, null, null, null); return getSsl(clientAuth, keyPassword, keyStore, null, null, null);
} }
private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyAlias, String keyStore) {
return getSsl(clientAuth, keyPassword, keyAlias, keyStore, null, null, null);
}
private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyStore, private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyStore,
String trustStore, String[] supportedProtocols, String[] ciphers) { String trustStore, String[] supportedProtocols, String[] ciphers) {
return getSsl(clientAuth, keyPassword, null, keyStore, trustStore, supportedProtocols, ciphers);
}
private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyAlias, String keyStore,
String trustStore, String[] supportedProtocols, String[] ciphers) {
Ssl ssl = new Ssl(); Ssl ssl = new Ssl();
ssl.setClientAuth(clientAuth); ssl.setClientAuth(clientAuth);
if (keyPassword != null) { if (keyPassword != null) {
ssl.setKeyPassword(keyPassword); ssl.setKeyPassword(keyPassword);
} }
if (keyAlias != null) {
ssl.setKeyAlias(keyAlias);
}
if (keyStore != null) { if (keyStore != null) {
ssl.setKeyStore(keyStore); ssl.setKeyStore(keyStore);
ssl.setKeyStorePassword("secret"); ssl.setKeyStorePassword("secret");
@ -1255,4 +1286,25 @@ public abstract class AbstractServletWebServerFactoryTests {
} }
/**
* {@link TrustSelfSignedStrategy} that also validates certificate serial
* number.
*/
private static final class SerialNumberValidatingTrustSelfSignedStrategy extends TrustSelfSignedStrategy {
private final String serialNumber;
private SerialNumberValidatingTrustSelfSignedStrategy(String serialNumber) {
this.serialNumber = serialNumber;
}
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
String hexSerialNumber = chain[0].getSerialNumber().toString(16);
boolean isMatch = hexSerialNumber.equals(this.serialNumber);
return super.isTrusted(chain, authType) && isMatch;
}
}
} }

Loading…
Cancel
Save