18
18
19
19
package com .loopj .android .http .sample .util ;
20
20
21
+ import android .annotation .TargetApi ;
21
22
import android .util .Log ;
22
23
23
24
import com .loopj .android .http .AsyncHttpClient ;
25
+
24
26
import org .apache .http .conn .ssl .SSLSocketFactory ;
25
27
26
- import java .lang .reflect .Field ;
27
28
import java .io .ByteArrayInputStream ;
28
29
import java .io .IOException ;
29
30
import java .io .InputStream ;
31
+ import java .lang .reflect .Field ;
30
32
import java .net .InetAddress ;
31
33
import java .net .Socket ;
32
- import java .net .UnknownHostException ;
33
- import java .security .cert .Certificate ;
34
- import java .security .cert .X509Certificate ;
35
34
import java .security .InvalidKeyException ;
36
35
import java .security .KeyManagementException ;
37
36
import java .security .KeyStore ;
40
39
import java .security .NoSuchProviderException ;
41
40
import java .security .SignatureException ;
42
41
import java .security .UnrecoverableKeyException ;
42
+ import java .security .cert .Certificate ;
43
43
import java .security .cert .CertificateException ;
44
44
import java .security .cert .CertificateFactory ;
45
+ import java .security .cert .X509Certificate ;
45
46
46
47
import javax .net .ssl .SSLContext ;
47
48
import javax .net .ssl .TrustManager ;
48
49
import javax .net .ssl .X509TrustManager ;
49
50
50
51
/**
51
- * A class to authenticate a secured connection against a custom CA using a
52
- * BKS store.
52
+ * A class to authenticate a secured connection against a custom CA using a BKS store.
53
53
*
54
54
* @author Noor Dawod <[email protected] >
55
55
*/
@@ -61,25 +61,20 @@ public class SecureSocketFactory extends SSLSocketFactory {
61
61
private final X509Certificate [] acceptedIssuers ;
62
62
63
63
/**
64
- * Instantiate a new secured factory pertaining to the passed store. Be sure
65
- * to initialize the store with the password using
66
- * {@link java.security.KeyStore#load(java.io.InputStream, char[])} method.
64
+ * Instantiate a new secured factory pertaining to the passed store. Be sure to initialize the
65
+ * store with the password using {@link java.security.KeyStore#load(java.io.InputStream,
66
+ * char[])} method.
67
67
*
68
68
* @param store The key store holding the certificate details
69
69
* @param alias The alias of the certificate to use
70
- * @throws CertificateException
71
- * @throws NoSuchAlgorithmException
72
- * @throws KeyManagementException
73
- * @throws KeyStoreException
74
- * @throws UnrecoverableKeyException
75
70
*/
76
71
public SecureSocketFactory (KeyStore store , String alias )
77
- throws
78
- CertificateException ,
79
- NoSuchAlgorithmException ,
80
- KeyManagementException ,
81
- KeyStoreException ,
82
- UnrecoverableKeyException {
72
+ throws
73
+ CertificateException ,
74
+ NoSuchAlgorithmException ,
75
+ KeyManagementException ,
76
+ KeyStoreException ,
77
+ UnrecoverableKeyException {
83
78
84
79
super (store );
85
80
@@ -88,10 +83,10 @@ public SecureSocketFactory(KeyStore store, String alias)
88
83
89
84
// Turn it to X509 format.
90
85
InputStream is = new ByteArrayInputStream (rootca .getEncoded ());
91
- X509Certificate x509ca = (X509Certificate )CertificateFactory .getInstance ("X.509" ).generateCertificate (is );
86
+ X509Certificate x509ca = (X509Certificate ) CertificateFactory .getInstance ("X.509" ).generateCertificate (is );
92
87
AsyncHttpClient .silentCloseInputStream (is );
93
88
94
- if (null == x509ca ) {
89
+ if (null == x509ca ) {
95
90
throw new CertificateException ("Embedded SSL certificate has expired." );
96
91
}
97
92
@@ -103,72 +98,72 @@ public SecureSocketFactory(KeyStore store, String alias)
103
98
104
99
sslCtx = SSLContext .getInstance ("TLS" );
105
100
sslCtx .init (
106
- null ,
107
- new TrustManager [] {
108
- new X509TrustManager () {
109
- @ Override
110
- public void checkClientTrusted (X509Certificate [] chain , String authType ) throws CertificateException {
111
- }
112
-
113
- @ Override
114
- public void checkServerTrusted (X509Certificate [] chain , String authType ) throws CertificateException {
115
- Exception error = null ;
116
-
117
- if (null == chain || 0 == chain .length ) {
118
- error = new CertificateException ("Certificate chain is invalid." );
119
- } else if (null == authType || 0 == authType .length ()) {
120
- error = new CertificateException ("Authentication type is invalid." );
121
- } else {
122
- Log .i (LOG_TAG , "Chain includes " + chain .length + " certificates." );
123
- try {
124
- for (X509Certificate cert : chain ) {
125
- Log .i (LOG_TAG , "Server Certificate Details:" );
126
- Log .i (LOG_TAG , "---------------------------" );
127
- Log .i (LOG_TAG , "IssuerDN: " + cert .getIssuerDN ().toString ());
128
- Log .i (LOG_TAG , "SubjectDN: " + cert .getSubjectDN ().toString ());
129
- Log .i (LOG_TAG , "Serial Number: " + cert .getSerialNumber ());
130
- Log .i (LOG_TAG , "Version: " + cert .getVersion ());
131
- Log .i (LOG_TAG , "Not before: " + cert .getNotBefore ().toString ());
132
- Log .i (LOG_TAG , "Not after: " + cert .getNotAfter ().toString ());
133
- Log .i (LOG_TAG , "---------------------------" );
134
-
135
- // Make sure that it hasn't expired.
136
- cert .checkValidity ();
137
-
138
- // Verify the certificate's public key chain.
139
- cert .verify (rootca .getPublicKey ());
101
+ null ,
102
+ new TrustManager []{
103
+ new X509TrustManager () {
104
+ @ Override
105
+ public void checkClientTrusted (X509Certificate [] chain , String authType ) throws CertificateException {
106
+ }
107
+
108
+ @ Override
109
+ public void checkServerTrusted (X509Certificate [] chain , String authType ) throws CertificateException {
110
+ Exception error = null ;
111
+
112
+ if (null == chain || 0 == chain .length ) {
113
+ error = new CertificateException ("Certificate chain is invalid." );
114
+ } else if (null == authType || 0 == authType .length ()) {
115
+ error = new CertificateException ("Authentication type is invalid." );
116
+ } else {
117
+ Log .i (LOG_TAG , "Chain includes " + chain .length + " certificates." );
118
+ try {
119
+ for (X509Certificate cert : chain ) {
120
+ Log .i (LOG_TAG , "Server Certificate Details:" );
121
+ Log .i (LOG_TAG , "---------------------------" );
122
+ Log .i (LOG_TAG , "IssuerDN: " + cert .getIssuerDN ().toString ());
123
+ Log .i (LOG_TAG , "SubjectDN: " + cert .getSubjectDN ().toString ());
124
+ Log .i (LOG_TAG , "Serial Number: " + cert .getSerialNumber ());
125
+ Log .i (LOG_TAG , "Version: " + cert .getVersion ());
126
+ Log .i (LOG_TAG , "Not before: " + cert .getNotBefore ().toString ());
127
+ Log .i (LOG_TAG , "Not after: " + cert .getNotAfter ().toString ());
128
+ Log .i (LOG_TAG , "---------------------------" );
129
+
130
+ // Make sure that it hasn't expired.
131
+ cert .checkValidity ();
132
+
133
+ // Verify the certificate's public key chain.
134
+ cert .verify (rootca .getPublicKey ());
135
+ }
136
+ } catch (InvalidKeyException e ) {
137
+ error = e ;
138
+ } catch (NoSuchAlgorithmException e ) {
139
+ error = e ;
140
+ } catch (NoSuchProviderException e ) {
141
+ error = e ;
142
+ } catch (SignatureException e ) {
143
+ error = e ;
144
+ }
145
+ }
146
+ if (null != error ) {
147
+ Log .e (LOG_TAG , "Certificate error" , error );
148
+ throw new CertificateException (error );
140
149
}
141
- } catch (InvalidKeyException e ) {
142
- error = e ;
143
- } catch (NoSuchAlgorithmException e ) {
144
- error = e ;
145
- } catch (NoSuchProviderException e ) {
146
- error = e ;
147
- } catch (SignatureException e ) {
148
- error = e ;
150
+ }
151
+
152
+ @ Override
153
+ public X509Certificate [] getAcceptedIssuers () {
154
+ return acceptedIssuers ;
149
155
}
150
156
}
151
- if (null != error ) {
152
- Log .e (LOG_TAG , "Certificate error" , error );
153
- throw new CertificateException (error );
154
- }
155
- }
156
-
157
- @ Override
158
- public X509Certificate [] getAcceptedIssuers () {
159
- return acceptedIssuers ;
160
- }
161
- }
162
- },
163
- null
157
+ },
158
+ null
164
159
);
165
160
166
161
setHostnameVerifier (SSLSocketFactory .STRICT_HOSTNAME_VERIFIER );
167
162
}
168
163
169
164
@ Override
170
165
public Socket createSocket (Socket socket , String host , int port , boolean autoClose )
171
- throws IOException , UnknownHostException {
166
+ throws IOException {
172
167
173
168
injectHostname (socket , host );
174
169
return sslCtx .getSocketFactory ().createSocket (socket , host , port , autoClose );
@@ -180,21 +175,21 @@ public Socket createSocket() throws IOException {
180
175
}
181
176
182
177
/**
183
- * Pre-ICS Android had a bug resolving HTTPS addresses. This workaround
184
- * fixes that bug.
178
+ * Pre-ICS Android had a bug resolving HTTPS addresses. This workaround fixes that bug.
185
179
*
186
180
* @param socket The socket to alter
187
- * @param host Hostname to connect to
188
- * @see https://code.google.com/p/android/issues/detail?id=13117#c14
181
+ * @param host Hostname to connect to
182
+ * @see <a href="http://github.com/%3C/span%3Ehttps://code.google.com/p/android/issues/detail?id=13117#c14%3Cspan%20class="x x-first x-last">">https://code.google.com/p/android/issues/detail?id=13117#c14</a>
189
183
*/
184
+ @ TargetApi (4 )
190
185
private void injectHostname (Socket socket , String host ) {
191
- if ( android . os . Build . VERSION . SDK_INT < 14 ) {
192
- try {
186
+ try {
187
+ if ( android . os . Build . VERSION . SDK_INT < 14 ) {
193
188
Field field = InetAddress .class .getDeclaredField ("hostName" );
194
189
field .setAccessible (true );
195
190
field .set (socket .getInetAddress (), host );
196
- } catch (Exception ignored ) {
197
191
}
192
+ } catch (Exception ignored ) {
198
193
}
199
194
}
200
195
}
0 commit comments