Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/main/kotlin/provider/KeyAttestationCertPathValidator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,10 @@ private class BasicChecker(
BasicReason.NOT_YET_VALID,
)
} catch (e: CertificateExpiredException) {
// Ignore validity on factory-provisioned certificate chains because it is not possible to
// safely rotate the keys.
if (certPath.provisioningMethod() == ProvisioningMethod.FACTORY_PROVISIONED) return

throw CertPathValidatorException(
"Validity check failed",
e,
Expand Down
22 changes: 20 additions & 2 deletions src/main/kotlin/testing/Certs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,9 @@ object Chains {
)
}

/* A chain where the attestation certificate has expired. */
/* A factory-provisioned chain where the attestation certificate has expired. */
@JvmStatic
val expired by lazy {
val expiredFactoryProvisioned by lazy {
KeyAttestationCertPath(
certFactory.generateLeafCert(),
certFactory.generateAttestationCert(
Expand All @@ -495,6 +495,24 @@ object Chains {
)
}

/* A remotely-provisioned chain where the attestation certificate has expired. */
@JvmStatic
val expiredRemotelyProvisioned by lazy {
val rkpAttestationCert =
certFactory.generateRkpAttestationCert(
serialNumber = BigInteger.valueOf(0x1234567890),
notBefore = fakeCalendar.lastWeek(),
notAfter = fakeCalendar.lastWeek(),
)
KeyAttestationCertPath(
certFactory.generateLeafCert(issuer = rkpAttestationCert.subject),
rkpAttestationCert,
certFactory.rkpIntermediate,
Certs.remoteIntermediate,
certFactory.root,
)
}

/* A chain where the leaf certificate has expired. This will pass. */
val expiredLeaf by lazy {
KeyAttestationCertPath(
Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/testing/KeyAttestationCertFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,16 @@ internal class KeyAttestationCertFactory(val fakeCalendar: FakeCalendar = FakeCa
internal fun generateRkpAttestationCert(
securityLevel: SecurityLevel = SecurityLevel.TRUSTED_ENVIRONMENT,
serialNumber: BigInteger,
notBefore: Date = fakeCalendar.lastWeek(),
notAfter: Date = fakeCalendar.nextWeek(),
) =
generateAttestationCert(
signingKey = rkpKey.private,
subject = rkpAttestationName(securityLevel, serialNumber),
issuer = rkpIntermediate.subject,
serialNumber,
notBefore,
notAfter,
extraExtension =
Extension(
ProvisioningInfoMap.OID,
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/testing/X509CertificateExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ import org.bouncycastle.cert.jcajce.JcaX500NameUtil

private fun X500Principal.asX500Name() = JcaX500NameUtil.getX500Name(this)

internal val X509Certificate.subject: X500Name
val X509Certificate.subject: X500Name
get() = subjectX500Principal.asX500Name()
40 changes: 36 additions & 4 deletions src/test/kotlin/provider/KeyAttestationCertPathValidatorTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.android.keyattestation.verifier.testing.Certs.rootAnchor as testAncho
import com.android.keyattestation.verifier.testing.Chains
import com.android.keyattestation.verifier.testing.FakeCalendar
import com.android.keyattestation.verifier.testing.TestUtils.prodAnchors
import com.android.keyattestation.verifier.testing.TestUtils.readCertPath
import com.google.common.truth.Truth.assertThat
import java.security.InvalidAlgorithmParameterException
import java.security.Security
Expand All @@ -34,6 +35,8 @@ import java.security.cert.PKIXCertPathChecker
import java.security.cert.PKIXCertPathValidatorResult
import java.security.cert.PKIXParameters
import java.security.cert.PKIXReason
import java.security.cert.TrustAnchor
import java.time.LocalDate
import kotlin.test.assertFailsWith
import org.junit.BeforeClass
import org.junit.Test
Expand Down Expand Up @@ -84,14 +87,14 @@ class KeyAttestationCertPathValidatorTest {
val exception =
assertFailsWith<CertPathValidatorException> {
certPathValidator.validate(
Chains.validFactoryProvisioned,
Chains.validRemotelyProvisioned,
PKIXParameters(setOf(testAnchor)),
)
}
val pkixException =
assertFailsWith<CertPathValidatorException> {
pkixCertPathValidator.validate(
Chains.validFactoryProvisioned,
Chains.validRemotelyProvisioned,
PKIXParameters(setOf(testAnchor)),
)
}
Expand Down Expand Up @@ -205,15 +208,44 @@ class KeyAttestationCertPathValidatorTest {
}

@Test
fun expired_throwsCertPathValidatorException() {
val certPath = Chains.expired
fun expiredFactory_succeeds() {
certPathValidator.validate(Chains.expiredFactoryProvisioned, testParams)
}

@Test
fun expiredRkp_throwsCertPathValidatorException() {
val certPath = Chains.expiredRemotelyProvisioned
val exception =
assertFailsWith<CertPathValidatorException> {
certPathValidator.validate(certPath, testParams)
}
assertThat(exception.reason).isEqualTo(BasicReason.EXPIRED)
}

@Test
fun bluelineSdk28_factoryProvisioned_expiryIgnored() {
val certPath = readCertPath("blueline/sdk28/TEE_EC_NONE.pem")
val root = certPath.certificatesWithAnchor.last()
val params =
PKIXParameters(setOf(TrustAnchor(root, null))).apply {
date = FakeCalendar(LocalDate.of(2030, 1, 1)).today()
}
certPathValidator.validate(certPath, params)
}

@Test
fun caimanSdk36_remoteProvisioned_expiryHonored() {
val certPath = readCertPath("caiman/sdk36/TEE_EC_RKP.pem")
val root = certPath.certificatesWithAnchor.last()
val params =
PKIXParameters(setOf(TrustAnchor(root, null))).apply {
date = FakeCalendar(LocalDate.of(2030, 1, 1)).today()
}
val exception =
assertFailsWith<CertPathValidatorException> { certPathValidator.validate(certPath, params) }
assertThat(exception.reason).isEqualTo(BasicReason.EXPIRED)
}

@Test
fun forgedKeybox_throwsCertPathValidatorException() {
val certPath = Chains.forgedKeybox
Expand Down
Loading