下面列出了io.netty.channel.pool.ChannelPoolHandler#io.netty.handler.ssl.SslProvider 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static SslContext getSslContext(){
ClassLoader classLoader = AlphaIntegrationWithSSLTest.class.getClassLoader();
SslContext sslContext = null;
try {
sslContext = GrpcSslContexts.forClient().sslProvider(SslProvider.OPENSSL)
.protocols("TLSv1.2","TLSv1.1")
.ciphers(Arrays.asList("ECDHE-RSA-AES128-GCM-SHA256",
"ECDHE-RSA-AES256-GCM-SHA384"))
.trustManager(new File(classLoader.getResource("ca.crt").getFile()))
.keyManager(new File(classLoader.getResource("client.crt").getFile()),
new File(classLoader.getResource("client.pem").getFile())).build();
} catch (SSLException e) {
e.printStackTrace();
}
return sslContext;
}
@Override
public SslContextBuilder createBuilderForServer() {
try {
ArrayList<X509Certificate> trustedCerts = getTrustedX509Certificates();
SslProvider sslProvider = chooseSslProvider();
LOG.debug("Using SslProvider of type {}", sslProvider.name());
SslContextBuilder builder = newBuilderForServer()
.ciphers(getCiphers(), getCiphersFilter())
.sessionTimeout(serverSslConfig.getSessionTimeout())
.sslProvider(sslProvider);
if (serverSslConfig.getClientAuth() != null && trustedCerts != null && !trustedCerts.isEmpty()) {
builder = builder
.trustManager(trustedCerts.toArray(new X509Certificate[0]))
.clientAuth(serverSslConfig.getClientAuth());
}
return builder;
}
catch (Exception e) {
throw new RuntimeException("Error configuring SslContext!", e);
}
}
/**
* init SslContext for p2p connection
*
* @param caCrt
* @param nodeCrt
* @param nodeKey
* @return
* @throws IOException
*/
public SslContext initSslContextForServer(
org.springframework.core.io.Resource caCrt,
org.springframework.core.io.Resource nodeCrt,
org.springframework.core.io.Resource nodeKey)
throws IOException {
SslContext sslCtx =
SslContextBuilder.forServer(nodeCrt.getInputStream(), nodeKey.getInputStream())
.trustManager(caCrt.getInputStream())
.sslProvider(SslProvider.JDK)
.clientAuth(ClientAuth.REQUIRE)
.build();
return sslCtx;
}
private static SslContext buildSslContext(AlphaClusterConfig clusterConfig) throws SSLException {
SslContextBuilder builder = GrpcSslContexts.forClient();
// openssl must be used because some older JDk does not support cipher suites required by http2,
// and the performance of JDK ssl is pretty low compared to openssl.
builder.sslProvider(SslProvider.OPENSSL);
Properties prop = new Properties();
try {
prop.load(LoadBalancedClusterMessageSender.class.getClassLoader().getResourceAsStream("ssl.properties"));
} catch (IOException e) {
throw new IllegalArgumentException("Unable to read ssl.properties.", e);
}
builder.protocols(prop.getProperty("protocols").split(","));
builder.ciphers(Arrays.asList(prop.getProperty("ciphers").split(",")));
builder.trustManager(new File(clusterConfig.getCertChain()));
if (clusterConfig.isEnableMutualAuth()) {
builder.keyManager(new File(clusterConfig.getCert()), new File(clusterConfig.getKey()));
}
return builder.build();
}
private SslContextBuilder getSslContextBuilder(GrpcServerConfig config) {
Properties prop = new Properties();
ClassLoader classLoader = getClass().getClassLoader();
try {
prop.load(classLoader.getResourceAsStream("ssl.properties"));
} catch (IOException e) {
throw new IllegalStateException("Unable to read ssl.properties.", e);
}
InputStream cert = getInputStream(classLoader, config.getCert(), "Server Cert");
InputStream key = getInputStream(classLoader, config.getKey(), "Server Key");
SslContextBuilder sslClientContextBuilder = SslContextBuilder.forServer(cert, key)
.protocols(prop.getProperty("protocols"))
.ciphers(Arrays.asList(prop.getProperty("ciphers").split(",")));
if (config.isMutualAuth()) {
InputStream clientCert = getInputStream(classLoader, config.getClientCert(), "Client Cert");
sslClientContextBuilder.trustManager(clientCert);
sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);
}
return GrpcSslContexts.configure(sslClientContextBuilder,
SslProvider.OPENSSL);
}
private static SslContext buildSslContext() {
try {
SslContextBuilder sslContextBuilder = SslContextBuilder.forClient()
.sslProvider(SslProvider.JDK)
.sessionCacheSize(0)
.sessionTimeout(0);
String[] protocols = new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" };
sslContextBuilder.protocols(protocols);
SslContext sslContext = sslContextBuilder.build();
return sslContext;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Test
public void usingProxy_noSchemeGiven_defaultsToHttp() {
ProxyConfiguration proxyConfiguration = ProxyConfiguration.builder()
.host("localhost")
.port(mockProxy.port())
.build();
channelPoolMap = AwaitCloseChannelPoolMap.builder()
.proxyConfiguration(proxyConfiguration)
.sdkChannelOptions(new SdkChannelOptions())
.sdkEventLoopGroup(SdkEventLoopGroup.builder().build())
.configuration(new NettyConfiguration(GLOBAL_HTTP_DEFAULTS))
.protocol(Protocol.HTTP1_1)
.maxStreams(100)
.sslProvider(SslProvider.OPENSSL)
.build();
SimpleChannelPoolAwareChannelPool simpleChannelPoolAwareChannelPool = channelPoolMap.newPool(
URI.create("https://some-awesome-service:443"));
simpleChannelPoolAwareChannelPool.acquire().awaitUninterruptibly();
String requests = recorder.requests().toString();
assertThat(requests).contains("CONNECT some-awesome-service:443");
}
public ChannelPipelineInitializer(Protocol protocol,
SslContext sslCtx,
SslProvider sslProvider,
long clientMaxStreams,
int clientInitialWindowSize,
Duration healthCheckPingPeriod,
AtomicReference<ChannelPool> channelPoolRef,
NettyConfiguration configuration,
URI poolKey) {
this.protocol = protocol;
this.sslCtx = sslCtx;
this.sslProvider = sslProvider;
this.clientMaxStreams = clientMaxStreams;
this.clientInitialWindowSize = clientInitialWindowSize;
this.healthCheckPingPeriod = healthCheckPingPeriod;
this.channelPoolRef = channelPoolRef;
this.configuration = configuration;
this.poolKey = poolKey;
}
@Parameters(name = "{index}: serverEngine = {0}, clientEngine = {1}")
public static Collection<Object[]> data() throws Exception {
List<SslContext> serverContexts = new ArrayList<SslContext>();
serverContexts.add(SslContextBuilder.forServer(CERT_FILE, KEY_FILE).sslProvider(SslProvider.JDK).build());
List<SslContext> clientContexts = new ArrayList<SslContext>();
clientContexts.add(SslContextBuilder.forClient().sslProvider(SslProvider.JDK).trustManager(CERT_FILE).build());
boolean hasOpenSsl = OpenSsl.isAvailable();
if (hasOpenSsl) {
serverContexts.add(SslContextBuilder.forServer(CERT_FILE, KEY_FILE)
.sslProvider(SslProvider.OPENSSL).build());
clientContexts.add(SslContextBuilder.forClient().sslProvider(SslProvider.OPENSSL)
.trustManager(CERT_FILE).build());
} else {
logger.warn("OpenSSL is unavailable and thus will not be tested.", OpenSsl.unavailabilityCause());
}
List<Object[]> params = new ArrayList<Object[]>();
for (SslContext sc: serverContexts) {
for (SslContext cc: clientContexts) {
params.add(new Object[] { sc, cc });
}
}
return params;
}
private static void testClientOcspNotEnabled(SslProvider sslProvider) throws Exception {
SslContext context = SslContextBuilder.forClient()
.sslProvider(sslProvider)
.build();
try {
SslHandler sslHandler = context.newHandler(ByteBufAllocator.DEFAULT);
ReferenceCountedOpenSslEngine engine = (ReferenceCountedOpenSslEngine) sslHandler.engine();
try {
engine.getOcspResponse();
} finally {
engine.release();
}
} finally {
ReferenceCountUtil.release(context);
}
}
/**
* Returns OpenSSL if available, otherwise returns the JDK provider.
*/
private static SslProvider defaultSslProvider() {
if (OpenSsl.isAvailable()) {
logger.log(Level.FINE, "Selecting OPENSSL");
return SslProvider.OPENSSL;
}
Provider provider = findJdkProvider();
if (provider != null) {
logger.log(Level.FINE, "Selecting JDK with provider {0}", provider);
return SslProvider.JDK;
}
logger.log(Level.INFO, "Java 9 ALPN API unavailable (this may be normal)");
logger.log(Level.INFO, "netty-tcnative unavailable (this may be normal)",
OpenSsl.unavailabilityCause());
logger.log(Level.INFO, "Conscrypt not found (this may be normal)",
ConscryptHolder.UNAVAILABILITY_CAUSE);
logger.log(Level.INFO, "Jetty ALPN unavailable (this may be normal)",
JettyTlsUtil.getJettyAlpnUnavailabilityCause());
throw new IllegalStateException(
"Could not find TLS ALPN provider; "
+ "no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN available");
}
@Setup(Level.Trial)
public void setup() throws Exception {
mockServer = new MockH2Server(false);
mockServer.start();
SslProvider sslProvider = getSslProvider(sslProviderValue);
sdkHttpClient = NettyNioAsyncHttpClient.builder()
.sslProvider(sslProvider)
.buildWithDefaults(trustAllTlsAttributeMapBuilder()
.put(PROTOCOL, Protocol.HTTP2)
.build());
client = ProtocolRestJsonAsyncClient.builder()
.endpointOverride(mockServer.getHttpsUri())
.httpClient(sdkHttpClient)
.build();
// Making sure the request actually succeeds
client.allTypes().join();
}
private static SslContext createSSLContext(boolean useClientCA, String sslKeyStoreType, String sslKeyFilePath, String sslManagerPwd, String sslStorePwd) {
try {
InputStream ksInputStream = new FileInputStream(sslKeyFilePath);
KeyStore ks = KeyStore.getInstance(sslKeyStoreType);
ks.load(ksInputStream, sslStorePwd.toCharArray());
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, sslManagerPwd.toCharArray());
SslContextBuilder contextBuilder = SslContextBuilder.forServer(kmf);
// whether need client CA(two-way authentication)
if (useClientCA) {
contextBuilder.clientAuth(ClientAuth.REQUIRE);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
contextBuilder.trustManager(tmf);
}
return contextBuilder.sslProvider(SslProvider.valueOf("JDK")).build();
} catch (Exception ex) {
log.error("Create ssl context failure.cause={}", ex);
return null;
}
}
private SslContext getSslContext() {
SslContext sslCtx = null;
final SslProvider provider = OpenSsl.isAlpnSupported() ? SslProvider.OPENSSL : SslProvider.JDK;
try {
sslCtx = SslContextBuilder.forClient()
.sslProvider(provider)
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.applicationProtocolConfig(new ApplicationProtocolConfig(
Protocol.ALPN,
SelectorFailureBehavior.NO_ADVERTISE,
SelectedListenerFailureBehavior.ACCEPT,
ApplicationProtocolNames.HTTP_2))
.build();
} catch(SSLException exception) {
return null;
}
return sslCtx;
}
private static KeyManagerFactory loadKeyManagerFactory(TransportOptions options, SslProvider provider) throws Exception {
if (options.getKeyStoreLocation() == null) {
return null;
}
final KeyManagerFactory factory;
if (provider.equals(SslProvider.JDK)) {
factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
} else {
factory = new OpenSslX509KeyManagerFactory();
}
String storeLocation = options.getKeyStoreLocation();
String storePassword = options.getKeyStorePassword();
String storeType = options.getKeyStoreType();
LOG.trace("Attempt to load KeyStore from location {} of type {}", storeLocation, storeType);
KeyStore keyStore = loadStore(storeLocation, storePassword, storeType);
factory.init(keyStore, storePassword != null ? storePassword.toCharArray() : null);
return factory;
}
@Substitute
static SslContext newClientContextInternal(
SslProvider provider,
Provider sslContextProvider,
X509Certificate[] trustCert, TrustManagerFactory trustManagerFactory,
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols,
long sessionCacheSize, long sessionTimeout, boolean enableOcsp, String keyStoreType) throws SSLException {
if (enableOcsp) {
throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider);
}
return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslClientContext(sslContextProvider,
trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize,
sessionTimeout, keyStoreType);
}
@Test
void buildTlsConfig_shouldUseCorrectTlsConfigValues() {
TlsConfig tlsConfig =
XConfig.buildTlsConfig(
ConfigFactory.parseResources(XConfig.class, "xrpc.conf").getConfig("tls"));
List<String> defaultSupportedProtocols = tlsConfig.getCiphers();
assertEquals(6, defaultSupportedProtocols.size());
for (String protocol : defaultSupportedProtocols) {
assertTrue(SUPPORTED_PROTOCOLS.contains(protocol));
}
ApplicationProtocolConfig applicationProtocolConfig = tlsConfig.getAlpnConfig();
assertEquals(
SUPPORTED_PROTOCOLS_IN_PREFERENCE_ORDER, applicationProtocolConfig.supportedProtocols());
assertEquals(NO_ADVERTISE, applicationProtocolConfig.selectorFailureBehavior());
assertEquals(ACCEPT, applicationProtocolConfig.selectedListenerFailureBehavior());
assertEquals(ALPN, applicationProtocolConfig.protocol());
assertTrue(tlsConfig.isLogInsecureConfig());
assertTrue(tlsConfig.isUseSsl());
assertEquals(ClientAuth.OPTIONAL, tlsConfig.getClientAuth());
assertFalse(tlsConfig.isEnableOcsp());
assertEquals(0, tlsConfig.getSessionTimeout());
assertEquals(0, tlsConfig.getSessionCacheSize());
assertEquals(SslProvider.OPENSSL, tlsConfig.getSslProvider());
}
/** {@link Provides} the {@link SslClientInitializer} used for the {@link EppProtocol}. */
@Provides
@EppProtocol
static SslClientInitializer<NioSocketChannel> provideSslClientInitializer(
SslProvider sslProvider,
@LocalSecrets Supplier<PrivateKey> privateKeySupplier,
@LocalSecrets Supplier<ImmutableList<X509Certificate>> certificatesSupplier) {
return SslClientInitializer
.createSslClientInitializerWithSystemTrustStoreAndClientAuthentication(
sslProvider,
channel -> channel.attr(REMOTE_ADDRESS_KEY).get(),
channel -> channel.attr(PROTOCOL_KEY).get().port(),
privateKeySupplier,
certificatesSupplier);
}
public SslServerInitializer(
boolean requireClientCert,
boolean validateClientCert,
SslProvider sslProvider,
Supplier<PrivateKey> privateKeySupplier,
Supplier<ImmutableList<X509Certificate>> certificatesSupplier) {
logger.atInfo().log("Server SSL Provider: %s", sslProvider);
checkArgument(
requireClientCert || !validateClientCert,
"Cannot validate client certificate if client certificate is not required.");
this.requireClientCert = requireClientCert;
this.validateClientCert = validateClientCert;
this.sslProvider = sslProvider;
this.privateKeySupplier = privateKeySupplier;
this.certificatesSupplier = certificatesSupplier;
this.supportedSslVersions =
sslProvider == SslProvider.OPENSSL
? ImmutableList.of("TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1")
// JDK support for TLS 1.3 won't be available until 2020-07-14 at the earliest.
// See: https://java.com/en/jre-jdk-cryptoroadmap.html
: ImmutableList.of("TLSv1.2", "TLSv1.1", "TLSv1");
}
SslContextBuilder getSslContextBuilder(X509Certificate[] clientCert, PrivateKey clientKey, SslProvider sslprovider) {
SslContextBuilder clientContextBuilder = GrpcSslContexts.configure(SslContextBuilder.forClient(), sslprovider);
if (clientKey != null && clientCert != null) {
clientContextBuilder = clientContextBuilder.keyManager(clientKey, clientCert);
} else {
logger.debug(format("Endpoint %s with no ssl context", url));
}
return clientContextBuilder;
}
@Test
public void channelConfigOptionCheck() throws SSLException {
targetUri = URI.create("https://some-awesome-service-1234.amazonaws.com:8080");
SslContext sslContext = SslContextBuilder.forClient()
.sslProvider(SslProvider.JDK)
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
.build();
AtomicReference<ChannelPool> channelPoolRef = new AtomicReference<>();
NettyConfiguration nettyConfiguration = new NettyConfiguration(GLOBAL_HTTP_DEFAULTS);
pipelineInitializer = new ChannelPipelineInitializer(Protocol.HTTP1_1,
sslContext,
SslProvider.JDK,
100,
1024,
Duration.ZERO,
channelPoolRef,
nettyConfiguration,
targetUri);
Channel channel = new EmbeddedChannel();
pipelineInitializer.channelCreated(channel);
assertThat(channel.config().getOption(ChannelOption.ALLOCATOR), is(UnpooledByteBufAllocator.DEFAULT));
}
public static SslContext build(File serverCert, File serverKey,
String serverPass, SslProvider sslProvider) throws SSLException {
if (serverPass == null || serverPass.isEmpty()) {
return SslContextBuilder.forServer(serverCert, serverKey)
.sslProvider(sslProvider)
.build();
} else {
return SslContextBuilder.forServer(serverCert, serverKey, serverPass)
.sslProvider(sslProvider)
.build();
}
}
/** {@link Provides} the {@link SslProvider} used by instances of {@link SslClientInitializer} */
@Provides
@Singleton
static SslProvider provideSslProvider() {
// Prefer OpenSSL.
return OpenSsl.isAvailable() ? SslProvider.OPENSSL : SslProvider.JDK;
}
@Override
public void start() throws ServerException {
try {
if (sslContextBuilder != null) {
nettyServerBuilder = nettyServerBuilder.sslContext(GrpcSslContexts.configure(sslContextBuilder, SslProvider.OPENSSL)
.build());
}
server = nettyServerBuilder.build();
server.start();
} catch (IOException e) {
throw new GRPCServerException(e.getMessage(), e);
}
}
@Override
protected HttpServer customizeServerOptions(HttpServer server) {
try {
SslContext ctx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
.sslProvider(SslProvider.JDK)
.build();
return server.secure(ssl -> ssl.sslContext(ctx));
}
catch (SSLException e) {
throw new RuntimeException(e);
}
}
/**
* Create a {@link ClientHttpConnector} for the given {@link ClientOptions}.
* @param options must not be {@literal null}
* @return a new {@link ClientHttpConnector}.
*/
public static ClientHttpConnector create(ClientOptions options) {
HttpClient httpClient = HttpClient.create();
if (usingCustomCerts(options)) {
TrustManagerFactory trustManagerFactory = sslCertificateUtils
.createTrustManagerFactory(options.getCaCertFiles());
httpClient = httpClient.secure((sslContextSpec) -> sslContextSpec.sslContext(
SslContextBuilder.forClient().sslProvider(SslProvider.JDK).trustManager(trustManagerFactory)));
}
else {
httpClient = httpClient.secure((sslContextSpec) -> {
try {
sslContextSpec.sslContext(new JdkSslContext(SSLContext.getDefault(), true, null,
IdentityCipherSuiteFilter.INSTANCE, null, ClientAuth.REQUIRE, null, false));
}
catch (NoSuchAlgorithmException ex) {
logger.error("Error configuring HTTP connections", ex);
throw new RuntimeException("Error configuring HTTP connections", ex);
}
});
}
if (options.getConnectionTimeout() != null) {
httpClient = httpClient
.tcpConfiguration((tcpClient) -> tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,
Math.toIntExact(options.getConnectionTimeout().toMillis())));
}
return new ReactorClientHttpConnector(httpClient);
}
private SslProvider getSslProvider() {
if (OpenSsl.isAvailable()) {
return SslProvider.OPENSSL_REFCNT;
} else {
return SslProvider.JDK;
}
}
private SslProvider getSslProvider() {
if (OpenSsl.isAvailable()) {
return SslProvider.OPENSSL_REFCNT;
} else {
return SslProvider.JDK;
}
}
public static SSLContext createContext() {
try {
JdkSslContext nettyContext = (JdkSslContext) SslContextBuilder
.forServer(getKeyManagerFactory())
.sslProvider(SslProvider.JDK)
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.build();
return nettyContext.context();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws Exception {
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContext.newServerContext(SslProvider.JDK, ssc.certificate(), ssc.privateKey());
} else {
sslCtx = null;
}
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new HttpStaticFileServerInitializer(sslCtx));
Channel ch = b.bind(PORT).sync().channel();
System.err.println("Open your web browser and navigate to " +
(SSL? "https" : "http") + "://127.0.0.1:" + PORT + '/');
ch.closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}