Skip to content

Commit af4fb40

Browse files
authored
Merge pull request #14 from android/test_788084424
Allow multiple key attestation roots
2 parents 1e0e9fe + b13a77f commit af4fb40

File tree

4 files changed

+22
-25
lines changed

4 files changed

+22
-25
lines changed

roots.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[
2+
"-----BEGIN CERTIFICATE-----\nMIIFHDCCAwSgAwIBAgIJAPHBcqaZ6vUdMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\nBAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMjIwMzIwMTgwNzQ4WhcNNDIwMzE1MTgw\nNzQ4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS\nSxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7\ntv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj\nnar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq\nC4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ\noVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O\nJtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg\nsTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi\nigHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M\nRPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E\naDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um\nAGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud\nIwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD\nVR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQB8cMqTllHc8U+qCrOlg3H7\n174lmaCsbo/bJ0C17JEgMLb4kvrqsXZs01U3mB/qABg/1t5Pd5AORHARs1hhqGIC\nW/nKMav574f9rZN4PC2ZlufGXb7sIdJpGiO9ctRhiLuYuly10JccUZGEHpHSYM2G\ntkgYbZba6lsCPYAAP83cyDV+1aOkTf1RCp/lM0PKvmxYN10RYsK631jrleGdcdkx\noSK//mSQbgcWnmAEZrzHoF1/0gso1HZgIn0YLzVhLSA/iXCX4QT2h3J5z3znluKG\n1nv8NQdxei2DIIhASWfu804CA96cQKTTlaae2fweqXjdN1/v2nqOhngNyz1361mF\nmr4XmaKH/ItTwOe72NI9ZcwS1lVaCvsIkTDCEXdm9rCNPAY10iTunIHFXRh+7KPz\nlHGewCq/8TOohBRn0/NNfh7uRslOSZ/xKbN9tMBtw37Z8d2vvnXq/YWdsm1+JLVw\nn6yYD/yacNJBlwpddla8eaVMjsF6nBnIgQOf9zKSe06nSTqvgwUHosgOECZJZ1Eu\nzbH4yswbt02tKtKEFhx+v+OTge/06V+jGsqTWLsfrOCNLuA8H++z+pUENmpqnnHo\nvaI47gC+TNpkgYGkkBT6B/m/U01BuOBBTzhIlMEZq9qkDWuM2cA5kW5V3FJUcfHn\nw1IdYIg2Wxg7yHcQZemFQg==\n-----END CERTIFICATE-----",
3+
"-----BEGIN CERTIFICATE-----\nMIICIjCCAaigAwIBAgIRAISp0Cl7DrWK5/8OgN52BgUwCgYIKoZIzj0EAwMwUjEc\nMBoGA1UEAwwTS2V5IEF0dGVzdGF0aW9uIENBMTEQMA4GA1UECwwHQW5kcm9pZDET\nMBEGA1UECgwKR29vZ2xlIExMQzELMAkGA1UEBhMCVVMwHhcNMjUwNzE3MjIzMjE4\nWhcNMzUwNzE1MjIzMjE4WjBSMRwwGgYDVQQDDBNLZXkgQXR0ZXN0YXRpb24gQ0Ex\nMRAwDgYDVQQLDAdBbmRyb2lkMRMwEQYDVQQKDApHb29nbGUgTExDMQswCQYDVQQG\nEwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABCPaI3FO3z5bBQo8cuiEas4HjqCt\nG/mLFfRT0MsIssPBEEU5Cfbt6sH5yOAxqEi5QagpU1yX4HwnGb7OtBYpDTB57uH5\nEczm34A5FNijV3s0/f0UPl7zbJcTx6xwqMIRq6NCMEAwDwYDVR0TAQH/BAUwAwEB\n/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFIyuyz7RkOb3NaBqQ5lZuA0QepA\nMAoGCCqGSM49BAMDA2gAMGUCMETfjPO/HwqReR2CS7p0ZWoD/LHs6hDi422opifH\nEUaYLxwGlT9SLdjkVpz0UUOR5wIxAIoGyxGKRHVTpqpGRFiJtQEOOTp/+s1GcxeY\nuR2zh/80lQyu9vAFCj6E4AXc+osmRg==\n-----END CERTIFICATE-----"
4+
]

src/main/kotlin/testing/TestUtils.kt

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
3838
import org.bouncycastle.openssl.PEMParser
3939

