Wrap parseGetInfoStructured in Result to propagate errors

This commit is contained in:
mimi89999
2026-04-02 17:49:48 +02:00
parent b931921c78
commit 196ef84e72
3 changed files with 18 additions and 16 deletions
@@ -239,15 +239,18 @@ object CTAP {
return byteArrayOf(cmd.toByte())
}
fun parseGetInfoStructured(response: ByteArray): DeviceInfo? {
fun parseGetInfoStructured(response: ByteArray): Result<DeviceInfo> {
if (!isSuccess(response)) {
return null
return Result.failure(Exception(
getResponseError(response) ?: Error.OTHER
))
}
val data = response.drop(1).toByteArray()
return try {
val parsed = CborMap.decode(data) ?: return null
val parsed = CborMap.decode(data)
?: return Result.failure(Exception("Failed to parse GetInfo response"))
val versions = parsed.list<String>(1) ?: emptyList()
val extensions = parsed.list<String>(2) ?: emptyList()
@@ -279,7 +282,7 @@ object CTAP {
val minPinLength = parsed.int(13)
val firmwareVersion = parsed.int(14)
DeviceInfo(
Result.success(DeviceInfo(
versions = versions,
extensions = extensions,
aaguid = aaguid,
@@ -292,9 +295,9 @@ object CTAP {
algorithms = algorithms,
firmwareVersion = firmwareVersion,
minPinLength = minPinLength
)
))
} catch (e: Exception) {
null
Result.failure(e)
}
}
@@ -510,7 +510,7 @@ class CredentialProviderActivity : AppCompatActivity() {
val infoResponse = withContext(Dispatchers.IO) {
transport.sendCtapCommand(CTAP.buildCommand(CTAP.CMD_GET_INFO))
}
deviceInfo = CTAP.parseGetInfoStructured(infoResponse)
deviceInfo = CTAP.parseGetInfoStructured(infoResponse).getOrThrow()
// Check if clientPin is actually set on the device
val deviceHasPin = deviceInfo?.clientPinSet == true
@@ -486,11 +486,11 @@ class MainActivity : AppCompatActivity() {
}
val deviceInfo = CTAP.parseGetInfoStructured(response)
if (deviceInfo != null) {
deviceInfo.onSuccess {
resultText.text = ""
showDeviceInfoDialog(deviceInfo)
} else {
resultText.text = outputFormatter.formatDeviceInfoError("Failed to parse response")
showDeviceInfoDialog(it)
}.onFailure {
resultText.text = outputFormatter.formatDeviceInfoError(it.message ?: "Failed to parse response")
}
pendingAction = null
@@ -529,8 +529,7 @@ class MainActivity : AppCompatActivity() {
transport.sendCtapCommand(CTAP.buildCommand(CTAP.CMD_GET_INFO))
}
val deviceInfo = CTAP.parseGetInfoStructured(infoResponse)
if (deviceInfo == null) {
val deviceInfo = CTAP.parseGetInfoStructured(infoResponse).getOrElse {
resultText.text = getString(R.string.error_parse_device_info)
pendingAction = null
return@launch
@@ -1020,9 +1019,9 @@ class MainActivity : AppCompatActivity() {
val infoResponse = withContext(Dispatchers.IO) {
transport.sendCtapCommand(CTAP.buildCommand(CTAP.CMD_GET_INFO))
}
val deviceInfo = CTAP.parseGetInfoStructured(infoResponse)
val isPinSet = deviceInfo?.clientPinSet == true
val minPinLength = deviceInfo?.minPinLength ?: 4
val deviceInfo = CTAP.parseGetInfoStructured(infoResponse).getOrThrow()
val isPinSet = deviceInfo.clientPinSet
val minPinLength = deviceInfo.minPinLength ?: 4
val retries = withContext(Dispatchers.IO) { protocol.getPinRetries() }.getOrNull()