Update device info after setPin and reset

This commit is contained in:
Adam Velebil 2024-09-02 14:52:04 +02:00
parent 8717854374
commit 4019675bfd
No known key found for this signature in database
GPG Key ID: C9B1E4A3CBBD2E10
3 changed files with 23 additions and 4 deletions

View File

@ -21,6 +21,7 @@ import com.yubico.authenticator.DialogManager
import com.yubico.authenticator.DialogTitle import com.yubico.authenticator.DialogTitle
import com.yubico.authenticator.device.DeviceManager import com.yubico.authenticator.device.DeviceManager
import com.yubico.authenticator.fido.data.YubiKitFidoSession import com.yubico.authenticator.fido.data.YubiKitFidoSession
import com.yubico.authenticator.yubikit.DeviceInfoHelper.Companion.getDeviceInfo
import com.yubico.authenticator.yubikit.withConnection import com.yubico.authenticator.yubikit.withConnection
import com.yubico.yubikit.android.transport.usb.UsbYubiKeyDevice import com.yubico.yubikit.android.transport.usb.UsbYubiKeyDevice
import com.yubico.yubikit.core.fido.FidoConnection import com.yubico.yubikit.core.fido.FidoConnection
@ -51,18 +52,25 @@ class FidoConnectionHelper(
suspend fun <T> useSession( suspend fun <T> useSession(
actionDescription: FidoActionDescription, actionDescription: FidoActionDescription,
updateDeviceInfo: Boolean = false,
action: (YubiKitFidoSession) -> T action: (YubiKitFidoSession) -> T
): T { ): T {
FidoManager.updateDeviceInfo.set(updateDeviceInfo)
return deviceManager.withKey( return deviceManager.withKey(
onNfc = { useSessionNfc(actionDescription,action) }, onNfc = { useSessionNfc(actionDescription,action) },
onUsb = { useSessionUsb(it, action) }) onUsb = { useSessionUsb(it, updateDeviceInfo, action) })
} }
suspend fun <T> useSessionUsb( suspend fun <T> useSessionUsb(
device: UsbYubiKeyDevice, device: UsbYubiKeyDevice,
updateDeviceInfo: Boolean = false,
block: (YubiKitFidoSession) -> T block: (YubiKitFidoSession) -> T
): T = device.withConnection<FidoConnection, T> { ): T = device.withConnection<FidoConnection, T> {
block(YubiKitFidoSession(it)) block(YubiKitFidoSession(it))
}.also {
if (updateDeviceInfo) {
deviceManager.setDeviceInfo(getDeviceInfo(device))
}
} }
suspend fun <T> useSessionNfc( suspend fun <T> useSessionNfc(

View File

@ -30,6 +30,7 @@ import com.yubico.authenticator.fido.data.Session
import com.yubico.authenticator.fido.data.SessionInfo import com.yubico.authenticator.fido.data.SessionInfo
import com.yubico.authenticator.fido.data.YubiKitFidoSession import com.yubico.authenticator.fido.data.YubiKitFidoSession
import com.yubico.authenticator.setHandler import com.yubico.authenticator.setHandler
import com.yubico.authenticator.yubikit.DeviceInfoHelper.Companion.getDeviceInfo
import com.yubico.authenticator.yubikit.withConnection import com.yubico.authenticator.yubikit.withConnection
import com.yubico.yubikit.android.transport.nfc.NfcYubiKeyDevice import com.yubico.yubikit.android.transport.nfc.NfcYubiKeyDevice
import com.yubico.yubikit.core.YubiKeyConnection import com.yubico.yubikit.core.YubiKeyConnection
@ -61,6 +62,7 @@ import org.slf4j.LoggerFactory
import java.io.IOException import java.io.IOException
import java.util.Arrays import java.util.Arrays
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicBoolean
typealias FidoAction = (Result<YubiKitFidoSession, Exception>) -> Unit typealias FidoAction = (Result<YubiKitFidoSession, Exception>) -> Unit
@ -80,6 +82,7 @@ class FidoManager(
} }
companion object { companion object {
val updateDeviceInfo = AtomicBoolean(false)
fun getPreferredPinUvAuthProtocol(infoData: InfoData): PinUvAuthProtocol { fun getPreferredPinUvAuthProtocol(infoData: InfoData): PinUvAuthProtocol {
val pinUvAuthProtocols = infoData.pinUvAuthProtocols val pinUvAuthProtocols = infoData.pinUvAuthProtocols
val pinSupported = infoData.options["clientPin"] != null val pinSupported = infoData.options["clientPin"] != null
@ -120,6 +123,8 @@ class FidoManager(
pinStore pinStore
) )
init { init {
pinRetries = null pinRetries = null
@ -187,6 +192,10 @@ class FidoManager(
processYubiKey(connection, device) processYubiKey(connection, device)
} }
} }
if (updateDeviceInfo.getAndSet(false)) {
deviceManager.setDeviceInfo(getDeviceInfo(device))
}
} catch (e: Exception) { } catch (e: Exception) {
// something went wrong, try to get DeviceInfo from any available connection type // something went wrong, try to get DeviceInfo from any available connection type
logger.error("Failure when processing YubiKey: ", e) logger.error("Failure when processing YubiKey: ", e)
@ -380,7 +389,7 @@ class FidoManager(
} }
private suspend fun setPin(pin: CharArray?, newPin: CharArray): String = private suspend fun setPin(pin: CharArray?, newPin: CharArray): String =
connectionHelper.useSession(FidoActionDescription.SetPin) { fidoSession -> connectionHelper.useSession(FidoActionDescription.SetPin, updateDeviceInfo = true) { fidoSession ->
try { try {
val clientPin = val clientPin =
ClientPin(fidoSession, getPreferredPinUvAuthProtocol(fidoSession.cachedInfo)) ClientPin(fidoSession, getPreferredPinUvAuthProtocol(fidoSession.cachedInfo))

View File

@ -162,8 +162,9 @@ class FidoResetHelper(
coroutineScope.launch(Dispatchers.Main) { coroutineScope.launch(Dispatchers.Main) {
fidoViewModel.updateResetState(FidoResetState.Touch) fidoViewModel.updateResetState(FidoResetState.Touch)
logger.debug("Waiting for touch") logger.debug("Waiting for touch")
deviceManager.withKey { usbYubiKeyDevice -> deviceManager.withKey {
connectionHelper.useSessionUsb(usbYubiKeyDevice) { fidoSession -> usbYubiKeyDevice ->
connectionHelper.useSessionUsb(usbYubiKeyDevice, updateDeviceInfo = true) { fidoSession ->
resetCommandState = CommandState() resetCommandState = CommandState()
try { try {
if (cancelReset) { if (cancelReset) {
@ -211,6 +212,7 @@ class FidoResetHelper(
coroutineScope.launch { coroutineScope.launch {
fidoViewModel.updateResetState(FidoResetState.Touch) fidoViewModel.updateResetState(FidoResetState.Touch)
try { try {
FidoManager.updateDeviceInfo.set(true)
connectionHelper.useSessionNfc(FidoActionDescription.Reset) { fidoSession -> connectionHelper.useSessionNfc(FidoActionDescription.Reset) { fidoSession ->
doReset(fidoSession) doReset(fidoSession)
continuation.resume(Unit) continuation.resume(Unit)