Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions src/main/kotlin/Extension.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import java.math.BigInteger
import java.nio.ByteBuffer
import java.nio.charset.CodingErrorAction
import java.security.cert.X509Certificate
import java.time.Instant
import java.time.YearMonth
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException
Expand Down Expand Up @@ -913,16 +914,34 @@ fun cborEncode(dataItem: DataItem): ByteArray {
return baos.toByteArray()
}

fun DataItem.asInteger(): Int {
if (this.majorType == MajorType.UNSIGNED_INTEGER) {
return (this as UnsignedInteger).value.toInt()
private fun BigInteger.toIntExact(): Int {
if (bitLength() < Integer.SIZE) {
return toInt()
}
if (this.majorType == MajorType.NEGATIVE_INTEGER) {
return (this as NegativeInteger).value.toInt()
throw CborException("BigInteger out of int range")
}

private fun BigInteger.toLongExact(): Long {
if (bitLength() < java.lang.Long.SIZE) {
return toLong()
}
throw CborException("Expected a number, got ${this.majorType}")
throw CborException("BigInteger out of long range")
}

fun DataItem.asInteger(): Int =
when (this) {
is UnsignedInteger -> value.toIntExact()
is NegativeInteger -> value.toIntExact()
else -> throw CborException("Expected a number, got $majorType")
}

fun DataItem.asLong(): Long =
when (this) {
is UnsignedInteger -> value.toLongExact()
is NegativeInteger -> value.toLongExact()
else -> throw CborException("Expected a number, got $majorType")
}

fun Int.asDataItem() =
when {
this >= 0 -> UnsignedInteger(this.toLong())
Expand Down
40 changes: 40 additions & 0 deletions src/test/kotlin/ExtensionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package com.android.keyattestation.verifier

import co.nstant.`in`.cbor.CborException
import co.nstant.`in`.cbor.model.NegativeInteger
import co.nstant.`in`.cbor.model.UnsignedInteger
import com.android.keyattestation.verifier.testing.Chains
import com.android.keyattestation.verifier.testing.FakeLogHook
import com.android.keyattestation.verifier.testing.TestUtils.TESTDATA_PATH
Expand All @@ -31,6 +34,8 @@ import com.google.testing.junit.testparameterinjector.TestParameters
import com.google.testing.junit.testparameterinjector.TestParameters.TestParametersValues
import com.google.testing.junit.testparameterinjector.TestParametersValuesProvider
import com.google.testing.junit.testparameterinjector.TestParametersValuesProvider.Context
import java.math.BigInteger
import java.time.Instant
import java.time.YearMonth
import kotlin.io.path.Path
import kotlin.io.path.inputStream
Expand Down Expand Up @@ -255,4 +260,39 @@ class ExtensionTest {
AttestationApplicationId.from(seq, inputLimits = limits)
}
}

@Test
fun asInteger_validValues_success() {
assertThat(UnsignedInteger(0).asInteger()).isEqualTo(0)
assertThat(UnsignedInteger(Int.MAX_VALUE.toLong()).asInteger()).isEqualTo(Int.MAX_VALUE)
assertThat(NegativeInteger(-1).asInteger()).isEqualTo(-1)
assertThat(NegativeInteger(Int.MIN_VALUE.toLong()).asInteger()).isEqualTo(Int.MIN_VALUE)
}

@Test
fun asInteger_outOfBounds_throws() {
val unsignedOutOfRange = UnsignedInteger(Int.MAX_VALUE.toLong() + 1)
assertThrows(CborException::class.java) { unsignedOutOfRange.asInteger() }

val negativeOutOfRange = NegativeInteger(Int.MIN_VALUE.toLong() - 1)
assertThrows(CborException::class.java) { negativeOutOfRange.asInteger() }
}

@Test
fun asLong_validValues_success() {
assertThat(UnsignedInteger(0).asLong()).isEqualTo(0L)
assertThat(UnsignedInteger(Long.MAX_VALUE).asLong()).isEqualTo(Long.MAX_VALUE)
assertThat(NegativeInteger(-1).asLong()).isEqualTo(-1L)
assertThat(NegativeInteger(Long.MIN_VALUE).asLong()).isEqualTo(Long.MIN_VALUE)
}

@Test
fun asLong_outOfBounds_throws() {
val unsignedOutOfRange = UnsignedInteger(BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE))
assertThrows(CborException::class.java) { unsignedOutOfRange.asLong() }

val negativeOutOfRange =
NegativeInteger(BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.ONE))
assertThrows(CborException::class.java) { negativeOutOfRange.asLong() }
}
}
Loading