@@ -22,7 +22,6 @@ import com.android.keyattestation.verifier.provider.ProvisioningMethod
2222import com.android.keyattestation.verifier.provider.RevocationChecker
2323import com.google.errorprone.annotations.ThreadSafe
2424import com.google.protobuf.ByteString
25- import java.nio.ByteBuffer
2625import java.security.PublicKey
2726import java.security.Security
2827import java.security.cert.CertPathValidator
@@ -46,7 +45,7 @@ sealed interface VerificationResult {
4645
4746 data object ChallengeMismatch : VerificationResult
4847
49- data object PathValidationFailure : VerificationResult
48+ data class PathValidationFailure ( val cause : CertPathValidatorException ) : VerificationResult
5049
5150 data object ChainParsingFailure : VerificationResult
5251
@@ -73,26 +72,42 @@ open class Verifier(
7372 Security .addProvider(KeyAttestationProvider ())
7473 }
7574
76- fun verify (chain : List <X509Certificate >, challenge : ByteArray? = null): VerificationResult {
75+ /* *
76+ * Verifies an Android Key Attestation certificate chain.
77+ *
78+ * @param chain The attestation certificate chain to verify.
79+ * @param challengeChecker The challenge checker to use for additional challenge validation.
80+ * @return [VerificationResult]
81+ */
82+ @JvmOverloads
83+ fun verify (
84+ chain : List <X509Certificate >,
85+ challengeChecker : ChallengeChecker ? = null,
86+ ): VerificationResult {
7787 val certPath =
7888 try {
7989 KeyAttestationCertPath (chain)
8090 } catch (e: Exception ) {
8191 return VerificationResult .ChainParsingFailure
8292 }
83- return verify(certPath, challenge )
93+ return verify(certPath, challengeChecker )
8494 }
8595
8696 /* *
8797 * Verifies an Android Key Attestation certificate chain.
8898 *
8999 * @param chain The attestation certificate chain to verify.
100+ * @param challengeChecker The challenge checker to use for additional validation of the challenge
101+ * in the attestation chain.
90102 * @return [VerificationResult]
91103 *
92104 * TODO: b/366058500 - Make the challenge required after Apparat's changes are rollback safe.
93105 */
94106 @JvmOverloads
95- fun verify (certPath : KeyAttestationCertPath , challenge : ByteArray? = null): VerificationResult {
107+ fun verify (
108+ certPath : KeyAttestationCertPath ,
109+ challengeChecker : ChallengeChecker ? = null,
110+ ): VerificationResult {
96111 val certPathValidator = CertPathValidator .getInstance(" KeyAttestation" )
97112 val certPathParameters =
98113 PKIXParameters (trustAnchorsSource()).apply {
@@ -103,7 +118,7 @@ open class Verifier(
103118 try {
104119 certPathValidator.validate(certPath, certPathParameters) as PKIXCertPathValidatorResult
105120 } catch (e: CertPathValidatorException ) {
106- return VerificationResult .PathValidationFailure
121+ return VerificationResult .PathValidationFailure (e)
107122 }
108123
109124 val keyDescription =
@@ -114,8 +129,8 @@ open class Verifier(
114129 }
115130
116131 if (
117- challenge != null &&
118- keyDescription.attestationChallenge.asReadOnlyByteBuffer() != ByteBuffer .wrap(challenge )
132+ challengeChecker != null &&
133+ ! challengeChecker.checkChallenge(keyDescription.attestationChallenge )
119134 ) {
120135 return VerificationResult .ChallengeMismatch
121136 }
0 commit comments