Welcome to mirror list, hosted at ThFree Co, Russian Federation.

CustomCertManagerTest.kt « cert4android « bitfire « at « java « androidTest « src - github.com/bitfireAT/cert4android.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b395d4881bb78fdf5f434660a6667eaffd4d7359 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/***************************************************************************************************
 * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
 **************************************************************************************************/

package at.bitfire.cert4android

import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.rule.ServiceTestRule
import org.junit.After
import org.junit.Assert.assertNotNull
import org.junit.Assume.assumeNotNull
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import java.io.IOException
import java.net.URL
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import javax.net.ssl.HttpsURLConnection

class CustomCertManagerTest {

    companion object {
        private fun getSiteCertificates(url: URL): List<X509Certificate> {
            val conn = url.openConnection() as HttpsURLConnection
            try {
                conn.inputStream.read()
                val certs = mutableListOf<X509Certificate>()
                conn.serverCertificates.forEach { certs += it as X509Certificate }
                return certs
            } finally {
                conn.disconnect()
            }
        }
    }

    lateinit var certManager: CustomCertManager
    lateinit var paranoidCertManager: CustomCertManager

    init {
        CustomCertManager.SERVICE_TIMEOUT = 1000
    }

    @JvmField
    @Rule
    val serviceTestRule = ServiceTestRule()

    var siteCerts: List<X509Certificate>? = null
    init {
        try {
            siteCerts = getSiteCertificates(URL("https://www.davdroid.com"))
        } catch(e: IOException) {
        }
        assumeNotNull(siteCerts)
    }


    @Before
    fun initCertManager() {
        // prepare a bound and ready service for testing
        // loop required because of https://code.google.com/p/android/issues/detail?id=180396
        val binder = bindService(CustomCertService::class.java)
        assertNotNull(binder)

        val context = getInstrumentation().context
        CustomCertManager.resetCertificates(context)

        certManager = CustomCertManager(context, false)
        assertNotNull(certManager)

        paranoidCertManager = CustomCertManager(context, false, false)
        assertNotNull(paranoidCertManager)
    }

    @After
    fun closeCertManager() {
        paranoidCertManager.close()
        certManager.close()
    }


    @Test(expected = CertificateException::class)
    fun testCheckClientCertificate() {
        certManager.checkClientTrusted(null, null)
    }

    @Test
    fun testTrustedCertificate() {
        certManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA")
    }

    @Test(expected = CertificateException::class)
    fun testParanoidCertificate() {
        paranoidCertManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA")
    }

    @Test
    fun testAddCustomCertificate() {
        addCustomCertificate()
        paranoidCertManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA")
    }

    // fails randomly for unknown reason:
    @Test(expected = CertificateException::class)
    fun testRemoveCustomCertificate() {
        addCustomCertificate()

        // remove certificate and check again
        // should now be rejected for the whole session, i.e. no timeout anymore
        val intent = Intent(getInstrumentation().context, CustomCertService::class.java)
        intent.action = CustomCertService.CMD_CERTIFICATION_DECISION
        intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts!!.first().encoded)
        intent.putExtra(CustomCertService.EXTRA_TRUSTED, false)
        startService(intent, CustomCertService::class.java)
        paranoidCertManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA")
    }

    private fun addCustomCertificate() {
        // add certificate and check again
        val intent = Intent(getInstrumentation().context, CustomCertService::class.java)
        intent.action = CustomCertService.CMD_CERTIFICATION_DECISION
        intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts!!.first().encoded)
        intent.putExtra(CustomCertService.EXTRA_TRUSTED, true)
        startService(intent, CustomCertService::class.java)
    }


    private fun bindService(clazz: Class<out Service>): IBinder {
        var binder = serviceTestRule.bindService(Intent(getInstrumentation().targetContext, clazz))
        var it = 0
        while (binder == null && it++ <100) {
            binder = serviceTestRule.bindService(Intent(getInstrumentation().targetContext, clazz))
            System.err.println("Waiting for ServiceTestRule.bindService")
            Thread.sleep(50)
        }
        if (binder == null)
            throw IllegalStateException("Couldn't bind to service")
        return binder
    }

    private fun startService(intent: Intent, clazz: Class<out Service>) {
        serviceTestRule.startService(intent)
        bindService(clazz)
    }

}