diff --git a/vclib/src/commonMain/kotlin/at/asitplus/wallet/lib/iso/DeviceRequest.kt b/vclib/src/commonMain/kotlin/at/asitplus/wallet/lib/iso/DeviceRequest.kt index 6794e9316..2669fbb58 100644 --- a/vclib/src/commonMain/kotlin/at/asitplus/wallet/lib/iso/DeviceRequest.kt +++ b/vclib/src/commonMain/kotlin/at/asitplus/wallet/lib/iso/DeviceRequest.kt @@ -6,6 +6,7 @@ import at.asitplus.wallet.lib.cbor.CoseSigned import at.asitplus.wallet.lib.iso.IsoDataModelConstants.NAMESPACE_MDL import io.github.aakira.napier.Napier import io.matthewnelson.component.encoding.base16.encodeBase16 +import kotlinx.datetime.LocalDate import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialName @@ -414,11 +415,20 @@ data class IssuerSignedItem( @Serializable(with = ElementValueSerializer::class) data class ElementValue( val bytes: ByteArray? = null, + @ValueTags(1004u) + val date: LocalDate? = null, val string: String? = null, val drivingPrivilege: List? = null, ) { fun serialize() = cborSerializer.encodeToByteArray(this) + override fun toString(): String { + return "ElementValue(bytes=${bytes?.encodeBase16()}," + + " date=${date}," + + " string=$string," + + " drivingPrivilege=$drivingPrivilege)" + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false @@ -429,21 +439,19 @@ data class ElementValue( if (other.bytes == null) return false if (!bytes.contentEquals(other.bytes)) return false } else if (other.bytes != null) return false + if (date != other.date) return false if (string != other.string) return false return drivingPrivilege == other.drivingPrivilege } override fun hashCode(): Int { var result = bytes?.contentHashCode() ?: 0 + result = 31 * result + (date?.hashCode() ?: 0) result = 31 * result + (string?.hashCode() ?: 0) result = 31 * result + (drivingPrivilege?.hashCode() ?: 0) return result } - override fun toString(): String { - return "ElementValue(bytes=${bytes?.encodeBase16()}, string=$string, drivingPrivilege=$drivingPrivilege)" - } - companion object { fun deserialize(it: ByteArray) = kotlin.runCatching { cborSerializer.decodeFromByteArray(it) @@ -551,6 +559,9 @@ object ElementValueSerializer : KSerializer { override fun serialize(encoder: Encoder, value: ElementValue) { value.bytes?.let { encoder.encodeSerializableValue(ByteArraySerializer(), it) + } ?: value.date?.let { + // TODO write tag 1004 + encoder.encodeSerializableValue(LocalDate.serializer(), it) } ?: value.string?.let { encoder.encodeString(it) } ?: value.drivingPrivilege?.let { @@ -562,14 +573,21 @@ object ElementValueSerializer : KSerializer { runCatching { return ElementValue(bytes = decoder.decodeSerializableValue(ByteArraySerializer())) } - runCatching { - return ElementValue(string = decoder.decodeString()) - } runCatching { return ElementValue( drivingPrivilege = decoder.decodeSerializableValue(ListSerializer(DrivingPrivilege.serializer())) ) } + runCatching { + val string = decoder.decodeString() + runCatching { + LocalDate.parse(string) + }.onSuccess { + return ElementValue(date = it) + }.onFailure { + return ElementValue(string = string) + } + } throw IllegalArgumentException("Could not decode instance of ElementValue") } diff --git a/vclib/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/CborSerializationTest.kt b/vclib/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/CborSerializationTest.kt index 4255d35f3..a1658eccb 100644 --- a/vclib/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/CborSerializationTest.kt +++ b/vclib/src/commonTest/kotlin/at/asitplus/wallet/lib/iso/CborSerializationTest.kt @@ -341,9 +341,9 @@ class CborSerializationTest : FreeSpec({ issuerSignedList.findItem(0U).elementIdentifier shouldBe FAMILY_NAME issuerSignedList.findItem(0U).elementValue.string shouldBe "Doe" issuerSignedList.findItem(3U).elementIdentifier shouldBe ISSUE_DATE - issuerSignedList.findItem(3U).elementValue.string shouldBe "2019-10-20" + issuerSignedList.findItem(3U).elementValue.date shouldBe LocalDate.parse("2019-10-20") issuerSignedList.findItem(4U).elementIdentifier shouldBe EXPIRY_DATE - issuerSignedList.findItem(4U).elementValue.string shouldBe "2024-10-20" + issuerSignedList.findItem(4U).elementValue.date shouldBe LocalDate.parse("2024-10-20") issuerSignedList.findItem(7U).elementIdentifier shouldBe DOCUMENT_NUMBER issuerSignedList.findItem(7U).elementValue.string shouldBe "123456789" issuerSignedList.findItem(8U).elementIdentifier shouldBe PORTRAIT @@ -384,7 +384,7 @@ class CborSerializationTest : FreeSpec({ document.deviceSigned.deviceAuth.deviceMac.shouldNotBeNull() - // TODO valuedigests need tag 24 -> 0xd818 + // TODO dates in ElementValue need tags 1004u => 0xD903EC deviceResponse.serialize().encodeBase16() shouldBe input }