refactor(persistence): remove dead rePersistIfNeeded and helper
Software keys receive their final cert chain at generation time and never go through onPostTransact patching, so re-persisting after patching is unreachable in PR 157's architecture.
This commit is contained in:
+1
-117
@@ -16,7 +16,7 @@ import java.util.concurrent.locks.ReentrantLock
|
|||||||
import org.matrix.TEESimulator.config.ConfigurationManager.CONFIG_PATH
|
import org.matrix.TEESimulator.config.ConfigurationManager.CONFIG_PATH
|
||||||
import org.matrix.TEESimulator.interception.keystore.KeyIdentifier
|
import org.matrix.TEESimulator.interception.keystore.KeyIdentifier
|
||||||
import org.matrix.TEESimulator.logging.SystemLogger
|
import org.matrix.TEESimulator.logging.SystemLogger
|
||||||
import org.matrix.TEESimulator.pki.CertificateHelper
|
|
||||||
|
|
||||||
data class PersistedKeyData(
|
data class PersistedKeyData(
|
||||||
val uid: Int,
|
val uid: Int,
|
||||||
@@ -250,77 +250,6 @@ object GeneratedKeyPersistence {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-persist updates the cert chain for an already-persisted key without
|
|
||||||
// reconstructing authorization parameters from the response. This avoids
|
|
||||||
// pulling keymint Tag dependencies into this file and is correct because
|
|
||||||
// the only field that changes post-generation is the patched cert chain.
|
|
||||||
fun rePersistIfNeeded(
|
|
||||||
callingUid: Int,
|
|
||||||
generatedKeyInfo: KeyMintSecurityLevelInterceptor.GeneratedKeyInfo,
|
|
||||||
) {
|
|
||||||
val metadata = generatedKeyInfo.response.metadata
|
|
||||||
if (metadata == null) {
|
|
||||||
SystemLogger.debug("rePersist: no metadata, skipping")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val secLevel = metadata.keySecurityLevel
|
|
||||||
|
|
||||||
val entry = KeyMintSecurityLevelInterceptor.generatedKeys.entries.find { (id, info) ->
|
|
||||||
id.uid == callingUid && info.nspace == generatedKeyInfo.nspace
|
|
||||||
}
|
|
||||||
if (entry == null) {
|
|
||||||
SystemLogger.debug("rePersist: key not found in map for uid=$callingUid nspace=${generatedKeyInfo.nspace}")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val keyId = entry.key
|
|
||||||
val filename = keyFileName(keyId.uid, keyId.alias)
|
|
||||||
val existing = File(PERSISTENCE_DIR, filename)
|
|
||||||
|
|
||||||
if (!existing.exists()) {
|
|
||||||
SystemLogger.debug("rePersist: no existing file for $keyId, skipping")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val newChain = CertificateHelper.getCertificateChain(metadata)
|
|
||||||
if (newChain == null) {
|
|
||||||
SystemLogger.warning("rePersist: could not extract cert chain for $keyId")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val persisted = runCatching {
|
|
||||||
DataInputStream(BufferedInputStream(FileInputStream(existing))).use { input ->
|
|
||||||
val version = input.readInt()
|
|
||||||
if (version != FORMAT_VERSION) {
|
|
||||||
SystemLogger.warning("rePersist: unknown format version $version for $keyId")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
readPersistedKeyData(input)
|
|
||||||
}
|
|
||||||
}.getOrNull()
|
|
||||||
if (persisted == null) {
|
|
||||||
SystemLogger.warning("rePersist: failed to read existing data for $keyId")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val keyPair = generatedKeyInfo.keyPair ?: return
|
|
||||||
save(
|
|
||||||
keyId = keyId,
|
|
||||||
keyPair = keyPair,
|
|
||||||
nspace = generatedKeyInfo.nspace,
|
|
||||||
securityLevel = secLevel,
|
|
||||||
certChain = newChain.toList(),
|
|
||||||
algorithm = persisted.algorithm,
|
|
||||||
keySize = persisted.keySize,
|
|
||||||
ecCurve = persisted.ecCurve,
|
|
||||||
purposes = persisted.purposes,
|
|
||||||
digests = persisted.digests,
|
|
||||||
isAttestationKey = persisted.isAttestationKey,
|
|
||||||
)
|
|
||||||
SystemLogger.debug("Re-persisted key $keyId with updated cert chain")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Corrupted binary files can have arbitrary length fields — cap allocations
|
|
||||||
private fun requireBounds(value: Int, max: Int, name: String): Int {
|
private fun requireBounds(value: Int, max: Int, name: String): Int {
|
||||||
require(value in 0..max) { "$name out of bounds: $value (max $max)" }
|
require(value in 0..max) { "$name out of bounds: $value (max $max)" }
|
||||||
return value
|
return value
|
||||||
@@ -331,49 +260,4 @@ object GeneratedKeyPersistence {
|
|||||||
.digest("$uid:$alias".toByteArray(Charsets.UTF_8))
|
.digest("$uid:$alias".toByteArray(Charsets.UTF_8))
|
||||||
return digest.joinToString("") { "%02x".format(it) } + ".bin"
|
return digest.joinToString("") { "%02x".format(it) } + ".bin"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads all fields after version has already been consumed
|
|
||||||
private fun readPersistedKeyData(input: DataInputStream): PersistedKeyData {
|
|
||||||
val secLevel = input.readInt()
|
|
||||||
val uid = input.readInt()
|
|
||||||
val alias = input.readUTF()
|
|
||||||
val nspace = input.readLong()
|
|
||||||
val isAttestKey = input.readBoolean()
|
|
||||||
val algo = input.readInt()
|
|
||||||
val kSize = input.readInt()
|
|
||||||
val curve = input.readInt()
|
|
||||||
|
|
||||||
val purposeCount = requireBounds(input.readInt(), 64, "purposeCount")
|
|
||||||
val purposes = (0 until purposeCount).map { input.readInt() }
|
|
||||||
|
|
||||||
val digestCount = requireBounds(input.readInt(), 64, "digestCount")
|
|
||||||
val digests = (0 until digestCount).map { input.readInt() }
|
|
||||||
|
|
||||||
val pkLen = requireBounds(input.readInt(), 8192, "pkLen")
|
|
||||||
val pkBytes = ByteArray(pkLen)
|
|
||||||
input.readFully(pkBytes)
|
|
||||||
|
|
||||||
val certCount = requireBounds(input.readInt(), 10, "certCount")
|
|
||||||
val certChainBytes = (0 until certCount).map {
|
|
||||||
val certLen = requireBounds(input.readInt(), 65536, "certLen")
|
|
||||||
val certBytes = ByteArray(certLen)
|
|
||||||
input.readFully(certBytes)
|
|
||||||
certBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
return PersistedKeyData(
|
|
||||||
uid = uid,
|
|
||||||
alias = alias,
|
|
||||||
nspace = nspace,
|
|
||||||
securityLevel = secLevel,
|
|
||||||
isAttestationKey = isAttestKey,
|
|
||||||
algorithm = algo,
|
|
||||||
keySize = kSize,
|
|
||||||
ecCurve = curve,
|
|
||||||
purposes = purposes,
|
|
||||||
digests = digests,
|
|
||||||
privateKeyBytes = pkBytes,
|
|
||||||
certChainBytes = certChainBytes,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user