@@ -8,12 +8,20 @@ import android.widget.Toast
8
8
import androidx.annotation.IdRes
9
9
import androidx.appcompat.app.AppCompatActivity
10
10
import androidx.core.content.ContextCompat
11
- import kotlinx.coroutines.Dispatchers
12
- import kotlinx.coroutines.GlobalScope
13
- import kotlinx.coroutines.launch
14
- import kotlinx.coroutines.withContext
11
+ import com.android.volley.toolbox.HurlStack
12
+ import com.android.volley.toolbox.StringRequest
13
+ import com.android.volley.toolbox.Volley
14
+ import kotlinx.coroutines.*
15
+ import okhttp3.CertificatePinner
16
+ import okhttp3.OkHttpClient
17
+ import okhttp3.Request
18
+ import java.io.BufferedInputStream
15
19
import java.net.HttpURLConnection
16
20
import java.net.URL
21
+ import java.security.KeyStore
22
+ import java.security.cert.CertificateFactory
23
+ import javax.net.ssl.SSLContext
24
+ import javax.net.ssl.TrustManagerFactory
17
25
18
26
19
27
class MainActivity : AppCompatActivity () {
@@ -22,8 +30,8 @@ class MainActivity : AppCompatActivity() {
22
30
setContentView(R .layout.activity_main)
23
31
}
24
32
25
- private suspend fun onStart (@IdRes id : Int ) {
26
- withContext (Dispatchers .Main ) {
33
+ private fun onStart (@IdRes id : Int ) {
34
+ GlobalScope .launch (Dispatchers .Main ) {
27
35
val button = findViewById<Button >(id)
28
36
button.setBackgroundColor(
29
37
ContextCompat .getColor(this @MainActivity, R .color.purple_500)
@@ -32,32 +40,36 @@ class MainActivity : AppCompatActivity() {
32
40
}
33
41
}
34
42
35
- private suspend fun onSuccess (@IdRes id : Int ) {
36
- withContext(Dispatchers .Main ) {
43
+ private fun onSuccess (@IdRes id : Int ) {
44
+ println (" onSuccess" )
45
+ GlobalScope .launch(Dispatchers .Main ) {
46
+ println (" dispatched" )
37
47
val button = findViewById<Button >(id)
38
48
button.setBackgroundColor(
39
- ContextCompat .getColor(this @MainActivity, R .color.success)
49
+ ContextCompat .getColor(this @MainActivity, R .color.success)
40
50
)
41
- val img: Drawable = ContextCompat .getDrawable(this @MainActivity,
42
- R .drawable.baseline_check_circle_24
51
+ val img: Drawable = ContextCompat .getDrawable(
52
+ this @MainActivity,
53
+ R .drawable.baseline_check_circle_24
43
54
)!!
44
55
button.setCompoundDrawablesWithIntrinsicBounds(img, null , null , null )
45
56
}
46
57
}
47
58
48
- private suspend fun onError (@IdRes id : Int , message : String ) {
49
- withContext (Dispatchers .Main ) {
59
+ private fun onError (@IdRes id : Int , message : String ) {
60
+ GlobalScope .launch (Dispatchers .Main ) {
50
61
val button = findViewById<Button >(id)
51
62
button.setBackgroundColor(
52
- ContextCompat .getColor(this @MainActivity, R .color.failure)
63
+ ContextCompat .getColor(this @MainActivity, R .color.failure)
53
64
)
54
- val img: Drawable = ContextCompat .getDrawable(this @MainActivity,
65
+ val img: Drawable = ContextCompat .getDrawable(
66
+ this @MainActivity,
55
67
R .drawable.baseline_cancel_24
56
68
)!!
57
69
button.setCompoundDrawablesWithIntrinsicBounds(img, null , null , null )
58
70
59
- val duration = Toast .LENGTH_SHORT
60
- val toast = Toast .makeText(applicationContext , message, duration)
71
+ val duration = Toast .LENGTH_LONG
72
+ val toast = Toast .makeText(this @MainActivity , message, duration)
61
73
toast.show()
62
74
}
63
75
}
@@ -79,4 +91,100 @@ class MainActivity : AppCompatActivity() {
79
91
}
80
92
}
81
93
}
94
+
95
+ fun sendConfigPinned (view : View ) {
96
+ GlobalScope .launch(Dispatchers .IO ) {
97
+ onStart(R .id.config_pinned)
98
+ try {
99
+ // Untrusted in system store, trusted & pinned in network config:
100
+ val mURL = URL (" https://untrusted-root.badssl.com" )
101
+ with (mURL.openConnection() as HttpURLConnection ) {
102
+ println (" URL: ${this .url} " )
103
+ println (" Response Code: ${this .responseCode} " )
104
+ }
105
+
106
+ onSuccess(R .id.config_pinned)
107
+ } catch (e: Throwable ) {
108
+ println (e)
109
+ onError(R .id.config_pinned, e.toString())
110
+ }
111
+ }
112
+ }
113
+
114
+ fun sendOkHttpPinned (view : View ) {
115
+ GlobalScope .launch(Dispatchers .IO ) {
116
+ onStart(R .id.okhttp_pinned)
117
+
118
+ try {
119
+ val hostname = " badssl.com"
120
+ val certificatePinner = CertificatePinner .Builder ()
121
+ // DigiCert SHA2 Secure Server CA (valid until March 2023)
122
+ .add(hostname, " sha256/5kJvNEMw0KjrCAu7eXY5HZdvyCS13BbA0VJG1RSP91w=" )
123
+ .build()
124
+
125
+ val client = OkHttpClient .Builder ()
126
+ .certificatePinner(certificatePinner)
127
+ .build()
128
+ val request = Request .Builder ()
129
+ .url(" https://badssl.com" )
130
+ .build();
131
+
132
+ client.newCall(request).execute().use { response ->
133
+ println (" URL: ${request.url} " )
134
+ println (" Response Code: ${response.code} " )
135
+ }
136
+
137
+ onSuccess(R .id.okhttp_pinned)
138
+ } catch (e: Throwable ) {
139
+ println (e)
140
+ onError(R .id.okhttp_pinned, e.toString())
141
+ }
142
+ }
143
+ }
144
+
145
+ fun sendVolleyPinned (view : View ) {
146
+ onStart(R .id.volley_pinned)
147
+
148
+ try {
149
+ // Create an HTTP client that only trusts our specific certificate:
150
+ val cf = CertificateFactory .getInstance(" X.509" )
151
+ val caStream = BufferedInputStream (resources.openRawResource(R .raw.example_com_digicert_ca))
152
+ val ca = cf.generateCertificate(caStream)
153
+ caStream.close()
154
+
155
+ val keyStore = KeyStore .getInstance(KeyStore .getDefaultType())
156
+ keyStore.load(null , null )
157
+ keyStore.setCertificateEntry(" ca" , ca)
158
+
159
+ val trustManagerAlgorithm = TrustManagerFactory .getDefaultAlgorithm()
160
+ val trustManagerFactory = TrustManagerFactory .getInstance(trustManagerAlgorithm)
161
+ trustManagerFactory.init (keyStore)
162
+
163
+ val context = SSLContext .getInstance(" TLS" )
164
+ context.init (null , trustManagerFactory.trustManagers, null )
165
+
166
+ val requestQueue = Volley .newRequestQueue(this @MainActivity,
167
+ HurlStack (null , context.socketFactory)
168
+ )
169
+
170
+ // Make a request using that client:
171
+ val stringRequest = StringRequest (
172
+ com.android.volley.Request .Method .GET ,
173
+ " https://example.com" ,
174
+ { _ ->
175
+ println (" Volley success" )
176
+ this @MainActivity.onSuccess(R .id.volley_pinned)
177
+ },
178
+ {
179
+ println (it.toString())
180
+ this @MainActivity.onError(R .id.volley_pinned, it.toString())
181
+ }
182
+ )
183
+
184
+ requestQueue.add(stringRequest)
185
+ } catch (e: Throwable ) {
186
+ println (e)
187
+ onError(R .id.volley_pinned, e.toString())
188
+ }
189
+ }
82
190
}
0 commit comments