diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SniX509ExtendedKeyManager.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SniX509ExtendedKeyManager.java index d4afc6409e5..b1cdfbd29ee 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SniX509ExtendedKeyManager.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SniX509ExtendedKeyManager.java @@ -50,6 +50,10 @@ public class SniX509ExtendedKeyManager extends X509ExtendedKeyManager private final X509ExtendedKeyManager _delegate; private final SslContextFactory.Server _sslContextFactory; + /** + * @deprecated not supported, you must have a {@link SslContextFactory.Server} for this to work. + */ + @Deprecated public SniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) { this(keyManager, null); @@ -58,7 +62,7 @@ public class SniX509ExtendedKeyManager extends X509ExtendedKeyManager public SniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager, SslContextFactory.Server sslContextFactory) { _delegate = keyManager; - _sslContextFactory = sslContextFactory; + _sslContextFactory = Objects.requireNonNull(sslContextFactory, "SslContextFactory.Server must be provided"); } @Override 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 f88ccfe06a6..f297f8d9f15 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 @@ -1159,9 +1159,13 @@ public abstract class SslContextFactory extends AbstractLifeCycle implements Dum return managers; } + /** + * @deprecated use {@link SslContextFactory.Server#newSniX509ExtendedKeyManager(X509ExtendedKeyManager)} instead + */ + @Deprecated protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) { - return new SniX509ExtendedKeyManager(keyManager); + throw new UnsupportedOperationException("X509ExtendedKeyManager only supported on Server"); } 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 04f84a5b264..2445a761831 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 @@ -19,11 +19,17 @@ package org.eclipse.jetty.util.ssl; import java.security.cert.X509Certificate; +import javax.net.ssl.KeyManager; +import javax.net.ssl.X509ExtendedKeyManager; +import org.eclipse.jetty.util.resource.Resource; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; public class X509Test { @@ -123,4 +129,56 @@ public class X509Test assertThat("Normal X509", X509.isCertSign(bogusX509), is(false)); } + + private X509ExtendedKeyManager getX509ExtendedKeyManager(SslContextFactory sslContextFactory) throws Exception + { + Resource keystoreResource = Resource.newSystemResource("keystore"); + Resource truststoreResource = Resource.newSystemResource("keystore"); + sslContextFactory.setKeyStoreResource(keystoreResource); + sslContextFactory.setTrustStoreResource(truststoreResource); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.setKeyManagerPassword("keypwd"); + sslContextFactory.setTrustStorePassword("storepwd"); + sslContextFactory.start(); + + KeyManager[] keyManagers = sslContextFactory.getKeyManagers(sslContextFactory.getKeyStore()); + X509ExtendedKeyManager x509ExtendedKeyManager = null; + + for (KeyManager keyManager : keyManagers) + { + if (keyManager instanceof X509ExtendedKeyManager) + { + x509ExtendedKeyManager = (X509ExtendedKeyManager)keyManager; + break; + } + } + assertThat("Found X509ExtendedKeyManager", x509ExtendedKeyManager, is(notNullValue())); + return x509ExtendedKeyManager; + } + + @Test + 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")); + } + + @Test + 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")); + } + + @Test + public void testSniX509ExtendedKeyManager_ServerClass() throws Exception + { + SslContextFactory serverSsl = new SslContextFactory.Server(); + X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(serverSsl); + serverSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager); + } }