4040
object TestUtils {
41-
private const val PROD_ROOT_PATH =
42-
"googledata/html/external_content/android_googleapis_com/attestation/root"
43-
const val TESTDATA_PATH = "third_party/java/keyattestation/testdata"
41+
private const val PROD_ROOT_PATH = "roots.json"
42+
const val TESTDATA_PATH = "testdata"
4443

4544
fun readCertPath(subpath: String): KeyAttestationCertPath =
4645
readCertPath(readFile(Path(base = TESTDATA_PATH, /* subpaths...= */ subpath)))
@@ -60,14 +59,13 @@ object TestUtils {
6059
.let { KeyAttestationCertPath(it) }
6160
}
6261

63-
val prodRoot by lazy {
64-
val certs = Gson().fromJson(readFile(PROD_ROOT_PATH), Array<String>::class.java).toSet()
65-
check(certs.size == 1) { "Multiple certificates in the root file are not yet supported" }
66-
certs.first().asX509Certificate()
62+
val prodAnchors by lazy {
63+
Gson()
64+
.fromJson(readFile(PROD_ROOT_PATH), Array<String>::class.java)
65+
.map { TrustAnchor(it.asX509Certificate(), null) }
66+
.toSet()
6767
}
6868

69-
val prodAnchor = TrustAnchor(prodRoot, null)
70-
7169
private fun readFile(path: Path) = path.reader()
7270
private fun readFile(path: String) = path.reader()
7371
}

src/test/kotlin/VerifierTest.kt

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@
1717
package com.android.keyattestation.verifier
1818

1919
import com.android.keyattestation.verifier.testing.CertLists
20-
import com.android.keyattestation.verifier.testing.TestUtils.prodRoot
20+
import com.android.keyattestation.verifier.testing.TestUtils.prodAnchors
2121
import com.android.keyattestation.verifier.testing.TestUtils.readCertPath
2222
import com.google.common.truth.Truth.assertThat
2323
import com.google.protobuf.ByteString
24-
import java.security.cert.TrustAnchor
2524
import java.time.Instant
2625
import kotlin.test.assertIs
2726
import org.junit.Test
@@ -31,12 +30,7 @@ import org.junit.runners.JUnit4
3130
/** Unit tests for [Verifier]. */
3231
@RunWith(JUnit4::class)
3332
class VerifierTest {
34-
private val verifier =
35-
Verifier(
36-
{ setOf(TrustAnchor(prodRoot, /* nameConstraints= */ null)) },
37-
{ setOf<String>() },
38-
{ Instant.now() },
39-
)
33+
private val verifier = Verifier({ prodAnchors }, { setOf<String>() }, { Instant.now() })
4034

4135
@Test
4236
fun verify_validChain_returnsSuccess() {

src/test/kotlin/provider/KeyAttestationCertPathValidatorTest.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package com.android.keyattestation.verifier.provider
1919
import com.android.keyattestation.verifier.testing.Certs.rootAnchor as testAnchor
2020
import com.android.keyattestation.verifier.testing.Chains
2121
import com.android.keyattestation.verifier.testing.FakeCalendar
22-
import com.android.keyattestation.verifier.testing.TestUtils.prodAnchor
22+
import com.android.keyattestation.verifier.testing.TestUtils.prodAnchors
2323
import com.google.common.truth.Truth.assertThat
2424
import java.security.InvalidAlgorithmParameterException
2525
import java.security.Security
@@ -42,7 +42,7 @@ import org.junit.runners.JUnit4
4242
class KeyAttestationCertPathValidatorTest {
4343
private val certPathValidator = CertPathValidator.getInstance("KeyAttestation")
4444
private val pkixCertPathValidator = CertPathValidator.getInstance("PKIX")
45-
private val prodParams = PKIXParameters(setOf(prodAnchor))
45+
private val prodParams = PKIXParameters(prodAnchors)
4646
private val testParams =
4747
PKIXParameters(setOf(testAnchor)).apply { date = FakeCalendar.DEFAULT.today() }
4848

@@ -116,10 +116,10 @@ class KeyAttestationCertPathValidatorTest {
116116
}
117117

118118
@Test
119-
fun multipleAnchors_returnsSuccess() {
119+
fun additionalAnchors_returnsSuccess() {
120120
val certPath = Chains.validFactoryProvisioned
121-
val params =
122-
PKIXParameters(setOf(prodAnchor, testAnchor)).apply { date = FakeCalendar.DEFAULT.today() }
121+
val moreAnchors = prodAnchors.union(setOf(testAnchor))
122+
val params = PKIXParameters(moreAnchors).apply { date = FakeCalendar.DEFAULT.today() }
123123
val result = certPathValidator.validate(certPath, params) as PKIXCertPathValidatorResult
124124
assertThat(result.trustAnchor).isEqualTo(testAnchor)
125125
assertThat(result.policyTree).isNull()
@@ -136,7 +136,7 @@ class KeyAttestationCertPathValidatorTest {
136136
}
137137

138138
@Test
139-
fun wrongAnchor_throwsCertPathValidatorException() {
139+
fun multipleWrongAnchors_throwsCertPathValidatorException() {
140140
val certPath = Chains.validFactoryProvisioned
141141
val exception =
142142
assertFailsWith<CertPathValidatorException> {
@@ -146,14 +146,15 @@ class KeyAttestationCertPathValidatorTest {
146146
assertFailsWith<CertPathValidatorException> {
147147
pkixCertPathValidator.validate(certPath, prodParams)
148148
}
149+
assertThat(prodParams.trustAnchors.size).isAtLeast(2)
149150
assertThat(exception.reason).isEqualTo(PKIXReason.NO_TRUST_ANCHOR)
150151
assertThat(pkixException.reason).isEqualTo(PKIXReason.NO_TRUST_ANCHOR)
151152
}
152153

153154
@Test
154-
fun multipleWrongAnchors_throwsCertPathValidatorException() {
155+
fun singleWrongAnchor_throwsCertPathValidatorException() {
155156
val params =
156-
PKIXParameters(setOf(prodAnchor, prodAnchor)).apply { date = FakeCalendar.DEFAULT.today() }
157+
PKIXParameters(setOf(prodAnchors.first())).apply { date = FakeCalendar.DEFAULT.today() }
157158
val exception =
158159
assertFailsWith<CertPathValidatorException> {
159160
certPathValidator.validate(Chains.validFactoryProvisioned, params)

0 commit comments

Comments
 (0)