Skip to content

Commit 3ae1313

Browse files
committed
enable SSL verification by default.
1 parent edfb89d commit 3ae1313

File tree

4 files changed

+457
-12
lines changed

4 files changed

+457
-12
lines changed

src/main/java/com/aliyun/oss/ClientConfiguration.java

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
import java.util.Date;
2929
import java.util.concurrent.locks.Lock;
3030
import java.util.concurrent.locks.ReentrantLock;
31+
import javax.net.ssl.HostnameVerifier;
32+
import javax.net.ssl.KeyManager;
33+
import javax.net.ssl.X509TrustManager;
34+
import java.security.SecureRandom;
3135

3236
import com.aliyun.oss.common.auth.RequestSigner;
3337
import com.aliyun.oss.common.comm.IdleConnectionReaper;
@@ -107,6 +111,12 @@ public class ClientConfiguration {
107111

108112
private boolean redirectEnable = true;
109113

114+
private boolean verifySSLEnable = true;
115+
private KeyManager[] keyManagers = null;
116+
private X509TrustManager[] x509TrustManagers = null;
117+
private SecureRandom secureRandom = null;
118+
private HostnameVerifier hostnameVerifier = null;
119+
110120
public ClientConfiguration() {
111121
super();
112122
AppendDefaultExcludeList(this.cnameExcludeList);
@@ -726,7 +736,6 @@ public void setRetryStrategy(RetryStrategy retryStrategy) {
726736
this.retryStrategy = retryStrategy;
727737
}
728738

729-
730739
/**
731740
* Gets whether is enable redirection.
732741
*
@@ -746,6 +755,103 @@ public void setRedirectEnable(boolean redirectEnable) {
746755
this.redirectEnable = redirectEnable;
747756
}
748757

758+
/**
759+
* Gets the flag of verifing SSL certificate. By default it's true.
760+
*
761+
* @return true verify SSL certificate;false ignore SSL certificate.
762+
*/
763+
public boolean isVerifySSLEnable() {
764+
return verifySSLEnable;
765+
}
766+
767+
/**
768+
* Sets the flag of verifing SSL certificate.
769+
*
770+
* @param verifySSLEnable
771+
* True to verify SSL certificate; False to ignore SSL certificate.
772+
*/
773+
public void setVerifySSLEnable(boolean verifySSLEnable) {
774+
this.verifySSLEnable = verifySSLEnable;
775+
}
776+
777+
/**
778+
* Gets the KeyManagers are responsible for managing the key material
779+
* which is used to authenticate the local SSLSocket to its peer.
780+
*
781+
* @return the key managers.
782+
*/
783+
public KeyManager[] getKeyManagers() {
784+
return keyManagers;
785+
}
786+
787+
/**
788+
* Sets the key managers are responsible for managing the key material
789+
* which is used to authenticate the local SSLSocket to its peer.
790+
*
791+
* @param keyManagers
792+
* the key managers
793+
*/
794+
public void setKeyManagers(KeyManager[] keyManagers) {
795+
this.keyManagers = keyManagers;
796+
}
797+
798+
/**
799+
* Gets the instance of this interface manage which X509 certificates
800+
* may be used to authenticate the remote side of a secure socket.
801+
*
802+
* @return the x509 trust managers .
803+
*/
804+
public X509TrustManager[] getX509TrustManagers() {
805+
return x509TrustManagers;
806+
}
807+
808+
/**
809+
* Sets the instance of this interface manage which X509 certificates
810+
* may be used to authenticate the remote side of a secure socket.
811+
*
812+
* @param x509TrustManagers
813+
* x509 trust managers
814+
*/
815+
public void setX509TrustManagers(X509TrustManager[] x509TrustManagers) {
816+
this.x509TrustManagers = x509TrustManagers;
817+
}
749818

819+
/**
820+
* Gets the cryptographically strong random number.
821+
*
822+
* @return random number.
823+
*/
824+
public SecureRandom getSecureRandom() {
825+
return secureRandom;
826+
}
827+
828+
/**
829+
* Sets the cryptographically strong random number.
830+
*
831+
* @param secureRandom
832+
* the cryptographically strong random number
833+
*/
834+
public void setSecureRandom(SecureRandom secureRandom) {
835+
this.secureRandom = secureRandom;
836+
}
837+
838+
/**
839+
* Gets the instance of this interface for hostname verification.
840+
*
841+
* @return the hostname verification instance.
842+
*/
843+
public HostnameVerifier getHostnameVerifier() {
844+
return hostnameVerifier;
845+
}
846+
847+
/**
848+
* Sets instance of this interface for hostname verification.
849+
*
850+
* @param hostnameVerifier
851+
* the hostname verification instance
852+
*/
853+
public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
854+
this.hostnameVerifier = hostnameVerifier;
855+
}
750856

751857
}

src/main/java/com/aliyun/oss/common/comm/DefaultServiceClient.java

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@
2323
import java.io.IOException;
2424
import java.io.InputStream;
2525
import java.lang.reflect.Method;
26+
import java.security.KeyStore;
2627
import java.security.cert.CertificateException;
2728
import java.security.cert.X509Certificate;
29+
import java.util.ArrayList;
30+
import java.util.Arrays;
31+
import java.util.List;
2832

29-
import javax.net.ssl.SSLContext;
33+
import javax.net.ssl.*;
3034

