@@ -4,9 +4,7 @@ import android.graphics.drawable.Drawable
4
4
import android.net.http.SslError
5
5
import android.os.Bundle
6
6
import android.view.View
7
- import android.webkit.SslErrorHandler
8
- import android.webkit.WebView
9
- import android.webkit.WebViewClient
7
+ import android.webkit.*
10
8
import android.widget.Button
11
9
import android.widget.Toast
12
10
import androidx.annotation.IdRes
@@ -17,7 +15,10 @@ import com.android.volley.toolbox.BasicNetwork
17
15
import com.android.volley.toolbox.HurlStack
18
16
import com.android.volley.toolbox.NoCache
19
17
import com.android.volley.toolbox.StringRequest
18
+ import com.appmattus.certificatetransparency.certificateTransparencyHostnameVerifier
20
19
import com.appmattus.certificatetransparency.certificateTransparencyInterceptor
20
+ import com.appmattus.certificatetransparency.certificateTransparencyTrustManager
21
+ import com.appmattus.certificatetransparency.installCertificateTransparencyProvider
21
22
import com.datatheorem.android.trustkit.TrustKit
22
23
import kotlinx.coroutines.Dispatchers
23
24
import kotlinx.coroutines.GlobalScope
@@ -46,6 +47,14 @@ class MainActivity : AppCompatActivity() {
46
47
setContentView(R .layout.activity_main)
47
48
48
49
TrustKit .initializeWithNetworkSecurityConfiguration(this @MainActivity)
50
+
51
+ // Appmattus global setup:
52
+ installCertificateTransparencyProvider {
53
+ // Match only our single Appmattus test domain:
54
+ - " *.httptoolkit.tech"
55
+ - " *.badssl.com"
56
+ + " rsa4096.badssl.com"
57
+ }
49
58
}
50
59
51
60
private fun onStart (@IdRes id : Int ) {
@@ -96,7 +105,7 @@ class MainActivity : AppCompatActivity() {
96
105
GlobalScope .launch(Dispatchers .IO ) {
97
106
onStart(R .id.unpinned)
98
107
try {
99
- val mURL = URL (" https://httptoolkit.com " )
108
+ val mURL = URL (" https://amiusing. httptoolkit.tech " )
100
109
with (mURL.openConnection() as HttpsURLConnection ) {
101
110
println (" URL: ${this .url} " )
102
111
println (" Response Code: ${this .responseCode} " )
@@ -116,7 +125,7 @@ class MainActivity : AppCompatActivity() {
116
125
117
126
var connectionFailed = false
118
127
119
- webView.loadUrl(" https://sha256.badssl.com " )
128
+ webView.loadUrl(" https://amiusing.httptoolkit.tech " )
120
129
webView.webViewClient = object : WebViewClient () {
121
130
override fun onReceivedSslError (
122
131
view : WebView ? ,
@@ -161,7 +170,7 @@ class MainActivity : AppCompatActivity() {
161
170
onStart(R .id.okhttp_pinned)
162
171
163
172
try {
164
- val hostname = " sha256 .badssl.com"
173
+ val hostname = " ecc384 .badssl.com"
165
174
val certificatePinner = CertificatePinner .Builder ()
166
175
.add(hostname, " sha256/${LETS_ENCRYPT_ROOT_SHA256 } " )
167
176
.build()
@@ -170,7 +179,7 @@ class MainActivity : AppCompatActivity() {
170
179
.certificatePinner(certificatePinner)
171
180
.build()
172
181
val request = Request .Builder ()
173
- .url(" https://sha256 .badssl.com" )
182
+ .url(" https://ecc384 .badssl.com" )
174
183
.build()
175
184
176
185
client.newCall(request).execute().use { response ->
@@ -216,7 +225,7 @@ class MainActivity : AppCompatActivity() {
216
225
// Make a request using that client:
217
226
val stringRequest = StringRequest (
218
227
com.android.volley.Request .Method .GET ,
219
- " https://sha256 .badssl.com" ,
228
+ " https://ecc384 .badssl.com" ,
220
229
{ _ ->
221
230
println (" Volley success" )
222
231
this @MainActivity.onSuccess(R .id.volley_pinned)
@@ -258,6 +267,26 @@ class MainActivity : AppCompatActivity() {
258
267
fun sendAppmattusCTChecked (view : View ) {
259
268
GlobalScope .launch(Dispatchers .IO ) {
260
269
onStart(R .id.appmattus_ct_checked)
270
+
271
+ try {
272
+ val mURL = URL (" https://sha256.badssl.com" )
273
+ with (mURL.openConnection() as HttpsURLConnection ) {
274
+ this .hostnameVerifier = certificateTransparencyHostnameVerifier(this .hostnameVerifier)
275
+ println (" URL: ${this .url} " )
276
+ println (" Response Code: ${this .responseCode} " )
277
+ }
278
+
279
+ onSuccess(R .id.appmattus_ct_checked)
280
+ } catch (e: Throwable ) {
281
+ println (e)
282
+ onError(R .id.appmattus_ct_checked, e.toString())
283
+ }
284
+ }
285
+ }
286
+
287
+ fun sendAppmattusOkHttpCTChecked (view : View ) {
288
+ GlobalScope .launch(Dispatchers .IO ) {
289
+ onStart(R .id.appmattus_okhttp_ct_checked)
261
290
try {
262
291
val appmattusInterceptor = certificateTransparencyInterceptor()
263
292
val client = OkHttpClient .Builder ().apply {
@@ -272,10 +301,92 @@ class MainActivity : AppCompatActivity() {
272
301
println (" Response Code: ${response.code} " )
273
302
}
274
303
275
- onSuccess(R .id.appmattus_ct_checked )
304
+ onSuccess(R .id.appmattus_okhttp_ct_checked )
276
305
} catch (e: Throwable ) {
277
306
println (e)
278
- onError(R .id.appmattus_ct_checked, e.toString())
307
+ onError(R .id.appmattus_okhttp_ct_checked, e.toString())
308
+ }
309
+ }
310
+ }
311
+
312
+ fun sendAppmattusRawCTChecked (view : View ) {
313
+ GlobalScope .launch(Dispatchers .IO ) {
314
+ onStart(R .id.appmattus_raw_ct_checked)
315
+
316
+ val cf = CertificateFactory .getInstance(" X.509" )
317
+ val caStream = BufferedInputStream (resources.openRawResource(R .raw.lets_encrypt_isrg_root))
318
+ val caCertificate = cf.generateCertificate(caStream)
319
+
320
+ val keyStore = KeyStore .getInstance(KeyStore .getDefaultType())
321
+ keyStore.load(null )
322
+ keyStore.setCertificateEntry(" ca" , caCertificate)
323
+
324
+ val trustManagerFactory = TrustManagerFactory
325
+ .getInstance(TrustManagerFactory .getDefaultAlgorithm())
326
+ trustManagerFactory.init (keyStore)
327
+
328
+ val originalTrustManagers = trustManagerFactory.trustManagers;
329
+
330
+ // Wrap the native trust managers with Appmattus's CT implementation:
331
+ val ctWrappedTrustManagers = originalTrustManagers.map { tm ->
332
+ certificateTransparencyTrustManager(tm as X509TrustManager )
333
+ }.toTypedArray()
334
+
335
+ try {
336
+ val context = SSLContext .getInstance(" TLS" )
337
+ context.init (null , ctWrappedTrustManagers, null )
338
+
339
+ val mURL = URL (" https://ecc384.badssl.com" )
340
+ with (mURL.openConnection() as HttpsURLConnection ) {
341
+ this .sslSocketFactory = context.socketFactory
342
+
343
+ println (" URL: ${this .url} " )
344
+ println (" Response Code: ${this .responseCode} " )
345
+ }
346
+ onSuccess(R .id.appmattus_raw_ct_checked)
347
+ } catch (e: Throwable ) {
348
+ println (e)
349
+ onError(R .id.appmattus_raw_ct_checked, e.toString())
350
+ }
351
+ }
352
+ }
353
+
354
+ // Pinned by global setup from installCertificateTransparencyProvider
355
+ // call in onCreate():
356
+ fun sendAppmattusCTWebView (view : View ) {
357
+ onStart(R .id.appmattus_webview_ct_checked)
358
+ val webView = WebView (this @MainActivity)
359
+
360
+ var connectionFailed = false
361
+
362
+ webView.loadUrl(" https://rsa4096.badssl.com" )
363
+ webView.webViewClient = object : WebViewClient () {
364
+ override fun onReceivedSslError (
365
+ view : WebView ? ,
366
+ handler : SslErrorHandler ? ,
367
+ error : SslError ?
368
+ ) {
369
+ println (" Appmattus webview SSL error: " + error.toString())
370
+ onError(R .id.appmattus_webview_ct_checked, error.toString())
371
+ connectionFailed = true
372
+ handler?.cancel()
373
+ }
374
+
375
+ override fun onReceivedError (
376
+ view : WebView ? ,
377
+ request : WebResourceRequest ? ,
378
+ error : WebResourceError ?
379
+ ) {
380
+ println (" Appmattus webview error: " + error.toString())
381
+ onError(R .id.appmattus_webview_ct_checked, error.toString())
382
+ connectionFailed = true
383
+ }
384
+
385
+ override fun onPageFinished (view : WebView ? , url : String? ) {
386
+ if (connectionFailed) return
387
+
388
+ println (" Appmattus WebView loaded OK" )
389
+ onSuccess(R .id.appmattus_webview_ct_checked)
279
390
}
280
391
}
281
392
}
@@ -302,7 +413,7 @@ class MainActivity : AppCompatActivity() {
302
413
val context = SSLContext .getInstance(" TLS" )
303
414
context.init (null , trustManagerFactory.trustManagers, null )
304
415
305
- val mURL = URL (" https://sha256 .badssl.com" )
416
+ val mURL = URL (" https://ecc384 .badssl.com" )
306
417
with (mURL.openConnection() as HttpsURLConnection ) {
307
418
this .sslSocketFactory = context.socketFactory
308
419
@@ -338,7 +449,7 @@ class MainActivity : AppCompatActivity() {
338
449
val context = SSLContext .getInstance(" TLS" )
339
450
context.init (null , trustManager, null )
340
451
341
- val socket = context.socketFactory.createSocket(" sha256 .badssl.com" , 443 ) as SSLSocket
452
+ val socket = context.socketFactory.createSocket(" ecc384 .badssl.com" , 443 ) as SSLSocket
342
453
343
454
val certs = socket.session.peerCertificates
344
455
@@ -350,7 +461,7 @@ class MainActivity : AppCompatActivity() {
350
461
// Send a real request, just to make it clear that we trust the connection:
351
462
val pw = PrintWriter (socket.outputStream)
352
463
pw.println (" GET / HTTP/1.1" )
353
- pw.println (" Host: sha256 .badssl.com" )
464
+ pw.println (" Host: ecc384 .badssl.com" )
354
465
pw.println (" " )
355
466
pw.flush()
356
467
0 commit comments