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.IOException;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -37,8 +41,10 @@ import java.util.Set;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@ -309,13 +315,23 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
keyPassword = ssl.getKeyStorePassword().toCharArray();
}
keyManagerFactory.init(keyStore, keyPassword);
return keyManagerFactory.getKeyManagers();
return getConfigurableAliasKeyManagers(ssl, keyManagerFactory.getKeyManagers());
}
catch (Exception 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 {
if (getSslStoreProvider() != null) {
return getSslStoreProvider().getKeyStore();
@ -691,6 +707,57 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
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.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@ -446,6 +447,24 @@ public abstract class AbstractServletWebServerFactoryTests {
.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
public void serverHeaderIsDisabledByDefaultWhenUsingSsl() throws Exception {
AbstractServletWebServerFactory factory = getFactory();
@ -659,13 +678,25 @@ public abstract class AbstractServletWebServerFactoryTests {
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,
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.setClientAuth(clientAuth);
if (keyPassword != null) {
ssl.setKeyPassword(keyPassword);
}
if (keyAlias != null) {
ssl.setKeyAlias(keyAlias);
}
if (keyStore != null) {
ssl.setKeyStore(keyStore);
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