package org.jboss.resteasy.plugins.server.netty;
import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.IdentityCipherSuiteFilter;
import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.ssl.SslContext;
import io.netty.util.DomainNameMapping;
import io.netty.util.DomainNameMappingBuilder;
import javax.net.ssl.SSLContext;
import java.util.Arrays;
/**
* TLS/SSL Server Name Indication configuration.
*
* @author Sebastian Ćaskawiec
* @see https://tools.ietf.org/html/rfc6066#page-6
*/
public class SniConfiguration
{
protected final DomainNameMappingBuilder<SslContext> mapping;
/**
* Constructs new {@link SniConfiguration}.
*
* @param defaultServerKeystore default keystore to be used when no SNI is specified by the client.
*/
public SniConfiguration(SSLContext defaultServerKeystore)
{
mapping = new DomainNameMappingBuilder<>(createContext(defaultServerKeystore));
}
/**
* Adds SNI mapping.
*
* @param sniHostName SNI Host Name from TLS Extensions.
* @param sslContext SSLContext to be associated with given SNI Host Name.
* @return <code>this</code> configuration.
*/
public SniConfiguration addSniMapping(String sniHostName, SSLContext sslContext)
{
mapping.add(sniHostName, createContext(sslContext));
return this;
}
protected DomainNameMapping<SslContext> buildMapping()
{
return mapping.build();
}
private SslContext createContext(SSLContext sslContext)
{
//Unfortunately we need to grap a list of available ciphers from the engine.
//If we won't, JdkSslContext will use common ciphers from DEFAULT and SUPPORTED, which gives us 5 out of ~50 available ciphers
//Of course, we don't need to any specific engine configuration here... just a list of ciphers
String[] ciphers = sslContext.createSSLEngine().getSupportedCipherSuites();
return new JdkSslContext(sslContext, false, Arrays.asList(ciphers), IdentityCipherSuiteFilter.INSTANCE, null,
ClientAuth.OPTIONAL);
}
}