Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions src/main/kotlin/Verifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,22 @@ interface VerifyRequestLog {
*
* @param inputChain The certificate chain which is being verified.
*/
fun logInputChain(inputChain: List<ByteString>)
fun logInputChain(inputChain: List<ByteString>) {}

/**
* Logs the result of the verification. Called for each call to [verify].
*
* @param result The result of the verification.
*/
fun logResult(result: VerificationResult)
fun logResult(result: VerificationResult) {}

/**
* Logs the key description of the leaf certificate. Called if [verify] reaches the point where
* the key description is parsed.
*
* @param keyDescription The key description of the leaf certificate.
*/
fun logKeyDescription(keyDescription: KeyDescription)
fun logKeyDescription(keyDescription: KeyDescription) {}

/**
* Logs the provisioning info map extension of the attestation certificate. Called if [verify]
Expand All @@ -107,7 +107,7 @@ interface VerifyRequestLog {
*
* @param provisioningInfoMap The provisioning info map extension of the leaf certificate.
*/
fun logProvisioningInfoMap(provisioningInfoMap: ProvisioningInfoMap)
fun logProvisioningInfoMap(provisioningInfoMap: ProvisioningInfoMap) {}

/**
* Logs the serial numbers of the intermediate certificates in the certificate chain. Called if
Expand All @@ -116,17 +116,25 @@ interface VerifyRequestLog {
* @param certSerialNumbers The serial numbers of the intermediate certificates in the certificate
* chain.
*/
fun logCertSerialNumbers(certSerialNumbers: List<String>)
fun logCertSerialNumbers(certSerialNumbers: List<String>) {}

/**
* Logs the certificate signing algorithms of the intermediate certificates in the certificate
* chain. Called if [verify] reaches the point where the certificate chain is validated.
*
* @param certSigningAlgorithms The certificate signing algorithms in the chain.
*/
fun logCertSigningAlgorithms(certSigningAlgorithms: Set<String>) {}

/**
* Logs an info level message. May be called throughout the verification process.
*
* @param infoMessage The info level message to log.
*/
fun logInfoMessage(infoMessage: String)
fun logInfoMessage(infoMessage: String) {}

/* Flushes any buffered logs. Called just before [verify] returns. */
fun flush()
fun flush() {}
}

/**
Expand Down Expand Up @@ -267,6 +275,8 @@ constructor(
return VerificationResult.PathValidationFailure(e)
}

log?.logCertSigningAlgorithms(certPath.signingAlgorithms())

val keyDescription =
try {
checkNotNull(
Expand Down
26 changes: 26 additions & 0 deletions src/main/kotlin/provider/KeyAttestationCertPath.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ package com.android.keyattestation.verifier.provider
import com.android.keyattestation.verifier.SecurityLevel
import com.android.keyattestation.verifier.asX509Certificate
import com.google.protobuf.ByteString
import java.security.PublicKey
import java.security.cert.CertPath
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.security.interfaces.DSAPublicKey
import java.security.interfaces.ECPublicKey
import java.security.interfaces.RSAPublicKey
import javax.crypto.interfaces.DHPublicKey
import javax.security.auth.x500.X500Principal

/**
Expand Down Expand Up @@ -72,6 +77,18 @@ class KeyAttestationCertPath(certs: List<X509Certificate>) : CertPath("X.509") {
*/
fun serialNumbers() = certificatesWithAnchor.map { it.serialNumber.toString(16) }

/**
* Returns the signing algorithms of the certificates in the certificate chain.
*
* The format is "algNameKeySizeN".
*
* @return the signing algorithms of the certificates in the certificate chain.
*/
fun signingAlgorithms() =
certificatesWithAnchor
.zipWithNext { cert, issuer -> "${cert.sigAlgName}KeySize${issuer.publicKey.keySize()}" }
.toSet()

fun provisioningMethod() =
when {
isFactoryProvisioned() -> ProvisioningMethod.FACTORY_PROVISIONED
Expand Down Expand Up @@ -152,6 +169,15 @@ private fun parseDN(dn: String): Map<String, String> {
return attributes
}

private fun PublicKey.keySize() =
when (this) {
is RSAPublicKey -> this.modulus.bitLength().toString()
is ECPublicKey -> this.params.curve.field.fieldSize.toString()
is DSAPublicKey -> this.y.bitLength().toString()
is DHPublicKey -> this.y.bitLength().toString()
else -> "unknown"
}

private fun String?.toSecurityLevel() =
when (this) {
"TEE" -> SecurityLevel.TRUSTED_ENVIRONMENT
Expand Down
5 changes: 5 additions & 0 deletions src/main/kotlin/testing/FakeLogHook.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class FakeVerifyRequestLog : VerifyRequestLog {
var provisioningInfoMap: ProvisioningInfoMap? = null
var certSerialNumbers = mutableListOf<String>()
var infoMessages = mutableListOf<String>()
var certSigningAlgorithms = mutableSetOf<String>()

override fun logInputChain(inputChain: List<ByteString>) {
this.inputChain.addAll(inputChain)
Expand All @@ -72,6 +73,10 @@ class FakeVerifyRequestLog : VerifyRequestLog {
this.certSerialNumbers.addAll(certSerialNumbers)
}

override fun logCertSigningAlgorithms(certSigningAlgorithms: Set<String>) {
this.certSigningAlgorithms.addAll(certSigningAlgorithms)
}

override fun logInfoMessage(infoMessage: String) {
this.infoMessages.add(infoMessage)
}
Expand Down
10 changes: 10 additions & 0 deletions src/test/kotlin/provider/KeyAttestationCertPathTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ class KeyAttestationCertPathTest {
.inOrder()
}

@Test
fun signingAlgorithms_returnsExpectedSigningAlgorithms() {
assertThat(readCertPath("blueline/sdk28/TEE_EC_NONE.pem").signingAlgorithms())
.containsExactly(
"SHA256withECDSAKeySize256",
"SHA256withECDSAKeySize384",
"SHA256withRSAKeySize4096",
)
}

@Test
fun provisioningMethod_returnsExpectedType(@TestParameter testCase: ProvisioningMethodTestCase) {
val certPath = readCertPath("${testCase.path}.pem")
Expand Down
Loading