6
6
*/
7
7
package org .asynchttpclient .util ;
8
8
9
- import sun .security .util .HostnameChecker ;
10
-
11
9
import javax .net .ssl .HostnameVerifier ;
12
10
import javax .net .ssl .SSLPeerUnverifiedException ;
13
11
import javax .net .ssl .SSLSession ;
14
12
import javax .security .auth .kerberos .KerberosPrincipal ;
13
+ import java .lang .reflect .InvocationTargetException ;
14
+ import java .lang .reflect .Method ;
15
15
import java .security .Principal ;
16
16
import java .security .cert .Certificate ;
17
17
import java .security .cert .CertificateException ;
28
28
* <p/>
29
29
* 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> .
30
30
* <p/>
31
-
32
31
*/
33
32
public class DefaultHostnameVerifier implements HostnameVerifier {
34
33
@@ -41,21 +40,76 @@ public DefaultHostnameVerifier(HostnameVerifier extraHostnameVerifier) {
41
40
this .extraHostnameVerifier = extraHostnameVerifier ;
42
41
}
43
42
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
+
44
97
private boolean hostnameMatches (String hostname , SSLSession session ) {
45
- HostnameChecker checker =
46
- HostnameChecker . getInstance ( HostnameChecker . TYPE_TLS ) ;
98
+ boolean validCertificate = false ;
99
+ boolean validPrincipal = false ;
47
100
48
- boolean validCertificate = false , validPrincipal = false ;
101
+ final Object checker = getHostnameChecker () ;
49
102
try {
50
- Certificate [] peerCertificates = session .getPeerCertificates ();
103
+
104
+ final Certificate [] peerCertificates = session .getPeerCertificates ();
51
105
52
106
if (peerCertificates .length > 0 &&
53
107
peerCertificates [0 ] instanceof X509Certificate ) {
54
108
X509Certificate peerCertificate =
55
109
(X509Certificate ) peerCertificates [0 ];
56
110
57
111
try {
58
- checker . match (hostname , peerCertificate );
112
+ match (checker , hostname , peerCertificate );
59
113
// Certificate matches hostname
60
114
validCertificate = true ;
61
115
} catch (CertificateException ex ) {
@@ -69,7 +123,7 @@ private boolean hostnameMatches(String hostname, SSLSession session) {
69
123
try {
70
124
Principal peerPrincipal = session .getPeerPrincipal ();
71
125
if (peerPrincipal instanceof KerberosPrincipal ) {
72
- validPrincipal = HostnameChecker . match (hostname ,
126
+ validPrincipal = match (checker , hostname ,
73
127
(KerberosPrincipal ) peerPrincipal );
74
128
} else {
75
129
// Can't verify principal, not Kerberos
@@ -78,7 +132,6 @@ private boolean hostnameMatches(String hostname, SSLSession session) {
78
132
// Can't verify principal, no principal
79
133
}
80
134
}
81
-
82
135
return validCertificate || validPrincipal ;
83
136
}
84
137
0 commit comments