3135
import org.apache.commons.codec.binary.Base64;
3236
import org.apache.http.Header;
@@ -47,16 +51,15 @@
4751
import org.apache.http.conn.HttpClientConnectionManager;
4852
import org.apache.http.conn.socket.ConnectionSocketFactory;
4953
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
54+
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
5055
import org.apache.http.conn.ssl.NoopHostnameVerifier;
5156
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
52-
import org.apache.http.conn.ssl.TrustStrategy;
5357
import org.apache.http.impl.auth.BasicScheme;
5458
import org.apache.http.impl.client.BasicAuthCache;
5559
import org.apache.http.impl.client.BasicCredentialsProvider;
5660
import org.apache.http.impl.client.CloseableHttpClient;
5761
import org.apache.http.impl.client.HttpClients;
5862
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
59-
import org.apache.http.ssl.SSLContextBuilder;
6063

6164
import com.aliyun.oss.ClientConfiguration;
6265
import com.aliyun.oss.ClientErrorCode;
@@ -232,23 +235,49 @@ protected CloseableHttpClient createHttpClient(HttpClientConnectionManager conne
232235
}
233236

234237
protected HttpClientConnectionManager createHttpClientConnectionManager() {
235-
SSLContext sslContext = null;
238+
SSLConnectionSocketFactory sslSocketFactory = null;
236239
try {
237-
sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
240+
List<TrustManager> trustManagerList = new ArrayList<TrustManager>();
241+
X509TrustManager[] trustManagers = config.getX509TrustManagers();
238242

239-
@Override
240-
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
241-
return true;
243+
if (null != trustManagers) {
244+
trustManagerList.addAll(Arrays.asList(trustManagers));
245+
}
246+
247+
// get trustManager using default certification from jdk
248+
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
249+
tmf.init((KeyStore) null);
250+
trustManagerList.addAll(Arrays.asList(tmf.getTrustManagers()));
251+
252+
final List<X509TrustManager> finalTrustManagerList = new ArrayList<X509TrustManager>();
253+
for (TrustManager tm : trustManagerList) {
254+
if (tm instanceof X509TrustManager) {
255+
finalTrustManagerList.add((X509TrustManager) tm);
242256
}
257+
}
258+
CompositeX509TrustManager compositeX509TrustManager = new CompositeX509TrustManager(finalTrustManagerList);
259+
compositeX509TrustManager.setVerifySSL(config.isVerifySSLEnable());
260+
KeyManager[] keyManagers = null;
261+
if (config.getKeyManagers() != null) {
262+
keyManagers = config.getKeyManagers();
263+
}
243264

244-
}).build();
265+
SSLContext sslContext = SSLContext.getInstance("TLS");
266+
sslContext.init(keyManagers, new TrustManager[]{compositeX509TrustManager}, config.getSecureRandom());
245267

268+
HostnameVerifier hostnameVerifier = null;
269+
if (!config.isVerifySSLEnable()) {
270+
hostnameVerifier = new NoopHostnameVerifier();
271+
} else if (config.getHostnameVerifier() != null) {
272+
hostnameVerifier = config.getHostnameVerifier();
273+
} else {
274+
hostnameVerifier = new DefaultHostnameVerifier();
275+
}
276+
sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
246277
} catch (Exception e) {
247278
throw new ClientException(e.getMessage());
248279
}
249280

250-
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext,
251-
NoopHostnameVerifier.INSTANCE);
252281
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
253282
.register(Protocol.HTTP.toString(), PlainConnectionSocketFactory.getSocketFactory())
254283
.register(Protocol.HTTPS.toString(), sslSocketFactory).build();
@@ -314,4 +343,53 @@ private static Method getClassMethd(Class<?> clazz, String methodName) {
314343
} catch (Exception e) {
315344
}
316345
}
346+
347+
private class CompositeX509TrustManager implements X509TrustManager {
348+
349+
private final List<X509TrustManager> trustManagers;
350+
private boolean verifySSL = true;
351+
352+
public boolean isVerifySSL() {
353+
return this.verifySSL;
354+
}
355+
356+
public void setVerifySSL(boolean verifySSL) {
357+
this.verifySSL = verifySSL;
358+
}
359+
360+
public CompositeX509TrustManager(List<X509TrustManager> trustManagers) {
361+
this.trustManagers = trustManagers;
362+
}
363+
364+
@Override
365+
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
366+
// do nothing
367+
}
368+
369+
@Override
370+
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
371+
if (!verifySSL) {
372+
return;
373+
}
374+
for (X509TrustManager trustManager : trustManagers) {
375+
try {
376+
trustManager.checkServerTrusted(chain, authType);
377+
return; // someone trusts them. success!
378+
} catch (CertificateException e) {
379+
// maybe someone else will trust them
380+
}
381+
}
382+
throw new CertificateException("None of the TrustManagers trust this certificate chain");
383+
}
384+
385+
@Override
386+
public X509Certificate[] getAcceptedIssuers() {
387+
List<X509Certificate> certificates = new ArrayList<X509Certificate>();
388+
for (X509TrustManager trustManager : trustManagers) {
389+
certificates.addAll(Arrays.asList(trustManager.getAcceptedIssuers()));
390+
}
391+
X509Certificate[] certificatesArray = new X509Certificate[certificates.size()];
392+
return certificates.toArray(certificatesArray);
393+
}
394+
}
317395
}

0 commit comments

Comments
 (0)