<lambda>null1 package android.security.attestationverification
2
3 import android.app.Activity
4 import android.os.Bundle
5 import android.security.attestationverification.AttestationVerificationManager.PARAM_CHALLENGE
6 import android.security.attestationverification.AttestationVerificationManager.PARAM_PUBLIC_KEY
7 import android.security.attestationverification.AttestationVerificationManager.PROFILE_PEER_DEVICE
8 import android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE
9 import android.security.attestationverification.AttestationVerificationManager.TYPE_CHALLENGE
10 import android.security.attestationverification.AttestationVerificationManager.TYPE_PUBLIC_KEY
11 import android.security.attestationverification.AttestationVerificationManager.TYPE_UNKNOWN
12 import androidx.test.ext.junit.rules.ActivityScenarioRule
13 import androidx.test.ext.junit.runners.AndroidJUnit4
14 import androidx.test.filters.SmallTest
15 import androidx.test.platform.app.InstrumentationRegistry
16 import com.google.common.truth.Truth.assertThat
17 import org.junit.Before
18 import org.junit.Rule
19 import org.junit.Test
20 import org.junit.runner.RunWith
21 import java.io.ByteArrayOutputStream
22 import java.security.cert.CertificateFactory
23 import java.util.concurrent.CompletableFuture
24 import java.util.concurrent.TimeUnit
25
26 /** Test for system-defined attestation verifiers. */
27 @SmallTest
28 @RunWith(AndroidJUnit4::class)
29 class PeerDeviceSystemAttestationVerificationTest {
30
31 @get:Rule
32 val rule = ActivityScenarioRule(TestActivity::class.java)
33
34 private val certifcateFactory = CertificateFactory.getInstance("X.509")
35 private lateinit var activity: Activity
36 private lateinit var avm: AttestationVerificationManager
37 private lateinit var invalidAttestationByteArray: ByteArray
38
39 @Before
40 fun setup() {
41 rule.getScenario().onActivity {
42 avm = it.getSystemService(AttestationVerificationManager::class.java)!!
43 activity = it
44 }
45 invalidAttestationByteArray = TEST_ATTESTATION_CERT_FILENAME.fromPEMFileToByteArray()
46 }
47
48 @Test
49 fun verifyAttestation_returnsFailureWrongBindingType() {
50 val future = CompletableFuture<Int>()
51 val profile = AttestationProfile(PROFILE_PEER_DEVICE)
52 avm.verifyAttestation(profile, TYPE_UNKNOWN, Bundle(),
53 invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
54 future.complete(result)
55 }
56
57 assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
58 }
59
60 @Test
61 fun verifyAttestation_returnsFailureEmptyRequirements() {
62 val future = CompletableFuture<Int>()
63 val profile = AttestationProfile(PROFILE_PEER_DEVICE)
64 avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(),
65 invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
66 future.complete(result)
67 }
68
69 assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
70 }
71
72 @Test
73 fun verifyAttestation_returnsFailureMismatchBindingType() {
74 val future = CompletableFuture<Int>()
75 val profile = AttestationProfile(PROFILE_PEER_DEVICE)
76 val publicKeyRequirements = Bundle()
77 publicKeyRequirements.putByteArray(PARAM_PUBLIC_KEY, "publicKeyStr".encodeToByteArray())
78 avm.verifyAttestation(profile, TYPE_CHALLENGE, publicKeyRequirements,
79 invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
80 future.complete(result)
81 }
82
83 assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
84
85 val future2 = CompletableFuture<Int>()
86 val challengeRequirements = Bundle()
87 challengeRequirements.putByteArray(PARAM_CHALLENGE, "challengeStr".encodeToByteArray())
88 avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, challengeRequirements,
89 invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
90 future2.complete(result)
91 }
92
93 assertThat(future2.getSoon()).isEqualTo(RESULT_FAILURE)
94 }
95
96 @Test
97 fun verifyAttestation_returnsFailureWrongResourceKey() {
98 val future = CompletableFuture<Int>()
99 val profile = AttestationProfile(PROFILE_PEER_DEVICE)
100 val wrongKeyRequirements = Bundle()
101 wrongKeyRequirements.putByteArray("wrongReqKey", "publicKeyStr".encodeToByteArray())
102 avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, wrongKeyRequirements,
103 invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
104 future.complete(result)
105 }
106
107 assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
108 }
109
110 @Test
111 fun verifyAttestation_returnsFailureEmptyAttestation() {
112 val future = CompletableFuture<Int>()
113 val profile = AttestationProfile(PROFILE_PEER_DEVICE)
114 val requirements = Bundle()
115 requirements.putByteArray(PARAM_PUBLIC_KEY, "publicKeyStr".encodeToByteArray())
116 avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, requirements, ByteArray(0),
117 activity.mainExecutor) { result, _ ->
118 future.complete(result)
119 }
120
121 assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
122 }
123
124 @Test
125 fun verifyAttestation_returnsFailureTrustAnchorMismatch() {
126 val future = CompletableFuture<Int>()
127 val profile = AttestationProfile(PROFILE_PEER_DEVICE)
128 val challengeRequirements = Bundle()
129 challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray())
130 avm.verifyAttestation(profile, TYPE_CHALLENGE, challengeRequirements,
131 invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
132 future.complete(result)
133 }
134 assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
135 }
136
137 private fun <T> CompletableFuture<T>.getSoon(): T {
138 return this.get(1, TimeUnit.SECONDS)
139 }
140
141 private fun String.fromPEMFileToByteArray(): ByteArray {
142 val certs = certifcateFactory.generateCertificates(
143 InstrumentationRegistry.getInstrumentation().getContext().getResources().getAssets()
144 .open(this))
145 val bos = ByteArrayOutputStream()
146 certs.forEach {
147 bos.write(it.encoded)
148 }
149 return bos.toByteArray()
150 }
151
152 class TestActivity : Activity() {
153 override fun onCreate(savedInstanceState: Bundle?) {
154 super.onCreate(savedInstanceState)
155 }
156 }
157
158 companion object {
159 private const val TEST_ATTESTATION_CERT_FILENAME = "test_attestation_wrong_root_certs.pem"
160 }
161 }
162