Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New ASN.1 parser/generator and migrate X509Cert and TrustManager. #826

Merged
merged 1 commit into from
Dec 23, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,14 @@ class TransferDocumentFragment : Fragment() {
}
val doc = viewModel.getSelectedDocuments().first { reqDoc.docType == it.docType }
if (reqDoc.readerAuth != null && reqDoc.readerAuthenticated) {
var certChain: List<X509Certificate> =
reqDoc.readerCertificateChain!!.certificates.map { it.javaX509Certificate }
.toList()
val customValidators = CustomValidators.getByDocType(doc.docType)
val result = HolderApp.trustManagerInstance.verify(
chain = certChain,
customValidators = customValidators
chain = reqDoc.readerCertificateChain!!.certificates,
)
trusted = result.isTrusted
if (result.trustChain.any()) {
certChain = result.trustChain
commonName = result.trustChain.last().issuer.name
}
commonName = certChain.last().issuerX500Principal.getCommonName("")

// Add some information about the reader certificate used
if (result.isTrusted) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.android.identity.crypto.Algorithm
import com.android.identity.crypto.Crypto
import com.android.identity.crypto.EcCurve
import com.android.identity.crypto.EcPublicKeyDoubleCoordinate
import com.android.identity.crypto.X509CertChain
import com.android.identity.crypto.javaPublicKey
import com.android.identity.crypto.javaX509Certificates
import com.android.identity.crypto.toEcPrivateKey
Expand Down Expand Up @@ -163,19 +164,19 @@ class ShowDeviceResponseFragment : Fragment() {
)
sb.append("<h3>Doctype: <font color=\"$color\">${doc.docType}</font></h3>")

var certChain = doc.issuerCertificateChain.javaX509Certificates
var certChain = doc.issuerCertificateChain
val customValidators = CustomValidators.getByDocType(doc.docType)
val result = VerifierApp.trustManagerInstance.verify(
chain = certChain,
customValidators = customValidators
chain = certChain.certificates,
//customValidators = customValidators
)
if (result.trustChain.any()){
certChain = result.trustChain
certChain = X509CertChain(result.trustChain)
}
if (!result.isTrusted) {
sb.append("${getFormattedCheck(false)}Error in certificate chain validation: ${result.error?.message}<br>")
}
val commonName = certChain.last().issuerX500Principal.getCommonName("")
val commonName = certChain.certificates.last().issuer.name
sb.append("${getFormattedCheck(result.isTrusted)}Issuer’s DS Key Recognized: ($commonName)<br>")
sb.append("${getFormattedCheck(doc.issuerSignedAuthenticated)}Issuer Signed Authenticated<br>")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.annotation.AttrRes
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.android.identity.cbor.Cbor
import com.android.identity.crypto.X509Cert
import com.android.identity.documenttype.DocumentAttributeType
import com.android.identity.documenttype.MdocDataElement
import com.android.identity.crypto.javaPublicKey
Expand Down Expand Up @@ -207,13 +208,12 @@ class ShowDocumentFragment : Fragment() {

for (doc in documents) {
sb.append("<h3>Doctype: <font color=\"$primaryColor\">${doc.docType}</font></h3>")
val cc = mutableListOf<X509Certificate>()
doc.issuerCertificateChain.certificates.forEach() { c -> cc.add(c.javaX509Certificate) }
var certChain: List<X509Certificate> = cc
val cc = doc.issuerCertificateChain.certificates
var certChain: List<X509Cert> = cc
val customValidators = CustomValidators.getByDocType(doc.docType)
val result = VerifierApp.trustManagerInstance.verify(
chain = certChain,
customValidators = customValidators
//customValidators = customValidators
)
if (result.trustChain.any()) {
certChain = result.trustChain
Expand All @@ -222,7 +222,7 @@ class ShowDocumentFragment : Fragment() {
sb.append("${getFormattedCheck(false)}Error in certificate chain validation: ${result.error?.message}<br>")
}

val commonName = certChain.last().issuerX500Principal.getCommonName("")
val commonName = certChain.last().issuer.name
sb.append("${getFormattedCheck(result.isTrusted)}Issuer’s DS Key Recognized: ($commonName)<br>")
sb.append("${getFormattedCheck(doc.issuerSignedAuthenticated)}Issuer Signed Authenticated<br>")
var macOrSignatureString = "MAC"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package com.android.identity.android.securearea.cloud
import android.content.Context
import android.content.pm.PackageManager
import androidx.test.InstrumentationRegistry
import com.android.identity.asn1.ASN1Integer
import com.android.identity.crypto.Algorithm
import com.android.identity.crypto.X509CertChain
import com.android.identity.crypto.Crypto
import com.android.identity.crypto.EcCurve
import com.android.identity.crypto.X500Name
import com.android.identity.crypto.X509Cert
import com.android.identity.crypto.create
import com.android.identity.crypto.X509KeyUsage
import com.android.identity.crypto.javaX509Certificate
import com.android.identity.securearea.AttestationExtension
import com.android.identity.securearea.CreateKeySettings
Expand Down Expand Up @@ -69,19 +71,19 @@ class CloudSecureAreaTest {
val attestationKeySignatureAlgorithm = attestationKey.curve.defaultSigningAlgorithm
val attestationKeyCertificates = X509CertChain(
listOf(
X509Cert.create(
attestationKey.publicKey,
attestationKey,
null,
attestationKeySignatureAlgorithm,
"1",
attestationKeySubject,
attestationKeySubject,
attestationKeyValidFrom,
attestationKeyValidUntil,
setOf(),
listOf()
X509Cert.Builder(
publicKey = attestationKey.publicKey,
signingKey = attestationKey,
signatureAlgorithm = attestationKeySignatureAlgorithm,
serialNumber = ASN1Integer(1L),
subject = X500Name.fromName(attestationKeySubject),
issuer = X500Name.fromName(attestationKeySubject),
validFrom = attestationKeyValidFrom,
validUntil = attestationKeyValidUntil
)
.includeSubjectKeyIdentifier()
.setKeyUsage(setOf(X509KeyUsage.KEY_CERT_SIGN))
.build(),
)
)

Expand All @@ -92,19 +94,19 @@ class CloudSecureAreaTest {
val cloudBindingKeySignatureAlgorithm = cloudBindingKeyAttestationKey.curve.defaultSigningAlgorithm
val cloudBindingKeyAttestationCertificates = X509CertChain(
listOf(
X509Cert.create(
cloudBindingKeyAttestationKey.publicKey,
cloudBindingKeyAttestationKey,
null,
cloudBindingKeySignatureAlgorithm,
"1",
cloudBindingKeySubject,
cloudBindingKeySubject,
cloudBindingKeyValidFrom,
cloudBindingKeyValidUntil,
setOf(),
listOf()
X509Cert.Builder(
publicKey = cloudBindingKeyAttestationKey.publicKey,
signingKey = cloudBindingKeyAttestationKey,
signatureAlgorithm = cloudBindingKeySignatureAlgorithm,
serialNumber = ASN1Integer(1L),
subject = X500Name.fromName(cloudBindingKeySubject),
issuer = X500Name.fromName(cloudBindingKeySubject),
validFrom = cloudBindingKeyValidFrom,
validUntil = cloudBindingKeyValidUntil
)
.includeSubjectKeyIdentifier()
.setKeyUsage(setOf(X509KeyUsage.KEY_CERT_SIGN))
.build(),
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import com.android.identity.crypto.Crypto
import com.android.identity.crypto.EcCurve
import com.android.identity.crypto.EcPublicKey
import com.android.identity.crypto.EcSignature
import com.android.identity.crypto.fromDer
import com.android.identity.crypto.fromJavaX509Certificates
import com.android.identity.crypto.javaX509Certificate
import com.android.identity.securearea.AttestationExtension
Expand Down Expand Up @@ -356,7 +355,7 @@ open class CloudSecureArea(
val request1 = E2EESetupRequest1(
eDeviceKey.publicKey.toCoseKey(),
deviceNonce,
EcSignature.fromDer(EcCurve.P256, derSignature),
EcSignature.fromDerEncoded(EcCurve.P256.bitSize, derSignature),
response0.serverState
)
response = runBlocking { communicate(serverUrl, request1.toCbor()) }
Expand Down Expand Up @@ -620,7 +619,7 @@ open class CloudSecureArea(
val derSignatureLocal = s.sign()

val request1 = SignRequest1(
EcSignature.fromDer(EcCurve.P256, derSignatureLocal),
EcSignature.fromDerEncoded(EcCurve.P256.bitSize, derSignatureLocal),
(keyUnlockData as? CloudKeyUnlockData)?.passphrase,
response0.serverState
)
Expand Down Expand Up @@ -741,7 +740,7 @@ open class CloudSecureArea(
val derSignatureLocal = s.sign()

val request1 = KeyAgreementRequest1(
EcSignature.fromDer(EcCurve.P256, derSignatureLocal),
EcSignature.fromDerEncoded(EcCurve.P256.bitSize, derSignatureLocal),
(keyUnlockData as? CloudKeyUnlockData)?.passphrase,
response0.serverState
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.android.identity.android.mdoc.engagement.QrEngagementHelper
import com.android.identity.android.mdoc.transport.DataTransport
import com.android.identity.android.mdoc.transport.DataTransportOptions
import com.android.identity.android.mdoc.transport.DataTransportTcp
import com.android.identity.asn1.ASN1Integer
import com.android.identity.cbor.Bstr
import com.android.identity.cbor.Cbor.encode
import com.android.identity.cbor.CborArray
Expand All @@ -41,9 +42,10 @@ import com.android.identity.crypto.Crypto.createEcPrivateKey
import com.android.identity.crypto.EcCurve
import com.android.identity.crypto.EcPrivateKey
import com.android.identity.crypto.EcPublicKey
import com.android.identity.crypto.X500Name
import com.android.identity.crypto.X509Cert
import com.android.identity.crypto.X509CertChain
import com.android.identity.crypto.create
import com.android.identity.crypto.X509KeyUsage
import com.android.identity.mdoc.credential.MdocCredential
import com.android.identity.mdoc.mso.MobileSecurityObjectGenerator
import com.android.identity.mdoc.mso.StaticAuthDataGenerator
Expand Down Expand Up @@ -81,6 +83,7 @@ import java.util.Calendar
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import kotlin.random.Random
import kotlin.time.Duration.Companion.days

@Suppress("deprecation")
class DeviceRetrievalHelperTest {
Expand Down Expand Up @@ -174,21 +177,21 @@ class DeviceRetrievalHelperTest {
msoGenerator.addDigestIdsForNamespace(nameSpaceName, digests)
}
val validFrom = now()
val validUntil = fromEpochMilliseconds(
validFrom.toEpochMilliseconds() + 5L * 365 * 24 * 60 * 60 * 1000
)
val validUntil = validFrom + 5.days
documentSignerKey = createEcPrivateKey(EcCurve.P256)
documentSignerCert = X509Cert.create(
documentSignerKey.publicKey,
documentSignerKey,
null,
Algorithm.ES256,
"1",
"CN=State Of Utopia",
"CN=State Of Utopia",
validFrom,
validUntil, setOf(), listOf()
documentSignerCert = X509Cert.Builder(
publicKey = documentSignerKey.publicKey,
signingKey = documentSignerKey,
signatureAlgorithm = documentSignerKey.curve.defaultSigningAlgorithm,
serialNumber = ASN1Integer(1L),
subject = X500Name.fromName("CN=State of Utopia"),
issuer = X500Name.fromName("CN=State of Utopia"),
validFrom = validFrom,
validUntil = validUntil
)
.includeSubjectKeyIdentifier()
.setKeyUsage(setOf(X509KeyUsage.DIGITAL_SIGNATURE))
.build()
val mso = msoGenerator.generate()
val taggedEncodedMso = encode(Tagged(24, Bstr(mso)))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ fun ConsentModalBottomSheet(
ModalBottomSheet(
onDismissRequest = { onCancel() },
sheetState = sheetState,
dragHandle = null,
containerColor = MaterialTheme.colorScheme.surface
) {
Column(
Expand Down Expand Up @@ -172,7 +173,7 @@ private fun ButtonSection(
@Composable
private fun RelyingPartySection(relyingParty: ConsentRelyingParty) {
Column(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier.fillMaxWidth().padding(top = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
if (relyingParty.trustPoint != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.android.identity.securearea.cloud

import com.android.identity.asn1.ASN1Integer
import com.android.identity.cbor.Cbor
import com.android.identity.cbor.CborArray
import com.android.identity.cbor.annotation.CborSerializable
Expand All @@ -8,10 +9,9 @@ import com.android.identity.crypto.Algorithm
import com.android.identity.crypto.Crypto
import com.android.identity.crypto.EcCurve
import com.android.identity.crypto.EcPrivateKey
import com.android.identity.crypto.X500Name
import com.android.identity.crypto.X509Cert
import com.android.identity.crypto.X509CertChain
import com.android.identity.crypto.X509CertificateExtension
import com.android.identity.crypto.create
import com.android.identity.crypto.javaX509Certificates
import com.android.identity.securearea.AttestationExtension
import com.android.identity.securearea.KeyPurpose
Expand Down Expand Up @@ -233,27 +233,26 @@ class CloudSecureAreaServer(
DateTimePeriod(years = 10),
TimeZone.currentSystemDefault()
)
val attestationExtension =
X509CertificateExtension(
AttestationExtension.ATTESTATION_OID,
false,
AttestationExtension.encode(request1.deviceChallenge)
)
val cloudBindingKeyAttestation = X509CertChain(
listOf(
X509Cert.create(
cloudBindingKey.publicKey,
cloudRootAttestationKey,
null,
cloudRootAttestationKeySignatureAlgorithm,
"1",
"CN=Cloud Secure Area Cloud Binding Key",
cloudRootAttestationKeyIssuer,
cloudBindingKeyValidFrom,
cloudBindingKeyValidUntil,
setOf(),
listOf(attestationExtension)
),
X509Cert.Builder(
publicKey = cloudBindingKey.publicKey,
signingKey = cloudRootAttestationKey,
signatureAlgorithm = cloudRootAttestationKeySignatureAlgorithm,
serialNumber = ASN1Integer(1L),
subject = X500Name.fromName("CN=Cloud Secure Area Cloud Binding Key"),
issuer = X500Name.fromName(cloudRootAttestationKeyIssuer),
validFrom = cloudBindingKeyValidFrom,
validUntil = cloudBindingKeyValidUntil
)
.includeSubjectKeyIdentifier()
.setAuthorityKeyIdentifierToCertificate(cloudRootAttestationKeyCertification.certificates[0])
.addExtension(
oid = AttestationExtension.ATTESTATION_OID,
critical = false,
value = AttestationExtension.encode(request1.deviceChallenge)
)
.build()
) + cloudRootAttestationKeyCertification.certificates
)
state.cloudBindingKey = cloudBindingKey.toCoseKey()
Expand Down Expand Up @@ -477,25 +476,24 @@ class CloudSecureAreaServer(

val keyInfo = secureArea.getKeyInfo("CloudKey")

val attestationCert = X509Cert.create(
keyInfo.publicKey,
attestationKey,
attestationKeyCertification.certificates[0],
attestationKeySignatureAlgorithm,
"1",
"CN=Cloud Secure Area Key",
attestationKeyIssuer,
Instant.fromEpochMilliseconds(state.validFromMillis),
Instant.fromEpochMilliseconds(state.validUntilMillis),
setOf(),
listOf(
X509CertificateExtension(
AttestationExtension.ATTESTATION_OID,
false,
AttestationExtension.encode(state.challenge!!)
)
val attestationCert = X509Cert.Builder(
publicKey = keyInfo.publicKey,
signingKey = attestationKey,
signatureAlgorithm = attestationKeySignatureAlgorithm,
serialNumber = ASN1Integer(1L),
subject = X500Name.fromName("CN=Cloud Secure Area Key"),
issuer = X500Name.fromName(attestationKeyIssuer),
validFrom = Instant.fromEpochMilliseconds(state.validFromMillis),
validUntil = Instant.fromEpochMilliseconds(state.validUntilMillis)
)
)
.includeSubjectKeyIdentifier()
.setAuthorityKeyIdentifierToCertificate(attestationKeyCertification.certificates[0])
.addExtension(
oid = AttestationExtension.ATTESTATION_OID,
critical = false,
value = AttestationExtension.encode(state.challenge!!)
)
.build()

state.cloudKeyStorage = storageEngine.toCbor()
val response1 = CreateKeyResponse1(
Expand Down
Loading
Loading