Set correct certificate KeyUsage based on KeyPurpose (#119)
The previous implementation hardcoded the X.509 KeyUsage extension to `keyCertSign` for all generated certificates. This was only correct for keys with the `ATTEST_KEY` purpose and violated the Android HAL specification for keys intended for other uses. For instance, a key created for signing (`KeyPurpose::SIGN`) requires the `digitalSignature` bit to be set, not `keyCertSign`. This commit corrects the logic by dynamically constructing the `KeyUsage` bitmask from the key's specified purposes, adhering to the mapping defined in `KeyCreationResult.aidl`. This ensures that generated certificates now have the correct KeyUsage bits, accurately reflecting the key's intended function (e.g., signing, decryption, key wrapping) and making them compliant with the specification.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package org.matrix.TEESimulator.pki
|
package org.matrix.TEESimulator.pki
|
||||||
|
|
||||||
import android.hardware.security.keymint.Algorithm
|
import android.hardware.security.keymint.Algorithm
|
||||||
|
import android.hardware.security.keymint.KeyPurpose
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Pair
|
import android.util.Pair
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
@@ -187,6 +188,22 @@ object CertificateGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Maps KeyPurpose values to X.509 KeyUsage bits per KeyCreationResult.aidl spec */
|
||||||
|
private fun buildKeyUsageFromPurposes(purposes: List<Int>): Int {
|
||||||
|
var bits = 0
|
||||||
|
for (purpose in purposes) {
|
||||||
|
bits = bits or when (purpose) {
|
||||||
|
KeyPurpose.SIGN -> KeyUsage.digitalSignature
|
||||||
|
KeyPurpose.DECRYPT -> KeyUsage.dataEncipherment
|
||||||
|
KeyPurpose.WRAP_KEY -> KeyUsage.keyEncipherment
|
||||||
|
KeyPurpose.AGREE_KEY -> KeyUsage.keyAgreement
|
||||||
|
KeyPurpose.ATTEST_KEY -> KeyUsage.keyCertSign
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bits
|
||||||
|
}
|
||||||
|
|
||||||
/** Constructs a new X.509 certificate with a simulated attestation extension. */
|
/** Constructs a new X.509 certificate with a simulated attestation extension. */
|
||||||
private fun buildCertificate(
|
private fun buildCertificate(
|
||||||
subjectKeyPair: KeyPair,
|
subjectKeyPair: KeyPair,
|
||||||
@@ -211,8 +228,11 @@ object CertificateGenerator {
|
|||||||
subjectKeyPair.public,
|
subjectKeyPair.public,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Add standard extensions.
|
// Add KeyUsage extension only if purposes map to valid bits
|
||||||
builder.addExtension(Extension.keyUsage, true, KeyUsage(KeyUsage.keyCertSign))
|
val keyUsageBits = buildKeyUsageFromPurposes(params.purpose)
|
||||||
|
if (keyUsageBits != 0) {
|
||||||
|
builder.addExtension(Extension.keyUsage, true, KeyUsage(keyUsageBits))
|
||||||
|
}
|
||||||
// Add our custom, simulated attestation extension.
|
// Add our custom, simulated attestation extension.
|
||||||
builder.addExtension(
|
builder.addExtension(
|
||||||
AttestationBuilder.buildAttestationExtension(params, uid, securityLevel)
|
AttestationBuilder.buildAttestationExtension(params, uid, securityLevel)
|
||||||
|
|||||||
Reference in New Issue
Block a user