Skip to content

Commit fa319d1

Browse files
committed
Move oscore parse code to Oscore.kt, add constants
1 parent 633e113 commit fa319d1

2 files changed

Lines changed: 62 additions & 41 deletions

File tree

koap-core/src/commonMain/kotlin/Message.kt

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -626,49 +626,10 @@ sealed class Message {
626626
return "Oscore($args)"
627627
}
628628

629-
fun optionValue(): ByteArray {
630-
val partialIvLength = partialIv.size
631-
if (partialIvLength > 5) {
632-
throw IllegalArgumentException("Partial IV length of $partialIvLength is outside allowable range of 0..5")
633-
}
634-
val kidContextLength = if (kidContext != null) kidContext.size else 0
635-
val kidFlag = if (kid != null) 0x08 else 0
636-
val kidContextFlag = if (kidContext != null) 0x10 else 0
637-
val flagBits = partialIvLength or kidFlag or kidContextFlag
638-
if (flagBits == 0) {
639-
// If the OSCORE flag bits are all zero (0x00), the option value SHALL be empty
640-
return byteArrayOf()
641-
}
642-
var value = byteArrayOf(flagBits.toByte()) + partialIv
643-
if (kidContext != null) {
644-
value += byteArrayOf(kidContextLength.toByte()) + kidContext
645-
}
646-
if (kid != null) {
647-
value += kid
648-
}
649-
return value
650-
}
629+
fun optionValue(): ByteArray = oscoreOptionValue(this)
651630

652631
companion object {
653-
fun fromOptionValue(value: ByteArray): Oscore {
654-
if (value.size == 0) {
655-
return Oscore(byteArrayOf(), null, null)
656-
}
657-
val flagBits = value[0].toInt()
658-
val partialIvLength = flagBits and 0x07
659-
val kidFlag = (flagBits and 0x08) != 0
660-
val kidContextFlag = (flagBits and 0x10) != 0
661-
val partialIv = value.sliceArray(1 until 1 + partialIvLength)
662-
val kidContextLength = if (kidContextFlag) value[1 + partialIvLength].toInt() else 0
663-
val kidContext = if (kidContextFlag) {
664-
value.sliceArray(2 + partialIvLength until 2 + partialIvLength + kidContextLength)
665-
} else {
666-
null
667-
}
668-
val kidOffset = (if (kidContextFlag) 2 else 1) + partialIvLength + kidContextLength
669-
val kid = if (kidFlag) value.sliceArray(kidOffset until value.size) else null
670-
return Oscore(partialIv, kidContext, kid)
671-
}
632+
fun fromOptionValue(value: ByteArray): Oscore = oscoreFromOptionValue(value)
672633
}
673634
}
674635

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.juul.koap
2+
3+
import com.juul.koap.Message.Option.Oscore
4+
5+
private val PARTIAL_IV_LENGTH_RANGE = 0..5
6+
private const val PARTIAL_IV_LENGTH_MASK = 0x07
7+
private const val KID_FLAG = 0x08
8+
private const val KID_CONTEXT_FLAG = 0x10
9+
10+
/**
11+
* Creates a binary OSCORE option value from an Oscore option object.
12+
*
13+
* - [RFC 8613](https://tools.ietf.org/html/rfc8613#section-2) 2. The OSCORE Option
14+
* - [RFC 8613](https://tools.ietf.org/html/rfc8613#section-6.1) 6.1. Encoding of the OSCORE Option Value
15+
*/
16+
internal fun oscoreOptionValue(oscore: Oscore): ByteArray {
17+
val partialIvLength = oscore.partialIv.size
18+
require(partialIvLength in PARTIAL_IV_LENGTH_RANGE) {
19+
"Partial IV length of $partialIvLength is outside allowable range of $PARTIAL_IV_LENGTH_RANGE"
20+
}
21+
val kidContextLength = if (oscore.kidContext != null) oscore.kidContext.size else 0
22+
val kidFlagBit = if (oscore.kid != null) KID_FLAG else 0
23+
val kidContextFlagBit = if (oscore.kidContext != null) KID_CONTEXT_FLAG else 0
24+
val flagBits = partialIvLength or kidFlagBit or kidContextFlagBit
25+
if (flagBits == 0) {
26+
// If the OSCORE flag bits are all zero (0x00), the option value SHALL be empty
27+
return byteArrayOf()
28+
}
29+
var value = byteArrayOf(flagBits.toByte()) + oscore.partialIv
30+
if (oscore.kidContext != null) {
31+
value += kotlin.byteArrayOf(kidContextLength.toByte()) + oscore.kidContext
32+
}
33+
if (oscore.kid != null) {
34+
value += oscore.kid
35+
}
36+
return value
37+
}
38+
39+
/**
40+
* Parses an Oscore option object from a binary OSCORE option value.
41+
*/
42+
internal fun oscoreFromOptionValue(value: ByteArray): Oscore {
43+
if (value.size == 0) {
44+
return Oscore(byteArrayOf(), null, null)
45+
}
46+
val flagBits = value[0].toInt()
47+
val partialIvLength = flagBits and PARTIAL_IV_LENGTH_MASK
48+
val kidFlag = (flagBits and KID_FLAG) != 0
49+
val kidContextFlag = (flagBits and KID_CONTEXT_FLAG) != 0
50+
val partialIv = value.sliceArray(1 until 1 + partialIvLength)
51+
val kidContextLength = if (kidContextFlag) value[1 + partialIvLength].toInt() else 0
52+
val kidContext = if (kidContextFlag) {
53+
value.sliceArray(2 + partialIvLength until 2 + partialIvLength + kidContextLength)
54+
} else {
55+
null
56+
}
57+
val kidOffset = (if (kidContextFlag) 2 else 1) + partialIvLength + kidContextLength
58+
val kid = if (kidFlag) value.sliceArray(kidOffset until value.size) else null
59+
return Oscore(partialIv, kidContext, kid)
60+
}

0 commit comments

Comments
 (0)