diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index c81236f9b26f..f141b846bec8 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -1249,10 +1249,17 @@ protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception // Is SNI needed to select a certificate? if (!_certWilds.isEmpty() || _certHosts.size() > 1 || (_certHosts.size() == 1 && _aliasX509.size() > 1)) { - for (int idx = 0; idx < managers.length; idx++) + if (this instanceof SslContextFactory.Server) { - if (managers[idx] instanceof X509ExtendedKeyManager) - managers[idx] = newSniX509ExtendedKeyManager((X509ExtendedKeyManager)managers[idx]); + for (int idx = 0; idx < managers.length; idx++) + { + if (managers[idx] instanceof X509ExtendedKeyManager) + managers[idx] = newSniX509ExtendedKeyManager((X509ExtendedKeyManager)managers[idx]); + } + } + else + { + LOG.warn("Unable to support SNI on {} (expecting {})", this.getClass().getName(), SslContextFactory.Server.class.getName()); } } } @@ -1270,7 +1277,7 @@ protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception @Deprecated protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) { - throw new UnsupportedOperationException("X509ExtendedKeyManager only supported on Server"); + throw new UnsupportedOperationException("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName()); } protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection crls) throws Exception diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java index 2445a7618316..a893be2d9ebe 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java @@ -18,10 +18,13 @@ package org.eclipse.jetty.util.ssl; +import java.nio.file.Path; import java.security.cert.X509Certificate; import javax.net.ssl.KeyManager; import javax.net.ssl.X509ExtendedKeyManager; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; import org.junit.jupiter.api.Test; @@ -161,8 +164,19 @@ public void testSniX509ExtendedKeyManager_BaseClass() throws Exception { SslContextFactory baseSsl = new SslContextFactory(); X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(baseSsl); - UnsupportedOperationException npe = assertThrows(UnsupportedOperationException.class, () -> baseSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); - assertThat("UnsupportedOperationException.message", npe.getMessage(), containsString("X509ExtendedKeyManager only supported on Server")); + UnsupportedOperationException ex = assertThrows(UnsupportedOperationException.class, () -> baseSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); + assertThat("UnsupportedOperationException.message", ex.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); + } + + @Test + public void testSniX509ExtendedKeyManager_BaseClass_Start() throws Exception + { + SslContextFactory baseSsl = new SslContextFactory(); + Path keystorePath = MavenTestingUtils.getTestResourcePathFile("keystore_sni.p12"); + baseSsl.setKeyStoreResource(new PathResource(keystorePath)); + baseSsl.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + baseSsl.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + baseSsl.start(); // should not throw an exception } @Test @@ -170,8 +184,8 @@ public void testSniX509ExtendedKeyManager_ClientClass() throws Exception { SslContextFactory clientSsl = new SslContextFactory.Client(); X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(clientSsl); - UnsupportedOperationException re = assertThrows(UnsupportedOperationException.class, () -> clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); - assertThat("UnsupportedOperationException.message", re.getMessage(), containsString("X509ExtendedKeyManager only supported on Server")); + UnsupportedOperationException ex = assertThrows(UnsupportedOperationException.class, () -> clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); + assertThat("SNI X509 ExtendedKeyManager is unsupported in Client mode", ex.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); } @Test diff --git a/jetty-util/src/test/resources/keystore_sni.p12 b/jetty-util/src/test/resources/keystore_sni.p12 new file mode 100644 index 000000000000..fab22bd8eb80 Binary files /dev/null and b/jetty-util/src/test/resources/keystore_sni.p12 differ