Skip to content

Commit bb0c35d

Browse files
author
Stephane Landelle
committed
Have a way to configure SslEngine enabled Protocols and CipherSuites, close #740
1 parent bc2c983 commit bb0c35d

File tree

4 files changed

+74
-18
lines changed

4 files changed

+74
-18
lines changed

src/main/java/com/ning/http/client/AsyncHttpClientConfig.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ public class AsyncHttpClientConfig {
7979
protected boolean disableUrlEncodingForBoundRequests;
8080
protected int ioThreadMultiplier;
8181
protected TimeConverter timeConverter;
82+
protected String[] enabledProtocols;
83+
protected String[] enabledCipherSuites;
8284
protected AsyncHttpProviderConfig<?, ?> providerConfig;
8385

8486
protected AsyncHttpClientConfig() {
@@ -114,6 +116,8 @@ private AsyncHttpClientConfig(int connectTimeout,//
114116
boolean disableUrlEncodingForBoundedRequests, //
115117
int ioThreadMultiplier, //
116118
TimeConverter timeConverter,//
119+
String[] enabledProtocols,//
120+
String[] enabledCipherSuites,//
117121
AsyncHttpProviderConfig<?, ?> providerConfig) {
118122

119123
this.connectTimeout = connectTimeout;
@@ -146,6 +150,8 @@ private AsyncHttpClientConfig(int connectTimeout,//
146150
this.disableUrlEncodingForBoundRequests = disableUrlEncodingForBoundedRequests;
147151
this.ioThreadMultiplier = ioThreadMultiplier;
148152
this.timeConverter = timeConverter;
153+
this.enabledProtocols = enabledProtocols;
154+
this.enabledCipherSuites = enabledCipherSuites;
149155
this.providerConfig = providerConfig;
150156
}
151157

@@ -449,6 +455,20 @@ public boolean isAcceptAnyCertificate() {
449455
return acceptAnyCertificate;
450456
}
451457

458+
/**
459+
* since 1.9.0
460+
*/
461+
public String[] getEnabledProtocols() {
462+
return enabledProtocols;
463+
}
464+
465+
/**
466+
* since 1.9.0
467+
*/
468+
public String[] getEnabledCipherSuites() {
469+
return enabledCipherSuites;
470+
}
471+
452472
/**
453473
* Builder for an {@link AsyncHttpClient}
454474
*/
@@ -484,6 +504,8 @@ public static class Builder {
484504
private int maxRequestRetry = defaultMaxRequestRetry();
485505
private boolean disableUrlEncodingForBoundedRequests = defaultDisableUrlEncodingForBoundRequests();
486506
private int ioThreadMultiplier = defaultIoThreadMultiplier();
507+
private String[] enabledProtocols;
508+
private String[] enabledCipherSuites;
487509
private TimeConverter timeConverter;
488510
private AsyncHttpProviderConfig<?, ?> providerConfig;
489511

@@ -903,6 +925,16 @@ public Builder setAcceptAnyCertificate(boolean acceptAnyCertificate) {
903925
return this;
904926
}
905927

928+
public Builder setEnabledProtocols(String[] enabledProtocols) {
929+
this.enabledProtocols = enabledProtocols;
930+
return this;
931+
}
932+
933+
public Builder setEnabledCipherSuites(String[] enabledCipherSuites) {
934+
this.enabledCipherSuites = enabledCipherSuites;
935+
return this;
936+
}
937+
906938
/**
907939
* Create a config builder with values taken from the given prototype configuration.
908940
*
@@ -943,6 +975,8 @@ public Builder(AsyncHttpClientConfig prototype) {
943975
hostnameVerifier = prototype.getHostnameVerifier();
944976
strict302Handling = prototype.isStrict302Handling();
945977
timeConverter = prototype.timeConverter;
978+
enabledProtocols = prototype.enabledProtocols;
979+
enabledCipherSuites = prototype.enabledCipherSuites;
946980
acceptAnyCertificate = prototype.acceptAnyCertificate;
947981
}
948982

@@ -1006,6 +1040,8 @@ else if (hostnameVerifier == null)
10061040
disableUrlEncodingForBoundedRequests, //
10071041
ioThreadMultiplier, //
10081042
timeConverter,//
1043+
enabledProtocols, //
1044+
enabledCipherSuites, //
10091045
providerConfig);
10101046
}
10111047
}

src/main/java/com/ning/http/client/SSLEngineFactory.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
*/
1414
package com.ning.http.client;
1515

16+
import com.ning.http.util.SslUtils;
17+
18+
import javax.net.ssl.SSLContext;
1619
import javax.net.ssl.SSLEngine;
1720

1821
import java.security.GeneralSecurityException;
@@ -21,11 +24,40 @@
2124
* Factory that creates an {@link SSLEngine} to be used for a single SSL connection.
2225
*/
2326
public interface SSLEngineFactory {
27+
2428
/**
2529
* Creates new {@link SSLEngine}.
2630
*
2731
* @return new engine
2832
* @throws GeneralSecurityException if the SSLEngine cannot be created
2933
*/
30-
SSLEngine newSSLEngine() throws GeneralSecurityException;
34+
SSLEngine newSSLEngine(String peerHost, int peerPort) throws GeneralSecurityException;
35+
36+
public static class DefaultSSLEngineFactory implements SSLEngineFactory {
37+
38+
private final AsyncHttpClientConfig config;
39+
40+
public DefaultSSLEngineFactory(AsyncHttpClientConfig config) {
41+
this.config = config;
42+
}
43+
44+
@Override
45+
public SSLEngine newSSLEngine(String peerHost, int peerPort) throws GeneralSecurityException {
46+
SSLContext sslContext = config.getSSLContext();
47+
48+
if (sslContext == null)
49+
sslContext = SslUtils.getInstance().getSSLContext(config.isAcceptAnyCertificate());
50+
51+
SSLEngine sslEngine = sslContext.createSSLEngine(peerHost, peerPort);
52+
sslEngine.setUseClientMode(true);
53+
54+
if (config.getEnabledProtocols() != null)
55+
sslEngine.setEnabledProtocols(config.getEnabledProtocols());
56+
57+
if (config.getEnabledCipherSuites() != null)
58+
sslEngine.setEnabledCipherSuites(config.getEnabledCipherSuites());
59+
60+
return sslEngine;
61+
}
62+
}
3163
}

src/main/java/com/ning/http/client/providers/netty/channel/ChannelManager.java

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.ning.http.client.AsyncHttpClientConfig;
4242
import com.ning.http.client.ConnectionPoolPartitioning;
4343
import com.ning.http.client.ProxyServer;
44+
import com.ning.http.client.SSLEngineFactory;
4445
import com.ning.http.client.providers.netty.Callback;
4546
import com.ning.http.client.providers.netty.NettyAsyncHttpProviderConfig;
4647
import com.ning.http.client.providers.netty.channel.pool.ChannelPool;
@@ -54,9 +55,7 @@
5455
import com.ning.http.client.providers.netty.handler.WebSocketProtocol;
5556
import com.ning.http.client.providers.netty.request.NettyRequestSender;
5657
import com.ning.http.client.uri.Uri;
57-
import com.ning.http.util.SslUtils;
5858

59-
import javax.net.ssl.SSLContext;
6059
import javax.net.ssl.SSLEngine;
6160

6261
import java.io.IOException;
@@ -85,6 +84,7 @@ public class ChannelManager {
8584

8685
private final AsyncHttpClientConfig config;
8786
private final NettyAsyncHttpProviderConfig nettyConfig;
87+
private final SSLEngineFactory sslEngineFactory;
8888
private final ChannelPool channelPool;
8989
private final boolean maxTotalConnectionsEnabled;
9090
private final Semaphore freeChannels;
@@ -109,6 +109,7 @@ public ChannelManager(AsyncHttpClientConfig config, NettyAsyncHttpProviderConfig
109109
this.config = config;
110110
this.nettyConfig = nettyConfig;
111111
this.nettyTimer = nettyTimer;
112+
this.sslEngineFactory = nettyConfig.getSslEngineFactory() != null? nettyConfig.getSslEngineFactory() : new SSLEngineFactory.DefaultSSLEngineFactory(config);
112113

113114
ChannelPool channelPool = nettyConfig.getChannelPool();
114115
if (channelPool == null && config.isAllowPoolingConnections()) {
@@ -376,19 +377,7 @@ private HttpClientCodec newHttpClientCodec() {
376377
}
377378

378379
public SslHandler createSslHandler(String peerHost, int peerPort) throws GeneralSecurityException, IOException {
379-
SSLEngine sslEngine = null;
380-
if (nettyConfig.getSslEngineFactory() != null) {
381-
sslEngine = nettyConfig.getSslEngineFactory().newSSLEngine();
382-
383-
} else {
384-
SSLContext sslContext = config.getSSLContext();
385-
if (sslContext == null)
386-
sslContext = SslUtils.getInstance().getSSLContext(config.isAcceptAnyCertificate());
387-
388-
sslEngine = sslContext.createSSLEngine(peerHost, peerPort);
389-
sslEngine.setUseClientMode(true);
390-
}
391-
380+
SSLEngine sslEngine = sslEngineFactory.newSSLEngine(peerHost, peerPort);
392381
return handshakeTimeout > 0 ? new SslHandler(sslEngine, getDefaultBufferPool(), false, nettyTimer, handshakeTimeout)
393382
: new SslHandler(sslEngine);
394383
}

src/main/java/com/ning/http/util/SslUtils.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import javax.net.ssl.TrustManager;
2020
import javax.net.ssl.X509TrustManager;
2121

22-
import java.io.IOException;
2322
import java.security.GeneralSecurityException;
2423
import java.security.KeyManagementException;
2524
import java.security.NoSuchAlgorithmException;
@@ -62,7 +61,7 @@ public static SslUtils getInstance() {
6261
return SingletonHolder.instance;
6362
}
6463

65-
public SSLContext getSSLContext(boolean acceptAnyCertificate) throws GeneralSecurityException, IOException {
64+
public SSLContext getSSLContext(boolean acceptAnyCertificate) throws GeneralSecurityException {
6665
return acceptAnyCertificate ? looseTrustManagerSSLContext : SSLContext.getDefault();
6766
}
6867
}

0 commit comments

Comments
 (0)