Merged branch 'jetty-9.4.x' into 'jetty-10.0.x'.

This commit is contained in:
Simone Bordet 2020-05-04 13:00:15 +02:00
commit 99ecfca439
3 changed files with 53 additions and 14 deletions

View File

@ -300,6 +300,29 @@ public class SniSslConnectionFactoryTest
assertThat(response.getStatus(), is(400)); assertThat(response.getStatus(), is(400));
} }
@Test
public void testWrongSNIRejectedConnectionWithNonSNIKeystore() throws Exception
{
start(ssl ->
{
// Keystore has only one certificate, but we want to enforce SNI.
ssl.setKeyStorePath("src/test/resources/keystore.p12");
ssl.setSniRequired(true);
});
// Wrong SNI host.
assertThrows(SSLHandshakeException.class, () -> getResponse("wrong.com", "wrong.com", null));
// No SNI host.
assertThrows(SSLHandshakeException.class, () -> getResponse(null, "wrong.com", null));
// Good SNI host.
HttpTester.Response response = HttpTester.parseResponse(getResponse("localhost", "localhost", null));
assertNotNull(response);
assertThat(response.getStatus(), is(200));
}
@Test @Test
public void testSameConnectionRequestsForManyDomains() throws Exception public void testSameConnectionRequestsForManyDomains() throws Exception
{ {

View File

@ -141,9 +141,9 @@ public abstract class SslContextFactory extends AbstractLifeCycle implements Dum
private final Set<String> _includeProtocols = new LinkedHashSet<>(); private final Set<String> _includeProtocols = new LinkedHashSet<>();
private final Set<String> _excludeCipherSuites = new LinkedHashSet<>(); private final Set<String> _excludeCipherSuites = new LinkedHashSet<>();
private final List<String> _includeCipherSuites = new ArrayList<>(); private final List<String> _includeCipherSuites = new ArrayList<>();
protected final Map<String, X509> _aliasX509 = new HashMap<>(); private final Map<String, X509> _aliasX509 = new HashMap<>();
protected final Map<String, X509> _certHosts = new HashMap<>(); private final Map<String, X509> _certHosts = new HashMap<>();
protected final Map<String, X509> _certWilds = new HashMap<>(); private final Map<String, X509> _certWilds = new HashMap<>();
private String[] _selectedProtocols; private String[] _selectedProtocols;
private boolean _useCipherSuitesOrder = true; private boolean _useCipherSuitesOrder = true;
private Comparator<String> _cipherComparator; private Comparator<String> _cipherComparator;
@ -453,6 +453,21 @@ public abstract class SslContextFactory extends AbstractLifeCycle implements Dum
_certWilds.clear(); _certWilds.clear();
} }
Map<String, X509> aliasCerts()
{
return _aliasX509;
}
Map<String, X509> hostCerts()
{
return _certHosts;
}
Map<String, X509> wildCerts()
{
return _certWilds;
}
@ManagedAttribute(value = "The selected TLS protocol versions", readonly = true) @ManagedAttribute(value = "The selected TLS protocol versions", readonly = true)
public String[] getSelectedProtocols() public String[] getSelectedProtocols()
{ {
@ -2157,7 +2172,7 @@ public abstract class SslContextFactory extends AbstractLifeCycle implements Dum
boolean hasSniX509ExtendedKeyManager = false; boolean hasSniX509ExtendedKeyManager = false;
// Is SNI needed to select a certificate? // Is SNI needed to select a certificate?
if (!_certWilds.isEmpty() || _certHosts.size() > 1 || (_certHosts.size() == 1 && _aliasX509.size() > 1)) if (isSniRequired() || !wildCerts().isEmpty() || hostCerts().size() > 1 || (hostCerts().size() == 1 && aliasCerts().size() > 1))
{ {
for (int idx = 0; idx < managers.length; idx++) for (int idx = 0; idx < managers.length; idx++)
{ {
@ -2201,7 +2216,7 @@ public abstract class SslContextFactory extends AbstractLifeCycle implements Dum
if (sniHost == null) if (sniHost == null)
{ {
// No SNI, so reject or delegate. // No SNI, so reject or delegate.
return _sniRequired ? null : SniX509ExtendedKeyManager.SniSelector.DELEGATE; return isSniRequired() ? null : SniX509ExtendedKeyManager.SniSelector.DELEGATE;
} }
else else
{ {

View File

@ -80,8 +80,7 @@ public class X509
String cn = list.get(1).toString(); String cn = list.get(1).toString();
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("Certificate SAN alias={} CN={} in {}", alias, cn, this); LOG.debug("Certificate SAN alias={} CN={} in {}", alias, cn, this);
if (cn != null) addName(cn);
addName(cn);
} }
} }
} }
@ -95,19 +94,21 @@ public class X509
String cn = rdn.getValue().toString(); String cn = rdn.getValue().toString();
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("Certificate CN alias={} CN={} in {}", alias, cn, this); LOG.debug("Certificate CN alias={} CN={} in {}", alias, cn, this);
if (cn != null && cn.contains(".") && !cn.contains(" ")) addName(cn);
addName(cn);
} }
} }
} }
protected void addName(String cn) protected void addName(String cn)
{ {
cn = StringUtil.asciiToLowerCase(cn); if (cn != null)
if (cn.startsWith("*.")) {
_wilds.add(cn.substring(2)); cn = StringUtil.asciiToLowerCase(cn);
else if (cn.startsWith("*."))
_hosts.add(cn); _wilds.add(cn.substring(2));
else
_hosts.add(cn);
}
} }
public String getAlias() public String getAlias()