Skip to content

Commit fa056c5

Browse files
committed
Use reflection to avoid the "not part of JDK" error running tests.
1 parent db6716a commit fa056c5

File tree

2 files changed

+65
-16
lines changed

2 files changed

+65
-16
lines changed

api/src/main/java/org/asynchttpclient/AsyncHttpClientConfigBean.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.asynchttpclient.filter.IOExceptionFilter;
1616
import org.asynchttpclient.filter.RequestFilter;
1717
import org.asynchttpclient.filter.ResponseFilter;
18+
import org.asynchttpclient.util.DefaultHostnameVerifier;
1819
import org.asynchttpclient.util.ProxyUtils;
1920

2021
import javax.net.ssl.HostnameVerifier;
@@ -70,12 +71,7 @@ void configureDefaults() {
7071
allowSslConnectionPool = true;
7172
useRawUrl = false;
7273
removeQueryParamOnRedirect = true;
73-
hostnameVerifier = new HostnameVerifier() {
74-
75-
public boolean verify(String s, SSLSession sslSession) {
76-
return true;
77-
}
78-
};
74+
hostnameVerifier = new DefaultHostnameVerifier();
7975
}
8076

8177
void configureExecutors() {

api/src/main/java/org/asynchttpclient/util/DefaultHostnameVerifier.java

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
*/
77
package org.asynchttpclient.util;
88

9-
import sun.security.util.HostnameChecker;
10-
119
import javax.net.ssl.HostnameVerifier;
1210
import javax.net.ssl.SSLPeerUnverifiedException;
1311
import javax.net.ssl.SSLSession;
1412
import javax.security.auth.kerberos.KerberosPrincipal;
13+
import java.lang.reflect.InvocationTargetException;
14+
import java.lang.reflect.Method;
1515
import java.security.Principal;
1616
import java.security.cert.Certificate;
1717
import java.security.cert.CertificateException;
@@ -28,7 +28,6 @@
2828
* <p/>
2929
* This code is based on Kevin Locke's <a href="http://kevinlocke.name/bits/2012/10/03/ssl-certificate-verification-in-dispatch-and-asynchttpclient/">guide</a> .
3030
* <p/>
31-
3231
*/
3332
public class DefaultHostnameVerifier implements HostnameVerifier {
3433

@@ -41,21 +40,76 @@ public DefaultHostnameVerifier(HostnameVerifier extraHostnameVerifier) {
4140
this.extraHostnameVerifier = extraHostnameVerifier;
4241
}
4342

43+
public final static byte TYPE_TLS = 1;
44+
45+
private Object getHostnameChecker() {
46+
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
47+
try {
48+
final Class<Object> hostnameCheckerClass = (Class<Object>) classLoader.loadClass("sun.security.util.HostnameChecker");
49+
final Method instanceMethod = hostnameCheckerClass.getMethod("getInstance", Byte.TYPE);
50+
final Object hostnameChecker = instanceMethod.invoke(null, TYPE_TLS);
51+
return hostnameChecker;
52+
} catch (ClassNotFoundException e) {
53+
throw new IllegalStateException(e);
54+
} catch (NoSuchMethodException e) {
55+
throw new IllegalStateException(e);
56+
} catch (InvocationTargetException e) {
57+
throw new IllegalStateException(e);
58+
} catch (IllegalAccessException e) {
59+
throw new IllegalStateException(e);
60+
}
61+
}
62+
63+
private void match(Object checker, String hostname, X509Certificate peerCertificate) throws CertificateException {
64+
try {
65+
final Class<?> hostnameCheckerClass = checker.getClass();
66+
final Method checkMethod = hostnameCheckerClass.getMethod("match", String.class, X509Certificate.class);
67+
checkMethod.invoke(checker, hostname, peerCertificate);
68+
} catch (NoSuchMethodException e) {
69+
throw new IllegalStateException(e);
70+
} catch (InvocationTargetException e) {
71+
Throwable t = e.getCause();
72+
if (t instanceof CertificateException) {
73+
throw (CertificateException) t;
74+
} else {
75+
throw new IllegalStateException(e);
76+
}
77+
} catch (IllegalAccessException e) {
78+
throw new IllegalStateException(e);
79+
}
80+
}
81+
82+
private boolean match(Object checker, String hostname, Principal principal) {
83+
try {
84+
final Class<?> hostnameCheckerClass = checker.getClass();
85+
final Method checkMethod = hostnameCheckerClass.getMethod("match", String.class, Principal.class);
86+
final boolean result = (Boolean) checkMethod.invoke(null, hostname, principal);
87+
return result;
88+
} catch (NoSuchMethodException e) {
89+
throw new IllegalStateException(e);
90+
} catch (InvocationTargetException e) {
91+
throw new IllegalStateException(e);
92+
} catch (IllegalAccessException e) {
93+
throw new IllegalStateException(e);
94+
}
95+
}
96+
4497
private boolean hostnameMatches(String hostname, SSLSession session) {
45-
HostnameChecker checker =
46-
HostnameChecker.getInstance(HostnameChecker.TYPE_TLS);
98+
boolean validCertificate = false;
99+
boolean validPrincipal = false;
47100

48-
boolean validCertificate = false, validPrincipal = false;
101+
final Object checker = getHostnameChecker();
49102
try {
50-
Certificate[] peerCertificates = session.getPeerCertificates();
103+
104+
final Certificate[] peerCertificates = session.getPeerCertificates();
51105

52106
if (peerCertificates.length > 0 &&
53107
peerCertificates[0] instanceof X509Certificate) {
54108
X509Certificate peerCertificate =
55109
(X509Certificate) peerCertificates[0];
56110

57111
try {
58-
checker.match(hostname, peerCertificate);
112+
match(checker, hostname, peerCertificate);
59113
// Certificate matches hostname
60114
validCertificate = true;
61115
} catch (CertificateException ex) {
@@ -69,7 +123,7 @@ private boolean hostnameMatches(String hostname, SSLSession session) {
69123
try {
70124
Principal peerPrincipal = session.getPeerPrincipal();
71125
if (peerPrincipal instanceof KerberosPrincipal) {
72-
validPrincipal = HostnameChecker.match(hostname,
126+
validPrincipal = match(checker, hostname,
73127
(KerberosPrincipal) peerPrincipal);
74128
} else {
75129
// Can't verify principal, not Kerberos
@@ -78,7 +132,6 @@ private boolean hostnameMatches(String hostname, SSLSession session) {
78132
// Can't verify principal, no principal
79133
}
80134
}
81-
82135
return validCertificate || validPrincipal;
83136
}
84137

0 commit comments

Comments
 (0)