Skip to content

Commit be14c30

Browse files
committed
Merged branch 'jetty-12.0.x' into 'jetty-12.1.x'.
Signed-off-by: Simone Bordet <[email protected]>
2 parents 3d68e2b + 74d7a74 commit be14c30

File tree

4 files changed

+53
-19
lines changed

4 files changed

+53
-19
lines changed

jetty-core/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class ConscryptHTTP2ServerTest
5656
Security.addProvider(new OpenSSLProvider());
5757
}
5858

59+
private final HttpConfiguration httpsConfig = new HttpConfiguration();
5960
private final Server server = new Server();
6061

6162
private SslContextFactory.Server newServerSslContextFactory()
@@ -90,9 +91,7 @@ private void configureSslContextFactory(SslContextFactory sslContextFactory)
9091
@BeforeEach
9192
public void startServer() throws Exception
9293
{
93-
HttpConfiguration httpsConfig = new HttpConfiguration();
9494
httpsConfig.setSecureScheme("https");
95-
9695
httpsConfig.setSendXPoweredBy(true);
9796
httpsConfig.setSendServerVersion(true);
9897
httpsConfig.addCustomizer(new SecureRequestCustomizer());
@@ -140,4 +139,12 @@ public void testSimpleRequest() throws Exception
140139
assertEquals(200, contentResponse.getStatus());
141140
}
142141
}
142+
143+
@Test
144+
public void testSNIRequired() throws Exception
145+
{
146+
// The KeyStore contains 1 certificate with two DNS names.
147+
httpsConfig.getCustomizer(SecureRequestCustomizer.class).setSniRequired(true);
148+
testSimpleRequest();
149+
}
143150
}
Binary file not shown.

jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
import java.security.cert.X509Certificate;
1818
import java.util.Set;
1919
import java.util.concurrent.TimeUnit;
20+
import javax.net.ssl.ExtendedSSLSession;
21+
import javax.net.ssl.SNIHostName;
22+
import javax.net.ssl.SNIServerName;
2023
import javax.net.ssl.SSLContext;
2124
import javax.net.ssl.SSLSession;
2225

@@ -213,7 +216,7 @@ protected void checkSni(Request request, SSLSession session)
213216
{
214217
if (isSniRequired() || isSniHostCheck())
215218
{
216-
String sniHost = (String)session.getValue(SslContextFactory.Server.SNI_HOST);
219+
String sniHost = retrieveSni(request, session);
217220

218221
X509 x509 = getX509(session);
219222
if (x509 == null)
@@ -230,6 +233,28 @@ protected void checkSni(Request request, SSLSession session)
230233
}
231234
}
232235

236+
protected String retrieveSni(Request request, SSLSession session)
237+
{
238+
// Quick retrieval of the SNI from a SSLSession attribute put by SniX509ExtendedKeyManager.
239+
String sniHost = (String)session.getValue(SslContextFactory.Server.SNI_HOST);
240+
if (sniHost != null)
241+
return null;
242+
243+
// Some security providers (for example, Conscrypt) do not support
244+
// SSLSession attributes, so perform a more expensive SNI retrieval.
245+
if (session instanceof ExtendedSSLSession extended)
246+
{
247+
for (SNIServerName serverName : extended.getRequestedServerNames())
248+
{
249+
if (serverName instanceof SNIHostName hostName)
250+
return hostName.getAsciiName();
251+
}
252+
}
253+
254+
// Nothing more we can do.
255+
return null;
256+
}
257+
233258
private X509 getX509(SSLSession session)
234259
{
235260
X509 x509 = (X509)session.getValue(X509_ATTRIBUTE);

jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SniX509ExtendedKeyManager.java

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.Collection;
2222
import java.util.Collections;
2323
import java.util.LinkedHashMap;
24-
import java.util.List;
2524
import java.util.Map;
2625
import java.util.Objects;
2726
import java.util.function.UnaryOperator;
@@ -115,29 +114,32 @@ protected String chooseServerAlias(String keyType, Principal[] issuers, Collecti
115114
.forEach(alias -> aliasMap.put(getAliasMapper().apply(alias), alias));
116115

117116
String host = null;
118-
if (session instanceof ExtendedSSLSession)
117+
if (session instanceof ExtendedSSLSession extended)
119118
{
120-
List<SNIServerName> serverNames = ((ExtendedSSLSession)session).getRequestedServerNames();
121-
if (serverNames != null)
119+
for (SNIServerName serverName : extended.getRequestedServerNames())
122120
{
123-
host = serverNames.stream()
124-
.findAny()
125-
.filter(SNIHostName.class::isInstance)
126-
.map(SNIHostName.class::cast)
127-
.map(SNIHostName::getAsciiName)
128-
.orElse(null);
121+
if (serverName instanceof SNIHostName hostName)
122+
{
123+
host = hostName.getAsciiName();
124+
break;
125+
}
129126
}
130127
}
131128
if (host == null)
132129
{
133130
// Find our SNIMatcher. There should only be one and it always matches (always returns true
134131
// from AliasSNIMatcher.matches), but it will capture the SNI Host if one was presented.
135-
host = matchers == null ? null : matchers.stream()
136-
.filter(SslContextFactory.AliasSNIMatcher.class::isInstance)
137-
.map(SslContextFactory.AliasSNIMatcher.class::cast)
138-
.findFirst()
139-
.map(SslContextFactory.AliasSNIMatcher::getHost)
140-
.orElse(null);
132+
if (matchers != null)
133+
{
134+
for (SNIMatcher matcher : matchers)
135+
{
136+
if (matcher instanceof SslContextFactory.AliasSNIMatcher aliasMatcher)
137+
{
138+
host = aliasMatcher.getHost();
139+
break;
140+
}
141+
}
142+
}
141143
}
142144
if (session != null && host != null)
143145
session.putValue(SslContextFactory.Server.SNI_HOST, host);

0 commit comments

Comments
 (0)