Skip to content

Commit

Permalink
Temp. upgrade to CBOR serializer 1.5.3-SNAPSHOT
Browse files Browse the repository at this point in the history
  • Loading branch information
nodh committed Jul 25, 2023
1 parent 06365d1 commit 11eec28
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 71 deletions.
2 changes: 1 addition & 1 deletion vclib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ kotlin {
api("at.asitplus:kmmresult:${VcLibVersions.resultlib}")
api("io.matthewnelson.kotlin-components:encoding-base16:${VcLibVersions.encoding}")
api("io.matthewnelson.kotlin-components:encoding-base64:${VcLibVersions.encoding}")
api("org.jetbrains.kotlinx:kotlinx-serialization-cbor:1.5.2-SNAPSHOT")
api("org.jetbrains.kotlinx:kotlinx-serialization-cbor:1.5.3-SNAPSHOT")
}
}
val commonTest by getting
Expand Down
43 changes: 29 additions & 14 deletions vclib/src/commonMain/kotlin/at/asitplus/wallet/lib/cbor/CoseKey.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ data class CoseKey(
@SerialLabel(3)
@SerialName("alg")
val algorithm: CoseAlgorithm? = null,
// @SerialLabel(4)
// @SerialName("key_ops")
// val operations: Array<CoseKeyOperation>? = null,
// @SerialLabel(5)
// @SerialName("Base IV")
// @ByteString
// val baseIv: ByteArray? = null,
@SerialLabel(4)
@SerialName("key_ops")
val operations: Array<CoseKeyOperation>? = null,
@SerialLabel(5)
@SerialName("Base IV")
@ByteString
val baseIv: ByteArray? = null,
@SerialLabel(-1)
@SerialName("crv")
val curve: CoseEllipticCurve? = null,
Expand All @@ -46,9 +46,9 @@ data class CoseKey(
@SerialLabel(-3)
@SerialName("y") // TODO might also be bool
val y: ByteArray? = null,
// @SerialLabel(-4)
// @SerialName("d")
// val d: ByteArray? = null,
@SerialLabel(-4)
@SerialName("d")
val d: ByteArray? = null,
) {
fun serialize() = cborSerializer.encodeToByteArray(this)

Expand Down Expand Up @@ -114,12 +114,12 @@ data class CoseKey(
return "CoseKey(type=$type," +
" keyId=${keyId?.encodeBase16()}," +
" algorithm=$algorithm," +
//" operations=${operations?.contentToString()}," +
//" baseIv=${baseIv?.encodeBase16()}," +
" operations=${operations?.contentToString()}," +
" baseIv=${baseIv?.encodeBase16()}," +
" curve=$curve," +
" x=${x?.encodeBase16()}," +
" y=${y?.encodeBase16()})"
//" d=${d?.encodeBase16()})"
" y=${y?.encodeBase16()}," +
" d=${d?.encodeBase16()})"
}

override fun equals(other: Any?): Boolean {
Expand All @@ -134,6 +134,14 @@ data class CoseKey(
if (!keyId.contentEquals(other.keyId)) return false
} else if (other.keyId != null) return false
if (algorithm != other.algorithm) return false
if (operations != null) {
if (other.operations == null) return false
if (!operations.contentEquals(other.operations)) return false
} else if (other.operations != null) return false
if (baseIv != null) {
if (other.baseIv == null) return false
if (!baseIv.contentEquals(other.baseIv)) return false
} else if (other.baseIv != null) return false
if (curve != other.curve) return false
if (x != null) {
if (other.x == null) return false
Expand All @@ -143,6 +151,10 @@ data class CoseKey(
if (other.y == null) return false
if (!y.contentEquals(other.y)) return false
} else if (other.y != null) return false
if (d != null) {
if (other.d == null) return false
if (!d.contentEquals(other.d)) return false
} else if (other.d != null) return false

return true
}
Expand All @@ -151,9 +163,12 @@ data class CoseKey(
var result = type.hashCode()
result = 31 * result + (keyId?.contentHashCode() ?: 0)
result = 31 * result + (algorithm?.hashCode() ?: 0)
result = 31 * result + (operations?.contentHashCode() ?: 0)
result = 31 * result + (baseIv?.contentHashCode() ?: 0)
result = 31 * result + (curve?.hashCode() ?: 0)
result = 31 * result + (x?.contentHashCode() ?: 0)
result = 31 * result + (y?.contentHashCode() ?: 0)
result = 31 * result + (d?.contentHashCode() ?: 0)
return result
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ data class DeviceRequest(
data class DocRequest(
@SerialName("itemsRequest")
@Serializable(with = ByteStringWrapperItemsRequestSerializer::class)
@ValueTags(24U)
val itemsRequest: ByteStringWrapper<ItemsRequest>,
@SerialName("readerAuth")
val readerAuth: CoseSigned? = null,
Expand Down Expand Up @@ -430,7 +431,7 @@ data class DeviceSigned(
@ValueTags(24U)
val namespaces: ByteArray,
@SerialName("deviceAuth")
@ByteString
//@ByteString
val deviceAuth: DeviceAuth,
) {
fun extractDeviceNameSpaces(): Map<String, Map<String, ElementValue>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ val cborSerializer by lazy {
ignoreUnknownKeys = true
alwaysUseByteString = true
encodeDefaults = false
writeDefiniteLengths = true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,43 @@ import io.matthewnelson.component.encoding.base16.decodeBase16ToArray
import io.matthewnelson.component.encoding.base16.encodeBase16
import kotlinx.serialization.cbor.ByteStringWrapper

// TODO Test once serialization library is correct
//class CoseSerializationTest : FreeSpec({
//
// Napier.base(DebugAntilog())
//
// "Serialization is correct" {
// val cose = CoseSigned(
// protectedHeader = ByteStringWrapper(CoseHeader(algorithm = CoseAlgorithm.ES256)),
// unprotectedHeader = CoseHeader(),
// payload = "This is the content.".encodeToByteArray(),
// signature = "bar".encodeToByteArray()
// )
// val serialized = cose.serialize().encodeBase16().uppercase()
//
// serialized shouldContain "546869732069732074686520636F6E74656E742E" // "This is the content."
// // TODO serialized shouldContain "43A10126" //
// }
//
// "Serialize header" {
// val header = CoseHeader(algorithm = CoseAlgorithm.ES256, kid = "11")
// val serialized = header.serialize().encodeBase16().uppercase()
// println(serialized)
//
// val deserialized = CoseHeader.deserialize(header.serialize())
// deserialized.shouldNotBeNull()
// deserialized.algorithm shouldBe header.algorithm
// deserialized.kid shouldBe header.kid
// }
//
// "Deserialization is correct" {
// val input = "d28443a10126a10442313154546869732069732074686520636f6e74656e" +
// "742e58408eb33e4ca31d1c465ab05aac34cc6b23d58fef5c083106c4d25a" +
// "91aef0b0117e2af9a291aa32e14ab834dc56ed2a223444547e01f11d3b09" +
// "16e5a4c345cacb36"
// val cose = CoseSigned.deserialize(input.uppercase().decodeBase16ToArray()!!)
//
// println(cose)
// cose.shouldNotBeNull()
// }
//
//})
class CoseSerializationTest : FreeSpec({

Napier.base(DebugAntilog())

"Serialization is correct" {
val cose = CoseSigned(
protectedHeader = ByteStringWrapper(CoseHeader(algorithm = CoseAlgorithm.ES256)),
unprotectedHeader = CoseHeader(),
payload = "This is the content.".encodeToByteArray(),
signature = "bar".encodeToByteArray()
)
val serialized = cose.serialize().encodeBase16().uppercase()

serialized shouldContain "546869732069732074686520636F6E74656E742E" // "This is the content."
serialized shouldContain "43A10126"
}

"Serialize header" {
val header = CoseHeader(algorithm = CoseAlgorithm.ES256, kid = "11")
val serialized = header.serialize().encodeBase16().uppercase()
println(serialized)

val deserialized = CoseHeader.deserialize(header.serialize())
deserialized.shouldNotBeNull()
deserialized.algorithm shouldBe header.algorithm
deserialized.kid shouldBe header.kid
}

"Deserialization is correct" {
val input = "d28443a10126a10442313154546869732069732074686520636f6e74656e" +
"742e58408eb33e4ca31d1c465ab05aac34cc6b23d58fef5c083106c4d25a" +
"91aef0b0117e2af9a291aa32e14ab834dc56ed2a223444547e01f11d3b09" +
"16e5a4c345cacb36"
val cose = CoseSigned.deserialize(input.uppercase().decodeBase16ToArray()!!)

println(cose)
cose.shouldNotBeNull()
}

})
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ class CoseServiceTest : FreeSpec({
signed.payload shouldBe randomPayload
signed.signature.shouldNotBeNull()

// TODO activate once serialization works
//val parsed = CoseSigned.deserialize(signed.serialize())
//parsed.shouldNotBeNull()
val parsed = signed
val parsed = CoseSigned.deserialize(signed.serialize())
parsed.shouldNotBeNull()

val result = verifierCoseService.verifyCose(parsed, cryptoService.toCoseKey()).getOrThrow()
result shouldBe true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ class CborSerializationTest : FreeSpec({
docRequest.readerAuth.shouldNotBeNull()
docRequest.readerAuth?.unprotectedHeader?.certificateChain?.shouldNotBeNull()

// TODO Needs definite length for arrays, e.g. in deviceRequest.docRequests
//deviceRequest.serialize().encodeBase16().uppercase() shouldBe input
// TODO only F6 as "null" for readerAuth.payload is missing
deviceRequest.serialize().encodeBase16().uppercase() shouldBe input
}

// From ISO/IEC 18013-5:2021(E), D4.1.2, page 116
Expand Down Expand Up @@ -382,8 +382,11 @@ class CborSerializationTest : FreeSpec({
valueDigestListUs.findItem(1U) shouldBe "4D80E1E2E4FB246D97895427CE7000BB59BB24C8CD003ECF94BF35BBD2917E34"
.decodeBase16ToArray()

// TODO D818 is the tags for digests
//deviceResponse.serialize().encodeBase16() shouldBe input
document.deviceSigned.deviceAuth.deviceMac.shouldNotBeNull()

// TODO Custom serializer IssuerSignedListSerializer doesn't produce output anymore with 1.5.3-SNAPSHOT
// TODO value for deviceauth doesn't get written
deviceResponse.serialize().encodeBase16() shouldBe input
}

"Driving Privilege" {
Expand Down Expand Up @@ -555,7 +558,7 @@ class CborSerializationTest : FreeSpec({
.decodeBase16ToArray()

// TODO only A7 vs A1 for serialized CoseHeader is wrong!
//coseSigned.serialize().encodeBase16() shouldBe input
coseSigned.serialize().encodeBase16() shouldBe input
}

})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ class Wallet {

val deviceKeyInfo = DeviceKeyInfo(
deviceKey = cryptoService.toCoseKey(),
// specify optional parameters as workaround for definite length encoding in CBOR
keyAuthorizations = KeyAuthorization(namespaces = arrayOf("a"), dataElements = mapOf("b" to arrayOf("c"))),
keyInfo = mapOf(0 to "bar")
)

var storedMdl: MobileDrivingLicence? = null
Expand Down Expand Up @@ -175,8 +172,6 @@ class Issuer {
signed = Clock.System.now(),
validFrom = Clock.System.now(),
validUntil = Clock.System.now(),
// specify optional parameters as workaround for definite length encoding in CBOR
expectedUpdate = Clock.System.now(),
)
)

Expand Down

0 comments on commit 11eec28

Please sign in to comment.