Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/main/java/com/aliyun/tea/okhttp/OkHttpClientBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.aliyun.tea.TeaException;
import com.aliyun.tea.okhttp.interceptors.SocksProxyAuthInterceptor;
import com.aliyun.tea.utils.StringUtils;
import com.aliyun.tea.utils.TrueHostnameVerifier;
import com.aliyun.tea.utils.DefaultHostnameVerifier;
import com.aliyun.tea.utils.X509TrustManagerImp;
import okhttp3.*;
import okhttp3.Authenticator;
Expand Down Expand Up @@ -87,11 +87,11 @@ public OkHttpClientBuilder connectionPool(Map<String, Object> map) {
public OkHttpClientBuilder certificate(Map<String, Object> map) {
try {
if (null != map.get("ignoreSSL") && Boolean.parseBoolean(String.valueOf(map.get("ignoreSSL")))) {
X509TrustManager compositeX509TrustManager = new X509TrustManagerImp();
X509TrustManager compositeX509TrustManager = new X509TrustManagerImp(true);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{compositeX509TrustManager}, new java.security.SecureRandom());
this.builder.sslSocketFactory(sslContext.getSocketFactory(), compositeX509TrustManager).
hostnameVerifier(new TrueHostnameVerifier());
hostnameVerifier(DefaultHostnameVerifier.getInstance(true));
} else if (!StringUtils.isEmpty(map.get("ca"))) {
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory keyManagerFactory = null;
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/com/aliyun/tea/utils/DefaultHostnameVerifier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.aliyun.tea.utils;

import okhttp3.internal.tls.OkHostnameVerifier;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

public class DefaultHostnameVerifier implements HostnameVerifier {
private final boolean ignoreSSLCert;
private static final HostnameVerifier NOOP_INSTANCE = new DefaultHostnameVerifier(true);
private static final HostnameVerifier DEFAULT_INSTANCE = OkHostnameVerifier.INSTANCE;

private DefaultHostnameVerifier(boolean ignoreSSLCert) {
this.ignoreSSLCert = ignoreSSLCert;
}

public static HostnameVerifier getInstance(boolean ignoreSSLCert) {
if (ignoreSSLCert) {
return NOOP_INSTANCE;
} else {
return DEFAULT_INSTANCE;
}
}

@Override
public boolean verify(String s, SSLSession sslSession) {
return ignoreSSLCert;
}
}
11 changes: 0 additions & 11 deletions src/main/java/com/aliyun/tea/utils/TrueHostnameVerifier.java

This file was deleted.

44 changes: 41 additions & 3 deletions src/main/java/com/aliyun/tea/utils/X509TrustManagerImp.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,57 @@
package com.aliyun.tea.utils;

import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class X509TrustManagerImp implements X509TrustManager {
private List<X509TrustManager> trustManagers = new ArrayList<X509TrustManager>();

private boolean ignoreSSLCert = false;

public boolean isIgnoreSSLCert() {
return ignoreSSLCert;
}

public X509TrustManagerImp(boolean ignoreSSLCert) {
this.ignoreSSLCert = ignoreSSLCert;
}

public X509TrustManagerImp(List<X509TrustManager> trustManagers) {
this.trustManagers = trustManagers;
}

@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
public void checkClientTrusted(X509Certificate[] chain, String authType) {
// do nothing
}

@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if (this.ignoreSSLCert) {
return;
}
for (X509TrustManager trustManager : this.trustManagers) {
try {
trustManager.checkServerTrusted(chain, authType);
return; // someone trusts them. success!
} catch (CertificateException e) {
// maybe someone else will trust them
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个是不是应该把异常抛出来啊

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

噢噢不是,这里是个链式检查,检查到最后一个还是不trust的话,会抛出CertificateException("None of the TrustManagers trust this certificate chain")

}
}
throw new CertificateException("None of the TrustManagers trust this certificate chain");
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
List<X509Certificate> certificates = new ArrayList<X509Certificate>();
for (X509TrustManager trustManager : this.trustManagers) {
certificates.addAll(Arrays.asList(trustManager.getAcceptedIssuers()));
}
X509Certificate[] certificatesArray = new X509Certificate[certificates.size()];
return certificates.toArray(certificatesArray);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.aliyun.tea.okhttp;

import com.aliyun.tea.TeaException;
import com.aliyun.tea.utils.TrueHostnameVerifier;
import com.aliyun.tea.utils.DefaultHostnameVerifier;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import org.junit.Assert;
Expand Down Expand Up @@ -103,7 +103,7 @@ public void certificateTest() throws IOException {
OkHttpClientBuilder builder = new OkHttpClientBuilder().certificate(map);

OkHttpClient client = builder.buildOkHttpClient();
Assert.assertFalse(client.hostnameVerifier() instanceof TrueHostnameVerifier);
Assert.assertFalse(client.hostnameVerifier() instanceof DefaultHostnameVerifier);
Assert.assertNotNull(client.sslSocketFactory());

map.put("key", null);
Expand Down
15 changes: 11 additions & 4 deletions src/test/java/com/aliyun/tea/utils/TrueHostnameVerifierTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@
import org.junit.Assert;
import org.junit.Test;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class TrueHostnameVerifierTest {
@Test
public void trueHostnameVerifierTest(){
TrueHostnameVerifier trueHostnameVerifier = new TrueHostnameVerifier();
public void trueHostnameVerifierTest() throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
HostnameVerifier trueHostnameVerifier = DefaultHostnameVerifier.getInstance(true);
SSLSession sslSession = null;
trueHostnameVerifier.verify("authType",sslSession);
Assert.assertTrue(trueHostnameVerifier.verify(null,null));
Assert.assertTrue(trueHostnameVerifier.verify("authType", sslSession));
Assert.assertTrue(trueHostnameVerifier.verify(null, null));

Constructor<DefaultHostnameVerifier> constructor = DefaultHostnameVerifier.class.getDeclaredConstructor(boolean.class);
constructor.setAccessible(true);
DefaultHostnameVerifier hostnameVerifier = constructor.newInstance(false);
Assert.assertFalse(hostnameVerifier.verify(null, null));
}
}
92 changes: 82 additions & 10 deletions src/test/java/com/aliyun/tea/utils/X509TrustManagerImpTest.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,106 @@
package com.aliyun.tea.utils;

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;

public class X509TrustManagerImpTest {

@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void getSetIgnoreSSLCert() {
X509TrustManagerImp trustManager = new X509TrustManagerImp(Collections.<X509TrustManager>emptyList());
Assert.assertFalse(trustManager.isIgnoreSSLCert());
trustManager = new X509TrustManagerImp(true);
Assert.assertTrue(trustManager.isIgnoreSSLCert());
}

@Test
public void testCheckClientTrusted(){
public void testCheckClientTrusted() {
try {
X509TrustManagerImp trustManagerImp = new X509TrustManagerImp();
trustManagerImp.checkClientTrusted(new X509Certificate[0],"authType");
}catch (Exception e){
X509TrustManagerImp trustManagerImp = new X509TrustManagerImp(Collections.<X509TrustManager>emptyList());
trustManagerImp.checkClientTrusted(new X509Certificate[0], "authType");
} catch (Exception e) {
Assert.fail();
}
}

@Test
public void testCheckServerTrusted(){
public void testCheckServerTrustedAndIgnoreSSLCert() {
try {
X509TrustManagerImp trustManager = new X509TrustManagerImp(true);
trustManager.checkServerTrusted(new X509Certificate[0], "authType");
} catch (Exception e) {
Assert.fail();
}

try {
X509TrustManagerImp trustManagerImp = new X509TrustManagerImp();
trustManagerImp.checkServerTrusted(new X509Certificate[0],"authType");
}catch (Exception e){
X509TrustManagerImp trustManagerImp = new X509TrustManagerImp(Collections.<X509TrustManager>emptyList());
trustManagerImp.checkServerTrusted(new X509Certificate[0], "authType");
Assert.fail();
} catch (Exception e) {
Assert.assertEquals("None of the TrustManagers trust this certificate chain", e.getMessage());
}

}

@Test
public void testCheckServerTrustedSucceedTwice() {
try {
final X509TrustManager trustManager0 = mock(X509TrustManager.class);
doThrow(CertificateException.class).when(trustManager0).checkServerTrusted(any(X509Certificate[].class), anyString());
final X509TrustManager trustManager1 = mock(X509TrustManager.class);
doNothing().when(trustManager0).checkServerTrusted(any(X509Certificate[].class), anyString());
List<X509TrustManager> trustManagerList = new ArrayList<X509TrustManager>();
trustManagerList.add(trustManager0);
trustManagerList.add(trustManager1);
X509TrustManagerImp trustManager = new X509TrustManagerImp(trustManagerList);
trustManager.checkServerTrusted(new X509Certificate[0], "authType");
} catch (Exception e) {
Assert.fail();
}

}

@Test
public void testCheckServerTrustedFailed() throws CertificateException {
thrown.expect(CertificateException.class);
final X509TrustManager trustManager0 = mock(X509TrustManager.class);
doThrow(CertificateException.class).when(trustManager0).checkServerTrusted(any(X509Certificate[].class), anyString());
List<X509TrustManager> trustManagerList = new ArrayList<X509TrustManager>();
trustManagerList.add(trustManager0);
X509TrustManagerImp trustManager = new X509TrustManagerImp(trustManagerList);
trustManager.checkServerTrusted(new X509Certificate[0], "authType");
}

@Test
public void testGetAcceptedIssuers(){
X509TrustManagerImp trustManagerImp = new X509TrustManagerImp();
public void testGetAcceptedIssuers() {
X509TrustManagerImp trustManagerImp = new X509TrustManagerImp(Collections.<X509TrustManager>emptyList());
trustManagerImp.getAcceptedIssuers();
X509Certificate[] res = trustManagerImp.getAcceptedIssuers();
Assert.assertEquals(0, res.length);
final X509TrustManager trustManager0 = mock(X509TrustManager.class);
X509Certificate certificate = mock(X509Certificate.class);
when(trustManager0.getAcceptedIssuers()).thenReturn(new X509Certificate[]{certificate});
List<X509TrustManager> trustManagerList = new ArrayList<X509TrustManager>();
trustManagerList.add(trustManager0);
X509TrustManagerImp trustManager = new X509TrustManagerImp(trustManagerList);
res = trustManager.getAcceptedIssuers();
Assert.assertEquals(1, res.length);
Assert.assertEquals(certificate, res[0]);
}
}