feat(intercept): resolve KEY_ID via teeResponses

PR #22's KEY_ID lookup at Keystore2Interceptor.onPreTransact only
scanned generatedKeys, which is populated exclusively by
doSoftwareKeyGen (GENERATE mode and the attest-key override path).
For AUTO packages on TEE-good devices the real TEE handles
generateKey and the response lands in teeResponses via the existing
GENERATE_KEY_TRANSACTION post-hook, so getKeyEntry(KEY_ID) by
TimingSideChannelProbe missed and the call leaked SSE.

Add findTeeResponseByKeyId companion helper that mirrors
findGeneratedKeyByKeyId's shape but scans teeResponses keyed by
response.metadata.key.nspace. Wire it as a fallback after the
existing PR #22 lookup. Behavior unchanged for GENERATE packages.
This commit is contained in:
Enginex0
2026-05-19 17:45:54 +01:00
parent c46aaa34f8
commit b323f41b08
2 changed files with 17 additions and 0 deletions
@@ -237,6 +237,15 @@ object Keystore2Interceptor : AbstractKeystoreInterceptor() {
) )
return InterceptorUtils.createTypedObjectReply(info.response) return InterceptorUtils.createTypedObjectReply(info.response)
} }
val teeResp = KeyMintSecurityLevelInterceptor.findTeeResponseByKeyId(
callingUid, descriptor.nspace
)
if (teeResp != null) {
SystemLogger.info(
"[TX_ID: $txId] Found TEE response via KEY_ID nspace=${descriptor.nspace}"
)
return InterceptorUtils.createTypedObjectReply(teeResp)
}
} }
return TransactionResult.ContinueAndSkipPost return TransactionResult.ContinueAndSkipPost
} }
@@ -1244,6 +1244,14 @@ class KeyMintSecurityLevelInterceptor(
?.value ?.value
} }
fun findTeeResponseByKeyId(callingUid: Int, nspace: Long?): KeyEntryResponse? {
if (nspace == null || nspace == 0L) return null
return teeResponses.entries
.filter { (keyId, _) -> keyId.uid == callingUid }
.find { (_, response) -> response.metadata?.key?.nspace == nspace }
?.value
}
fun getPatchedChain(keyId: KeyIdentifier): Array<Certificate>? = patchedChains[keyId] fun getPatchedChain(keyId: KeyIdentifier): Array<Certificate>? = patchedChains[keyId]
fun isAttestationKey(keyId: KeyIdentifier): Boolean = attestationKeys.contains(keyId) fun isAttestationKey(keyId: KeyIdentifier): Boolean = attestationKeys.contains(keyId)