From a35875a51e388c01c3941149f38e42fa13068a8c Mon Sep 17 00:00:00 2001 From: Dain Nilsson Date: Wed, 28 Aug 2024 11:12:23 +0200 Subject: [PATCH 1/4] Desktop: Improve DeviceInfo caching --- helper/helper/device.py | 18 ++++++++++++++---- helper/helper/piv.py | 6 ++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/helper/helper/device.py b/helper/helper/device.py index 34f44e3f..a2db4192 100644 --- a/helper/helper/device.py +++ b/helper/helper/device.py @@ -274,9 +274,6 @@ class AbstractDeviceNode(RpcNode): # Clear DeviceInfo cache self._info = None self._data = None - # Make sure any child node is re-opened after this, - # as enabled applications may have changed - super().close() return response @@ -465,7 +462,20 @@ class ConnectionNode(RpcNode): def __call__(self, *args, **kwargs): try: - return super().__call__(*args, **kwargs) + response = super().__call__(*args, **kwargs) + if "device_info" in response.flags: + # Refresh DeviceInfo + info = read_info(self._connection, self._device.pid) + if self._info != info: + self._info = info + # Make sure any child node is re-opened after this, + # as enabled applications may have changed + self.close() + else: + # No change to DeviceInfo, further propagation not needed. + response.flags.remove("device_info") + + return response except (SmartcardException, OSError) as e: logger.exception("Connection error") raise ChildResetException(f"{e}") diff --git a/helper/helper/piv.py b/helper/helper/piv.py index f1b9c198..7045343b 100644 --- a/helper/helper/piv.py +++ b/helper/helper/piv.py @@ -502,7 +502,7 @@ class SlotNode(RpcNode): self._refresh() - return dict( + response = dict( metadata=_metadata_dict(metadata), public_key=( private_key.public_key() @@ -519,6 +519,7 @@ class SlotNode(RpcNode): else None ), ) + return RpcResponse(response, ["device_info"]) @action def generate(self, params, event, signal): @@ -570,4 +571,5 @@ class SlotNode(RpcNode): self._refresh() - return dict(public_key=public_key_pem, result=result) + response = dict(public_key=public_key_pem, result=result) + return RpcResponse(response, ["device_info"]) From 06dbe65d0a2a63807724bdd6ce79a0b8a314519b Mon Sep 17 00:00:00 2001 From: Dain Nilsson Date: Wed, 28 Aug 2024 14:41:31 +0200 Subject: [PATCH 2/4] Finalize UI for PIV when not FIPS approved --- lib/l10n/app_de.arb | 1 + lib/l10n/app_en.arb | 1 + lib/l10n/app_fr.arb | 1 + lib/l10n/app_ja.arb | 1 + lib/l10n/app_pl.arb | 1 + lib/piv/views/actions.dart | 18 ++++++++++++++---- 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 9400d885..740cdc6d 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -587,6 +587,7 @@ "l_delete_certificate_or_key_desc": "Entfernen Sie das Zertifikat oder den Schlüssel von Ihrem YubiKey", "l_move_key": "Schlüssel verschieben", "l_move_key_desc": "Verschieben Sie einen Schlüssel von einem PIV-Slot in einen anderen", + "l_change_defaults": null, "s_issuer": "Aussteller", "s_serial": "Serial", "s_certificate_fingerprint": "Fingerprint", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 9954b87e..760fa084 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -587,6 +587,7 @@ "l_delete_certificate_or_key_desc": "Remove the certificate or key from your YubiKey", "l_move_key": "Move key", "l_move_key_desc": "Move a key from one PIV slot into another", + "l_change_defaults": "Change default access codes", "s_issuer": "Issuer", "s_serial": "Serial", "s_certificate_fingerprint": "Fingerprint", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 9e43e088..7b920e21 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -587,6 +587,7 @@ "l_delete_certificate_or_key_desc": "Supprimer le certificat ou la clé de votre YubiKey", "l_move_key": "Déplacer la clé", "l_move_key_desc": "Déplacer une clé d'un emplacement PIV vers un autre", + "l_change_defaults": null, "s_issuer": "Émetteur", "s_serial": "Série", "s_certificate_fingerprint": "Empreinte digitale", diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index 09ac00a0..cfeed76e 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -587,6 +587,7 @@ "l_delete_certificate_or_key_desc": "YubiKey から証明書または鍵を削除する", "l_move_key": "キーを移動", "l_move_key_desc": "あるPIVスロットから別のスロットにキーを移動する", + "l_change_defaults": null, "s_issuer": "発行者", "s_serial": "シリアル", "s_certificate_fingerprint": "フィンガープリント", diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 50623db1..1b106a97 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -587,6 +587,7 @@ "l_delete_certificate_or_key_desc": null, "l_move_key": null, "l_move_key_desc": null, + "l_change_defaults": null, "s_issuer": "Wydawca", "s_serial": "Nr. seryjny", "s_certificate_fingerprint": "Odcisk palca", diff --git a/lib/piv/views/actions.dart b/lib/piv/views/actions.dart index aef2627e..86d54222 100644 --- a/lib/piv/views/actions.dart +++ b/lib/piv/views/actions.dart @@ -312,12 +312,22 @@ class PivActions extends ConsumerWidget { List buildSlotActions( PivState pivState, PivSlot slot, bool fipsUnready, AppLocalizations l10n) { if (fipsUnready) { - // TODO: Decide on final look and move strings to .arb file. return [ ActionItem( - icon: const Icon(Symbols.add), - title: 'Provision slot', - subtitle: 'Change from default PIN/PUK/Management key first'), + key: keys.generateAction, + feature: features.slotsGenerate, + icon: const Icon(Symbols.add), + actionStyle: ActionStyle.primary, + title: l10n.s_generate_key, + subtitle: l10n.l_change_defaults, + ), + ActionItem( + key: keys.importAction, + feature: features.slotsImport, + icon: const Icon(Symbols.file_download), + title: l10n.l_import_file, + subtitle: l10n.l_change_defaults, + ), ]; } final hasCert = slot.certInfo != null; From 4e421c431484b114f2871e75e96a492554c51e25 Mon Sep 17 00:00:00 2001 From: Elias Bonnici Date: Thu, 29 Aug 2024 15:47:56 +0200 Subject: [PATCH 3/4] Add missing return from delete FIDO credential --- helper/helper/fido.py | 1 + 1 file changed, 1 insertion(+) diff --git a/helper/helper/fido.py b/helper/helper/fido.py index e3d71149..9c2f3d9d 100644 --- a/helper/helper/fido.py +++ b/helper/helper/fido.py @@ -333,6 +333,7 @@ class CredentialNode(RpcNode): def delete(self, params, event, signal): self.credman.delete_cred(self.data["credential_id"]) self.refresh_rps() + return dict() class FingerprintsNode(RpcNode): From 868c47cbf466d9f4477a19ab03dc8fcabb533158 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Fri, 30 Aug 2024 11:03:32 +0200 Subject: [PATCH 4/4] bump deps, add support for version override --- android/app/build.gradle | 6 +++--- .../authenticator/yubikit/DeviceInfoHelper.kt | 13 ++++++++++++- android/build.gradle | 2 +- .../qrscanner_zxing/android/build.gradle | 4 ++-- android/settings.gradle | 6 +++--- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 18fd04a0..88e47aa9 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -91,13 +91,13 @@ dependencies { api "com.yubico.yubikit:fido:$project.yubiKitVersion" api "com.yubico.yubikit:support:$project.yubiKitVersion" - implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3' + implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1' // Lifecycle - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4' implementation "androidx.core:core-ktx:1.13.1" - implementation 'androidx.fragment:fragment-ktx:1.8.1' + implementation 'androidx.fragment:fragment-ktx:1.8.2' implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'com.google.android.material:material:1.12.0' diff --git a/android/app/src/main/kotlin/com/yubico/authenticator/yubikit/DeviceInfoHelper.kt b/android/app/src/main/kotlin/com/yubico/authenticator/yubikit/DeviceInfoHelper.kt index dd038e54..a0f04d77 100644 --- a/android/app/src/main/kotlin/com/yubico/authenticator/yubikit/DeviceInfoHelper.kt +++ b/android/app/src/main/kotlin/com/yubico/authenticator/yubikit/DeviceInfoHelper.kt @@ -24,8 +24,10 @@ import com.yubico.authenticator.device.unknownFido2DeviceInfo import com.yubico.authenticator.device.unknownOathDeviceInfo import com.yubico.yubikit.android.transport.nfc.NfcYubiKeyDevice import com.yubico.yubikit.android.transport.usb.UsbYubiKeyDevice +import com.yubico.yubikit.core.Version import com.yubico.yubikit.core.YubiKeyDevice import com.yubico.yubikit.core.application.ApplicationNotAvailableException +import com.yubico.yubikit.core.application.SessionVersionOverride import com.yubico.yubikit.core.fido.FidoConnection import com.yubico.yubikit.core.otp.OtpConnection import com.yubico.yubikit.core.smartcard.Apdu @@ -46,8 +48,17 @@ class DeviceInfoHelper { byteArrayOf(0x00, 0x1F, 0xD1.toByte(), 0x01, 0x1b, 0x55, 0x04) + uri suspend fun getDeviceInfo(device: YubiKeyDevice): Info? { - val pid = (device as? UsbYubiKeyDevice)?.pid + SessionVersionOverride.set(null) + var deviceInfo = readDeviceInfo(device) + if (deviceInfo?.version?.major == 0.toByte()) { + SessionVersionOverride.set(Version(5, 7, 2)) + deviceInfo = readDeviceInfo(device) + } + return deviceInfo + } + private suspend fun readDeviceInfo(device: YubiKeyDevice): Info? { + val pid = (device as? UsbYubiKeyDevice)?.pid val deviceInfo = runCatching { device.withConnection { diff --git a/android/build.gradle b/android/build.gradle index f48ac0bb..ba755aee 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -9,7 +9,7 @@ allprojects { targetSdkVersion = 34 compileSdkVersion = 34 - yubiKitVersion = "2.7.0-alpha01" + yubiKitVersion = "2.7.0" junitVersion = "4.13.2" mockitoVersion = "5.12.0" } diff --git a/android/flutter_plugins/qrscanner_zxing/android/build.gradle b/android/flutter_plugins/qrscanner_zxing/android/build.gradle index d28ad156..cceb6c3a 100644 --- a/android/flutter_plugins/qrscanner_zxing/android/build.gradle +++ b/android/flutter_plugins/qrscanner_zxing/android/build.gradle @@ -2,14 +2,14 @@ group 'com.yubico.authenticator.flutter_plugins.qrscanner_zxing' version '1.0' buildscript { - ext.kotlin_version = '2.0.0' + ext.kotlin_version = '2.0.20' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.5.0' + classpath 'com.android.tools.build:gradle:8.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/android/settings.gradle b/android/settings.gradle index 5c254c38..1ee8c8b2 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -26,9 +26,9 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.5.0" apply false - id "org.jetbrains.kotlin.android" version "2.0.0" apply false - id "org.jetbrains.kotlin.plugin.serialization" version "2.0.0" apply false + id "com.android.application" version "8.5.2" apply false + id "org.jetbrains.kotlin.android" version "2.0.20" apply false + id "org.jetbrains.kotlin.plugin.serialization" version "2.0.20" apply false id "com.google.android.gms.oss-licenses-plugin" version "0.10.6" apply false }