This commit is contained in:
Adam Velebil 2023-01-20 16:01:40 +01:00
commit 750b87d125
No known key found for this signature in database
GPG Key ID: C9B1E4A3CBBD2E10
3 changed files with 57 additions and 19 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022 Yubico.
* Copyright (C) 2022-2023 Yubico.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,7 +23,10 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import com.yubico.authenticator.*
import com.yubico.authenticator.device.Capabilities
import com.yubico.authenticator.device.Config
import com.yubico.authenticator.device.Info
import com.yubico.authenticator.device.Version
import com.yubico.authenticator.logging.Log
import com.yubico.authenticator.oath.keystore.ClearingMemProvider
import com.yubico.authenticator.oath.keystore.KeyStoreProvider
@ -39,6 +42,7 @@ import com.yubico.yubikit.core.smartcard.SW
import com.yubico.yubikit.core.smartcard.SmartCardConnection
import com.yubico.yubikit.core.smartcard.SmartCardProtocol
import com.yubico.yubikit.core.util.Result
import com.yubico.yubikit.management.FormFactor
import com.yubico.yubikit.oath.*
import com.yubico.yubikit.support.DeviceUtil
import io.flutter.plugin.common.BinaryMessenger
@ -293,9 +297,35 @@ class OathManager(
// OATH not enabled/supported, try to get DeviceInfo over other USB interfaces
Log.e(TAG, "Failed to connect to CCID", e.toString())
if (device.transport == Transport.USB || e is ApplicationNotAvailableException) {
val deviceInfoData = getDeviceInfo(device)
Log.d(TAG, "Sending device info: $deviceInfoData")
appViewModel.setDeviceInfo(deviceInfoData)
val deviceInfo = try {
getDeviceInfo(device)
} catch (e: IllegalArgumentException) {
Log.d(TAG, "Device was not recognized")
Info(
config = Config(
deviceFlags = null,
challengeResponseTimeout = null,
autoEjectTimeout = null,
enabledCapabilities = Capabilities()
),
serialNumber = null,
version = Version(0, 0, 0),
formFactor = FormFactor.UNKNOWN.value,
isLocked = false,
isSky = false,
isFips = false,
name = "Unrecognized device",
isNfc = device.transport == Transport.NFC,
usbPid = null,
supportedCapabilities = Capabilities()
)
} catch (e: Exception) {
Log.d(TAG, "Failure getting device info: ${e.message}")
null
}
Log.d(TAG, "Setting device info: $deviceInfo")
appViewModel.setDeviceInfo(deviceInfo)
}
// Clear any cached OATH state

View File

@ -27,24 +27,27 @@ import com.yubico.yubikit.core.otp.OtpConnection
import com.yubico.yubikit.core.smartcard.SmartCardConnection
import com.yubico.yubikit.management.DeviceInfo
import com.yubico.yubikit.support.DeviceUtil
import java.io.IOException
suspend fun getDeviceInfo(device: YubiKeyDevice): Info {
val pid = (device as? UsbYubiKeyDevice)?.pid
val deviceInfo = runCatching {
val deviceInfo = try {
device.withConnection<SmartCardConnection, DeviceInfo> { DeviceUtil.readInfo(it, pid) }
}.recoverCatching {
Log.d(OathManager.TAG, "Smart card connection not available")
device.withConnection<OtpConnection, DeviceInfo> { DeviceUtil.readInfo(it, pid) }
}.recoverCatching {
Log.d(OathManager.TAG, "OTP connection not available")
device.withConnection<FidoConnection, DeviceInfo> { DeviceUtil.readInfo(it, pid) }
}.recoverCatching {
Log.d(OathManager.TAG, "FIDO connection not available")
return SkyHelper.getDeviceInfo(device)
}.getOrElse {
Log.e(OathManager.TAG, "Failed to recognize device")
throw it
} catch (e: IOException) {
runCatching {
Log.d(OathManager.TAG, "Smart card connection not available: ${e.message}")
device.withConnection<OtpConnection, DeviceInfo> { DeviceUtil.readInfo(it, pid) }
}.recoverCatching { t ->
Log.d(OathManager.TAG, "OTP connection not available: ${t.message}")
device.withConnection<FidoConnection, DeviceInfo> { DeviceUtil.readInfo(it, pid) }
}.recoverCatching { t ->
Log.d(OathManager.TAG, "FIDO connection not available: ${t.message}")
return SkyHelper.getDeviceInfo(device)
}.getOrElse {
Log.e(OathManager.TAG, "Failed to recognize device: ${it.message}")
throw it
}
}
val name = DeviceUtil.getName(deviceInfo, pid?.type)

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022 Yubico.
* Copyright (C) 2022-2023 Yubico.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -113,7 +113,12 @@ class MainPage extends ConsumerWidget {
return ref.watch(currentDeviceDataProvider).when(
data: (data) {
final app = ref.watch(currentAppProvider);
if (app.getAvailability(data) == Availability.unsupported) {
if (data.info.supportedCapabilities.isEmpty &&
data.name == 'Unrecognized device') {
return const MessagePage(
header: 'Device not recognized',
);
} else if (app.getAvailability(data) == Availability.unsupported) {
return MessagePage(
header: 'Application not supported',
message: