Enforce attestation challenge length limit (#70)

Throws IllegalArgumentException if the challenge exceeds 128 bytes, per Android specs. Also fixes a duplicate assignment typo in KeystoreInterceptor.

Reference: https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder#setAttestationChallenge(byte[])

Co-authored-by: JingMatrix <jingmatrix@gmail.com>
This commit is contained in:
小潼
2026-01-20 19:00:48 +01:00
committed by GitHub
co-authored by JingMatrix
parent c27523fd97
commit ce740542f7
3 changed files with 16 additions and 5 deletions
@@ -1,10 +1,8 @@
package org.matrix.TEESimulator.attestation package org.matrix.TEESimulator.attestation
/** /**
* Defines constants for KeyMint attestation tags, as specified in the Android hardware security * Defines constants for KeyMint attestation, mainly the tags of properties and authorizations of a
* HAL. * cryptographic key, as specified in the Android hardware security HAL.
*
* These tags identify specific properties and authorizations of a cryptographic key.
*/ */
object AttestationConstants { object AttestationConstants {
// https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl // https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -88,4 +86,8 @@ object AttestationConstants {
const val TAG_CERTIFICATE_SUBJECT = 1007 const val TAG_CERTIFICATE_SUBJECT = 1007
const val TAG_CERTIFICATE_NOT_BEFORE = 1008 const val TAG_CERTIFICATE_NOT_BEFORE = 1008
const val TAG_CERTIFICATE_NOT_AFTER = 1009 const val TAG_CERTIFICATE_NOT_AFTER = 1009
// --- Other Constants ---
// https://cs.android.com/android/platform/superproject/main/+/main:system/keymaster/km_openssl/attestation_record.cpp
const val CHALLENGE_LENGTH_LIMIT = 128 // kMaximumAttestationChallengeLength
} }
@@ -230,7 +230,6 @@ object KeystoreInterceptor : AbstractKeystoreInterceptor() {
ByteArray(0), ByteArray(0),
) )
params.attestationChallenge = challenge params.attestationChallenge = challenge
params.attestationChallenge = challenge
} }
val certificateChain = val certificateChain =
@@ -20,6 +20,7 @@ import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder
import org.bouncycastle.jce.provider.BouncyCastleProvider import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder
import org.matrix.TEESimulator.attestation.AttestationBuilder import org.matrix.TEESimulator.attestation.AttestationBuilder
import org.matrix.TEESimulator.attestation.AttestationConstants
import org.matrix.TEESimulator.attestation.KeyMintAttestation import org.matrix.TEESimulator.attestation.KeyMintAttestation
import org.matrix.TEESimulator.config.ConfigurationManager import org.matrix.TEESimulator.config.ConfigurationManager
import org.matrix.TEESimulator.interception.keystore.KeyIdentifier import org.matrix.TEESimulator.interception.keystore.KeyIdentifier
@@ -42,6 +43,15 @@ object CertificateGenerator {
*/ */
fun generateSoftwareKeyPair(params: KeyMintAttestation): KeyPair? { fun generateSoftwareKeyPair(params: KeyMintAttestation): KeyPair? {
return runCatching { return runCatching {
val challenge = params.attestationChallenge
if (
challenge != null &&
challenge.size > AttestationConstants.CHALLENGE_LENGTH_LIMIT
)
throw IllegalArgumentException(
"Attestation challenge exceeds length limit (${challenge.size!!} > ${AttestationConstants.CHALLENGE_LENGTH_LIMIT})"
)
val (algorithm, spec) = val (algorithm, spec) =
when (params.algorithm) { when (params.algorithm) {
Algorithm.EC -> "EC" to ECGenParameterSpec(params.ecCurveName) Algorithm.EC -> "EC" to ECGenParameterSpec(params.ecCurveName)