-
Notifications
You must be signed in to change notification settings - Fork 614
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
CBOR Feature Drop: COSE #2412
base: dev
Are you sure you want to change the base?
CBOR Feature Drop: COSE #2412
Changes from all commits
c2db1cf
1edcec3
04826be
8979a6e
3e235dd
256e12d
eaf5ef1
d68c3a3
db1700b
45f70e9
79bf170
b0b9974
19f9227
b2cc8bc
c78f102
2e84646
b4e3942
a9d00c2
2ef81c4
51bb184
2c558f0
1c6edde
337555e
0d351c1
dbebe10
ad25978
0e5e519
36655cb
f160d70
751aa81
da25674
68218a1
2c4ff1e
d4e2052
d3039fb
f8d7dfd
91e97c9
4786990
b415365
dbb9d0e
77e89c7
4f8b680
1137c42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package kotlinx.serialization.cbor | ||
|
||
import kotlinx.serialization.* | ||
import kotlinx.serialization.builtins.* | ||
import kotlinx.serialization.descriptors.* | ||
import kotlinx.serialization.encoding.* | ||
|
||
/** | ||
* Use this class if you'll need to serialize a complex type as a byte string before encoding it, | ||
* i.e. as it is the case with the protected header in COSE structures. | ||
* | ||
* An example for a COSE header data class would be: | ||
* | ||
* ``` | ||
* @Serializable | ||
* data class CoseHeader( | ||
* @CborLabel(1) | ||
* @SerialName("alg") | ||
* val alg: Int? = null | ||
* ) | ||
* | ||
* @Serializable | ||
* data class CoseSigned( | ||
* @ByteString | ||
* @CborLabel(1) | ||
* @SerialName("protectedHeader") | ||
* val protectedHeader: ByteStringWrapper<CoseHeader>, | ||
sandwwraith marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* ) | ||
* ``` | ||
* | ||
* Serializing this `CoseHeader` object would result in `a10143a10126`, in diagnostic notation: | ||
* | ||
* ``` | ||
* A1 # map(1) | ||
* 01 # unsigned(1) | ||
* 43 # bytes(3) | ||
* A10126 # "\xA1\u0001&" | ||
* ``` | ||
* | ||
* so the `protectedHeader` got serialized first and then encoded as a `@ByteString`. | ||
* | ||
* Note that `equals()` and `hashCode()` only use `value`, not `serialized`. | ||
*/ | ||
@Serializable(with = ByteStringWrapperSerializer::class) | ||
public class ByteStringWrapper<T>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NB: it seems you need to update There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, done! |
||
public val value: T, | ||
public val serialized: ByteArray = byteArrayOf() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've skimmed through the diff and can't find any usages of this value. Is there any reason to be a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nodh can you take care of this, please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll use the CBOR serialization for ISO 18013-5 compliaent mobile driving licences. There verifiers need to check that (the digest of) the serialized byte values appear in another structure (signed by the issuer). So in that case its quite useful to have the bytes as they were serialized (and parsed) in the deserialized |
||
) { | ||
override fun equals(other: Any?): Boolean { | ||
sandwwraith marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (this === other) return true | ||
if (other == null || this::class != other::class) return false | ||
|
||
other as ByteStringWrapper<*> | ||
|
||
return value == other.value | ||
} | ||
|
||
override fun hashCode(): Int { | ||
return value?.hashCode() ?: 0 | ||
} | ||
|
||
override fun toString(): String { | ||
return "ByteStringWrapper(value=$value, serialized=${serialized.contentToString()})" | ||
} | ||
|
||
} | ||
|
||
|
||
@OptIn(ExperimentalSerializationApi::class) | ||
public class ByteStringWrapperSerializer<T>(private val dataSerializer: KSerializer<T>) : | ||
KSerializer<ByteStringWrapper<T>> { | ||
|
||
override val descriptor: SerialDescriptor = dataSerializer.descriptor | ||
|
||
override fun serialize(encoder: Encoder, value: ByteStringWrapper<T>) { | ||
val bytes = Cbor.encodeToByteArray(dataSerializer, value.value) | ||
encoder.encodeSerializableValue(ByteArraySerializer(), bytes) | ||
} | ||
|
||
override fun deserialize(decoder: Decoder): ByteStringWrapper<T> { | ||
val bytes = decoder.decodeSerializableValue(ByteArraySerializer()) | ||
val value = Cbor.decodeFromByteArray(dataSerializer, bytes) | ||
return ByteStringWrapper(value, bytes) | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe
ValueTags.Companion
should be mentioned here as a source for pre-defined tagsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done