From 316904c8a5bdf73443db8c1f1845cb2294913868 Mon Sep 17 00:00:00 2001 From: Christian Kollmann Date: Tue, 26 Nov 2024 18:43:17 +0100 Subject: [PATCH] WIP: Can't decode IssuerSigned --- signum | 2 +- .../at/asitplus/wallet/lib/agent/IssuerAgent.kt | 6 ++++-- .../kotlin/at/asitplus/wallet/lib/agent/Validator.kt | 8 ++++---- .../at/asitplus/wallet/lib/iso/IssuerSigned.kt | 5 +++-- .../lib/cbor/DeviceSignedItemSerializationTest.kt | 2 +- .../lib/cbor/IssuerSignedItemSerializationTest.kt | 2 +- .../at/asitplus/wallet/lib/iso/IsoProcessTest.kt | 12 +++++++----- .../wallet/lib/iso/Tag24SerializationTest.kt | 4 ++-- 8 files changed, 23 insertions(+), 18 deletions(-) diff --git a/signum b/signum index 65096bd11..bc9b8600d 160000 --- a/signum +++ b/signum @@ -1 +1 @@ -Subproject commit 65096bd1130758fdc6f22c73d95c1eabab3a155c +Subproject commit bc9b8600d653f3c705c2cef4c5af1f937cf6abfe diff --git a/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/agent/IssuerAgent.kt b/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/agent/IssuerAgent.kt index 8c6d0c5d0..b1127e95e 100644 --- a/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/agent/IssuerAgent.kt +++ b/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/agent/IssuerAgent.kt @@ -4,6 +4,8 @@ import at.asitplus.KmmResult import at.asitplus.catching import at.asitplus.signum.indispensable.SignatureAlgorithm import at.asitplus.signum.indispensable.asn1.BitSet +import at.asitplus.signum.indispensable.cosef.io.ByteStringWrapper +import at.asitplus.signum.indispensable.cosef.io.ByteStringWrapperSerializer import at.asitplus.signum.indispensable.cosef.toCoseKey import at.asitplus.signum.indispensable.io.Base64Strict import at.asitplus.signum.indispensable.josef.ConfirmationClaim @@ -118,8 +120,8 @@ class IssuerAgent( val issuerSigned = IssuerSigned.fromIssuerSignedItems( namespacedItems = mapOf(credential.scheme.isoNamespace!! to credential.issuerSignedItems), issuerAuth = coseService.createSignedCose( - payload = mso, - serializer = MobileSecurityObject.serializer(), + payload = ByteStringWrapper(mso), + serializer = ByteStringWrapperSerializer(MobileSecurityObject.serializer()), addKeyId = false, addCertificate = true, ).getOrThrow(), diff --git a/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/agent/Validator.kt b/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/agent/Validator.kt index 23ea33d78..bf9cd100a 100644 --- a/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/agent/Validator.kt +++ b/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/agent/Validator.kt @@ -5,6 +5,7 @@ import at.asitplus.signum.indispensable.asn1.BitSet import at.asitplus.signum.indispensable.asn1.toBitSet import at.asitplus.signum.indispensable.cosef.CoseKey import at.asitplus.signum.indispensable.cosef.io.ByteStringWrapper +import at.asitplus.signum.indispensable.cosef.io.ByteStringWrapperSerializer import at.asitplus.signum.indispensable.cosef.toCoseKey import at.asitplus.signum.indispensable.io.Base64Strict import at.asitplus.signum.indispensable.josef.JwsHeader @@ -296,13 +297,12 @@ class Validator( throw IllegalArgumentException("issuerKey") } - if (verifierCoseService.verifyCose(issuerAuth, issuerKey, MobileSecurityObject.serializer()).isFailure) { + if (verifierCoseService.verifyCose(issuerAuth, issuerKey, ByteStringWrapperSerializer(MobileSecurityObject.serializer())).isFailure) { Napier.w("IssuerAuth not verified: $issuerAuth") throw IllegalArgumentException("issuerAuth") } - val mso: MobileSecurityObject? = issuerSigned.issuerAuth.payload - if (mso == null) { + val mso: MobileSecurityObject = issuerSigned.issuerAuth.payload?.value ?: run { Napier.w("MSO is null: $issuerAuth") throw IllegalArgumentException("mso") } @@ -470,7 +470,7 @@ class Validator( it.serialize().encodeToString(Base16(strict = true)) ) } - val result = verifierCoseService.verifyCose(it.issuerAuth, issuerKey, MobileSecurityObject.serializer()) + val result = verifierCoseService.verifyCose(it.issuerAuth, issuerKey, ByteStringWrapperSerializer(MobileSecurityObject.serializer())) if (result.isFailure) { Napier.w("ISO: Could not verify credential", result.exceptionOrNull()) return Verifier.VerifyCredentialResult.InvalidStructure( diff --git a/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/iso/IssuerSigned.kt b/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/iso/IssuerSigned.kt index 9b48b4c11..88013d21c 100644 --- a/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/iso/IssuerSigned.kt +++ b/vck/src/commonMain/kotlin/at/asitplus/wallet/lib/iso/IssuerSigned.kt @@ -2,6 +2,7 @@ package at.asitplus.wallet.lib.iso import at.asitplus.KmmResult.Companion.wrap import at.asitplus.signum.indispensable.cosef.CoseSigned +import at.asitplus.signum.indispensable.cosef.io.ByteStringWrapper import kotlinx.serialization.* /** @@ -13,7 +14,7 @@ data class IssuerSigned private constructor( @Serializable(with = NamespacedIssuerSignedListSerializer::class) val namespaces: Map? = null, @SerialName("issuerAuth") - val issuerAuth: CoseSigned, + val issuerAuth: CoseSigned>, ) { fun serialize() = vckCborSerializer.encodeToByteArray(this) @@ -54,7 +55,7 @@ data class IssuerSigned private constructor( */ fun fromIssuerSignedItems( namespacedItems: Map>, - issuerAuth: CoseSigned, + issuerAuth: CoseSigned>, ): IssuerSigned = IssuerSigned( namespaces = namespacedItems.map { (namespace, value) -> namespace to IssuerSignedList.fromIssuerSignedItems(value, namespace) diff --git a/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/cbor/DeviceSignedItemSerializationTest.kt b/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/cbor/DeviceSignedItemSerializationTest.kt index d062acffc..54d415a36 100644 --- a/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/cbor/DeviceSignedItemSerializationTest.kt +++ b/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/cbor/DeviceSignedItemSerializationTest.kt @@ -48,7 +48,7 @@ class DeviceSignedItemSerializationTest : FreeSpec({ value = Random.nextBytes(32), ) val protectedHeader = ByteStringWrapper(CoseHeader(), CoseHeader().serialize()) - val issuerAuth = CoseSigned(protectedHeader, null, null, byteArrayOf()) + val issuerAuth = CoseSigned>(protectedHeader, null, null, byteArrayOf()) val deviceAuth = CoseSigned(protectedHeader, null, null, byteArrayOf()) val doc = Document( diff --git a/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/cbor/IssuerSignedItemSerializationTest.kt b/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/cbor/IssuerSignedItemSerializationTest.kt index a2a0ac6ec..ce0262a9d 100644 --- a/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/cbor/IssuerSignedItemSerializationTest.kt +++ b/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/cbor/IssuerSignedItemSerializationTest.kt @@ -46,7 +46,7 @@ class IssuerSignedItemSerializationTest : FreeSpec({ elementValue = Random.nextBytes(32), ) val protectedHeader = ByteStringWrapper(CoseHeader(), CoseHeader().serialize()) - val issuerAuth = CoseSigned(protectedHeader, null, null, byteArrayOf()) + val issuerAuth = CoseSigned>(protectedHeader, null, null, byteArrayOf()) val doc = Document( docType = uuid4().toString(), issuerSigned = IssuerSigned.fromIssuerSignedItems( diff --git a/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/IsoProcessTest.kt b/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/IsoProcessTest.kt index 326a08f8d..a912f6003 100644 --- a/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/IsoProcessTest.kt +++ b/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/IsoProcessTest.kt @@ -4,6 +4,7 @@ import at.asitplus.signum.indispensable.cosef.CoseHeader import at.asitplus.signum.indispensable.cosef.CoseKey import at.asitplus.signum.indispensable.cosef.CoseSigned import at.asitplus.signum.indispensable.cosef.io.ByteStringWrapper +import at.asitplus.signum.indispensable.cosef.io.ByteStringWrapperSerializer import at.asitplus.signum.indispensable.cosef.toCoseKey import at.asitplus.wallet.lib.agent.DefaultCryptoService import at.asitplus.wallet.lib.agent.EphemeralKeyWithoutCert @@ -45,7 +46,7 @@ class Wallet { private val coseService = DefaultCoseService(cryptoService) val deviceKeyInfo = DeviceKeyInfo(cryptoService.keyMaterial.publicKey.toCoseKey().getOrThrow()) - private var storedIssuerAuth: CoseSigned? = null + private var storedIssuerAuth: CoseSigned>? = null private var storedMdlItems: IssuerSignedList? = null fun storeMdl(deviceResponse: DeviceResponse) { @@ -57,6 +58,7 @@ class Wallet { issuerAuth.payload.shouldNotBeNull() val mso = document.issuerSigned.issuerAuth .payload.shouldNotBeNull() + .value val mdlItems = document.issuerSigned.namespaces?.get(ConstantIndex.AtomicAttribute2023.isoNamespace) .shouldNotBeNull() @@ -141,8 +143,8 @@ class Issuer { ConstantIndex.AtomicAttribute2023.isoNamespace to issuerSigned ), issuerAuth = coseService.createSignedCose( - payload = mso, - serializer = MobileSecurityObject.serializer(), + payload = ByteStringWrapper(mso), + serializer = ByteStringWrapperSerializer(MobileSecurityObject.serializer()), addKeyId = false, addCertificate = true, ).getOrThrow() @@ -198,9 +200,9 @@ class Verifier { doc.errors.shouldBeNull() val issuerSigned = doc.issuerSigned val issuerAuth = issuerSigned.issuerAuth - verifierCoseService.verifyCose(issuerAuth, issuerKey, MobileSecurityObject.serializer()).isSuccess shouldBe true + verifierCoseService.verifyCose(issuerAuth, issuerKey, ByteStringWrapperSerializer(MobileSecurityObject.serializer())).isSuccess shouldBe true issuerAuth.payload.shouldNotBeNull() - val mso = issuerAuth.payload.shouldNotBeNull() + val mso = issuerAuth.payload.shouldNotBeNull().value mso.docType shouldBe ConstantIndex.AtomicAttribute2023.isoDocType val mdlItems = mso.valueDigests[ConstantIndex.AtomicAttribute2023.isoNamespace].shouldNotBeNull() diff --git a/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/Tag24SerializationTest.kt b/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/Tag24SerializationTest.kt index 6d63872ef..2a3dee9d1 100644 --- a/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/Tag24SerializationTest.kt +++ b/vck/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/Tag24SerializationTest.kt @@ -98,7 +98,7 @@ class Tag24SerializationTest : FreeSpec({ ).getOrThrow().shouldBeInstanceOf() issuedCredential.issuerSigned.namespaces!!.shouldNotBeEmpty() - val numberOfClaims = issuedCredential.issuerSigned.namespaces!!.entries.fold(0) { acc, entry -> + val numberOfClaims = issuedCredential.issuerSigned.namespaces.entries.fold(0) { acc, entry -> acc + entry.value.entries.size } val serialized = issuedCredential.issuerSigned.serialize().encodeToString(Base16(true)) @@ -166,7 +166,7 @@ private fun MobileSecurityObject.Companion.deserializeFromIssuerAuth(it: ByteArr private fun deviceKeyInfo() = DeviceKeyInfo(CoseKey(CoseKeyType.EC2, keyParams = CoseKeyParams.EcYBoolParams(CoseEllipticCurve.P256))) -private fun issuerAuth() = CoseSigned( +private fun issuerAuth() = CoseSigned>( protectedHeader = ByteStringWrapper(CoseHeader()), unprotectedHeader = null, payload = null,