Skip to content

Commit 81c21a4

Browse files
committed
Ensured BIO MPE is handled correctly in PIV banner
1 parent 30125f1 commit 81c21a4

14 files changed

+51
-19
lines changed

lib/app/views/reset_dialog.dart

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class ResetDialog extends ConsumerStatefulWidget {
7373

7474
class _ResetDialogState extends ConsumerState<ResetDialog> {
7575
late Capability? _application;
76+
late bool _globalReset;
7677
StreamSubscription<InteractionEvent>? _subscription;
7778
InteractionEvent? _interaction;
7879
int _currentStep = -1;
@@ -84,7 +85,8 @@ class _ResetDialogState extends ConsumerState<ResetDialog> {
8485
super.initState();
8586
final nfc = widget.data.node.transport == Transport.nfc;
8687
_totalSteps = nfc ? 2 : 3;
87-
_application = widget.application;
88+
_globalReset = _isGlobalReset();
89+
_application = !_globalReset ? widget.application : null;
8890
}
8991

9092
@override
@@ -109,6 +111,20 @@ class _ResetDialogState extends ConsumerState<ResetDialog> {
109111
};
110112
}
111113

114+
bool _isGlobalReset() {
115+
final enabled =
116+
widget.data.info.config.enabledCapabilities[widget
117+
.data
118+
.node
119+
.transport] ??
120+
0;
121+
final isBio = [
122+
FormFactor.usbABio,
123+
FormFactor.usbCBio,
124+
].contains(widget.data.info.formFactor);
125+
return isBio && (enabled & Capability.piv.value) != 0;
126+
}
127+
112128
@override
113129
Widget build(BuildContext context) {
114130
final hasFeature = ref.watch(featureProvider);
@@ -121,11 +137,6 @@ class _ResetDialogState extends ConsumerState<ResetDialog> {
121137
.transport] ??
122138
0;
123139

124-
final isBio = [
125-
FormFactor.usbABio,
126-
FormFactor.usbCBio,
127-
].contains(widget.data.info.formFactor);
128-
final globalReset = isBio && (enabled & Capability.piv.value) != 0;
129140
final l10n = AppLocalizations.of(context);
130141
final usbTransport = widget.data.node.transport == Transport.usb;
131142

@@ -289,7 +300,7 @@ class _ResetDialogState extends ConsumerState<ResetDialog> {
289300
});
290301
},
291302
null =>
292-
globalReset
303+
_globalReset
293304
? () async {
294305
setState(() {
295306
_resetting = true;
@@ -324,7 +335,7 @@ class _ResetDialogState extends ConsumerState<ResetDialog> {
324335
crossAxisAlignment: CrossAxisAlignment.start,
325336
children:
326337
[
327-
if (!globalReset)
338+
if (!_globalReset)
328339
Builder(
329340
builder: (context) {
330341
final width = MediaQuery.of(context).size.width;
@@ -383,7 +394,7 @@ class _ResetDialogState extends ConsumerState<ResetDialog> {
383394
Capability.piv => l10n.p_warning_piv_reset,
384395
Capability.fido2 => l10n.p_warning_deletes_accounts,
385396
_ =>
386-
globalReset
397+
_globalReset
387398
? l10n.p_warning_global_reset
388399
: l10n.p_factory_reset_an_app,
389400
},
@@ -400,7 +411,7 @@ class _ResetDialogState extends ConsumerState<ResetDialog> {
400411
Capability.piv => l10n.p_warning_piv_reset_desc,
401412
Capability.fido2 => l10n.p_warning_disable_accounts,
402413
_ =>
403-
globalReset
414+
_globalReset
404415
? l10n.p_warning_global_reset_desc
405416
: l10n.p_factory_reset_desc,
406417
}),

lib/desktop/piv/state.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ final _sessionProvider = Provider.autoDispose.family<
5151
// Make sure the managementKey and PIN are held for the duration of the session.
5252
ref.watch(_managementKeyProvider(devicePath));
5353
ref.watch(_pinProvider(devicePath));
54+
// Reset the state if resetBlocked is toggled from != 0 to == 0 (as on Global Reset)
55+
ref.listen(currentDeviceDataProvider, (prev, next) {
56+
final prevResetBlocked = prev?.value?.info.resetBlocked;
57+
final nextResetBlocked = next.value?.info.resetBlocked;
58+
if (prevResetBlocked != 0 && nextResetBlocked == 0) {
59+
ref.invalidateSelf();
60+
}
61+
});
5462
return RpcNodeSession(ref.watch(rpcProvider).requireValue, devicePath, [
5563
'ccid',
5664
'piv',

lib/l10n/app_cs.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "Akce, kterou se chystáte provést, vyžaduje zadání kódu PIV PIN.",
389389
"l_piv_pin_blocked": "Zablokováno, pro obnovení použijte PUK",
390390
"p_piv_pin_blocked_desc": "PIN je zablokován. Použijte PUK pro jeho obnovení.",
391+
"l_piv_pin_blocked_bio": null,
391392
"l_piv_pin_puk_blocked": "Zablokováno, je potřeba obnovení továrních nastavení",
392393
"p_piv_pin_puk_blocked_desc": "PIN i PUK jsou zablokovány. Je potřeba resetovat aplikaci PIV.",
393394
"p_new_piv_pin_puk_requirements": "{name} musí mít alespoň {length} znaků.",

lib/l10n/app_de.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "Diese Aktion erfordert die PIV PIN.",
389389
"l_piv_pin_blocked": "Gesperrt, verwende die PUK zum Zurücksetzen",
390390
"p_piv_pin_blocked_desc": "Die PIN ist blockiert. Benutze die PUK um sie zurückzusetzen.",
391+
"l_piv_pin_blocked_bio": null,
391392
"l_piv_pin_puk_blocked": "Gesperrt, Zurücksetzen auf Werkseinstellungen erforderlich",
392393
"p_piv_pin_puk_blocked_desc": "Sowohl die PIN als auch PUK sind blockiert. Die PIV-Anwendung muss zurückgesetzt werden.",
393394
"p_new_piv_pin_puk_requirements": "Eine {name} muss mindestens {length} Zeichen lang sein.",

lib/l10n/app_en.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "The action you are about to perform requires the PIV PIN to be entered.",
389389
"l_piv_pin_blocked": "Blocked, use PUK to reset",
390390
"p_piv_pin_blocked_desc": "The PIN is blocked. Use the PUK to reset it.",
391+
"l_piv_pin_blocked_bio": "The PIN is blocked. A factory reset is required.",
391392
"l_piv_pin_puk_blocked": "Blocked, factory reset needed",
392393
"p_piv_pin_puk_blocked_desc": "Both the PIN and PUK are blocked. A factory reset of the PIV application is required.",
393394
"p_new_piv_pin_puk_requirements": "A {name} must be at least {length} characters long.",

lib/l10n/app_fr.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "L'action que vous allez effectuer nécessite la saisie du PIN PIV.",
389389
"l_piv_pin_blocked": "Bloqué, utilisez PUK pour réinitialiser",
390390
"p_piv_pin_blocked_desc": "Le code PIN est bloqué. Utilisez le code PUK pour le réinitialiser.",
391+
"l_piv_pin_blocked_bio": null,
391392
"l_piv_pin_puk_blocked": "Bloqué, réinitialisation aux paramètres d'usine nécessaire",
392393
"p_piv_pin_puk_blocked_desc": "Le code PIN et le code PUK sont tous deux bloqués. Une réinitialisation d'usine de l'application PIV est nécessaire.",
393394
"p_new_piv_pin_puk_requirements": "Le {name} doit avoir au moins {length} caractères.",

lib/l10n/app_ja.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "実行しようとしているアクションでは、PIV PINを入力する必要があります。",
389389
"l_piv_pin_blocked": "ブロックされています。リセットするにはPUKを使用してください",
390390
"p_piv_pin_blocked_desc": "PIN がブロックされています。PUK を使用してリセットしてください。",
391+
"l_piv_pin_blocked_bio": null,
391392
"l_piv_pin_puk_blocked": "ブロックされています。工場出荷時の状態にリセットする必要があります",
392393
"p_piv_pin_puk_blocked_desc": "PIN と PUK の両方がブロックされています。PIV アプリケーションの工場出荷時リセットが必要です。",
393394
"p_new_piv_pin_puk_requirements": "{name} は {length} 文字以上で設定してください。",

lib/l10n/app_pl.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "Działanie wymaga wpisania kodu PIN PIV.",
389389
"l_piv_pin_blocked": "Zablokowano. Użyj kodu PUK, aby zresetować",
390390
"p_piv_pin_blocked_desc": "Kod PIN jest zablokowany. Użyj kodu PUK, aby zresetować.",
391+
"l_piv_pin_blocked_bio": null,
391392
"l_piv_pin_puk_blocked": "Zablokowano. Wymagane jest przywrócenie ustawień fabrycznych",
392393
"p_piv_pin_puk_blocked_desc": "Kody PIN i PUK są zablokowane. Wymagane jest przywrócenie ustawień fabrycznych aplikacji PIV.",
393394
"p_new_piv_pin_puk_requirements": "{name} musi składać się z co najmniej {length} znaków.",

lib/l10n/app_sk.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "Akcia, ktorú sa chystáte vykonať, vyžaduje zadanie kódu PIV PIN.",
389389
"l_piv_pin_blocked": "Zablokované, na obnovenie použite PUK",
390390
"p_piv_pin_blocked_desc": "PIN kód je zablokovaný. Na jeho obnovenie použite PUK.",
391+
"l_piv_pin_blocked_bio": null,
391392
"l_piv_pin_puk_blocked": "Zablokované, je potrebné obnovenie výrobných nastavení",
392393
"p_piv_pin_puk_blocked_desc": "PIN aj PUK sú zablokované. Vyžaduje sa obnovenie výrobných nastavení aplikácie PIV.",
393394
"p_new_piv_pin_puk_requirements": "{name} musí mať aspoň {length} znakov.",

lib/l10n/app_sv.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "Den åtgärd du ska utföra kräver att du anger PIV PIN-koden.",
389389
"l_piv_pin_blocked": "Blockerad, använd PUK för att återställa",
390390
"p_piv_pin_blocked_desc": "PIN-koden är blockerad. Använd PUK för att återställa den.",
391+
"l_piv_pin_blocked_bio": null,
391392
"l_piv_pin_puk_blocked": "Blockerad, fabriksåterställning krävs",
392393
"p_piv_pin_puk_blocked_desc": "Både PIN och PUK är blockerade. En fabriksåterställning av PIV applikationen krävs.",
393394
"p_new_piv_pin_puk_requirements": "A {name} must be at least {length} characters long.",

lib/l10n/app_vi.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "Hành động bạn sắp thực hiện yêu cầu phải nhập Mã PIN PIV.",
389389
"l_piv_pin_blocked": "Bị khóa, sử dụng PUK để khôi phục",
390390
"p_piv_pin_blocked_desc": "The PIN is blocked. Use the PUK to reset it.",
391+
"l_piv_pin_blocked_bio": null,
391392
"l_piv_pin_puk_blocked": "Bị khóa, cần khôi phục cài đặt gốc",
392393
"p_piv_pin_puk_blocked_desc": "Both the PIN and PUK are blocked. A factory reset of the PIV application is required.",
393394
"p_new_piv_pin_puk_requirements": "A {name} must be at least {length} characters long.",

lib/l10n/app_zh.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@
388388
"p_pin_required_desc": "您将要执行的操作需要输入 PIV PIN 。",
389389
"l_piv_pin_blocked": "已封禁,请使用 PUK 以重置",
390390
"p_piv_pin_blocked_desc": "PIN 已被封禁。请使用 PUK 重置。",
391+
"l_piv_pin_blocked_bio": null,
391392
"l_piv_pin_puk_blocked": "已封禁,需要出厂重置",
392393
"p_piv_pin_puk_blocked_desc": "PIN 和 PUK 均被封禁。需要对 PIV 应用程序进行出厂重置。",
393394
"p_new_piv_pin_puk_requirements": "{name} 的长度必须至少为 {length} 个字符。",

lib/piv/views/key_actions.dart

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616

1717
import 'package:flutter/material.dart';
1818

19-
import 'package:flutter_riverpod/flutter_riverpod.dart';
2019
import 'package:material_symbols_icons/symbols.dart';
2120

2221
import '../../app/message.dart';
2322
import '../../app/models.dart';
24-
import '../../app/state.dart';
2523
import '../../app/views/action_list.dart';
2624
import '../../generated/l10n/app_localizations.dart';
2725
import '../../management/models.dart';
@@ -42,9 +40,8 @@ bool pivShowActionsNotifier(PivState state) {
4240

4341
Widget pivBuildActions(
4442
BuildContext context,
45-
DevicePath devicePath,
43+
YubiKeyData data,
4644
PivState pivState,
47-
WidgetRef ref,
4845
) {
4946
final colors =
5047
Theme.of(context).buttonTheme.colorScheme ??
@@ -60,11 +57,11 @@ Widget pivBuildActions(
6057
final pukAttempts = pivState.metadata?.pukMetadata.attemptsRemaining;
6158
final alertIcon = Icon(Symbols.warning_amber, color: colors.tertiary);
6259

63-
final deviceData = ref.read(currentDeviceDataProvider).valueOrNull;
60+
final devicePath = data.node.path;
6461
final isBio = [
6562
FormFactor.usbABio,
6663
FormFactor.usbCBio,
67-
].contains(deviceData?.info.formFactor);
64+
].contains(data.info.formFactor);
6865

6966
return Column(
7067
children: [

lib/piv/views/piv_screen.dart

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,8 @@ class _PivScreenState extends ConsumerState<PivScreen> {
242242
hasFeature(features.actions)
243243
? (context) => pivBuildActions(
244244
context,
245-
widget.data.node.path,
245+
widget.data,
246246
pivState,
247-
ref,
248247
)
249248
: null,
250249
keyActionsBadge: pivShowActionsNotifier(pivState),
@@ -258,6 +257,11 @@ class _PivScreenState extends ConsumerState<PivScreen> {
258257
});
259258
}
260259

260+
final isBio = [
261+
FormFactor.usbABio,
262+
FormFactor.usbCBio,
263+
].contains(widget.data.info.formFactor);
264+
261265
final usingDefaultPin =
262266
pivState.metadata?.pinMetadata.defaultValue == true;
263267
final pinBlocked = pivState.pinAttempts == 0;
@@ -293,7 +297,9 @@ class _PivScreenState extends ConsumerState<PivScreen> {
293297
MaterialBanner(
294298
padding: EdgeInsets.all(18),
295299
content: Text(
296-
pukAttempts == 0
300+
isBio
301+
? l10n.l_piv_pin_blocked_bio
302+
: pukAttempts == 0
297303
? l10n.p_piv_pin_puk_blocked_desc
298304
: l10n.p_piv_pin_blocked_desc,
299305
),

0 commit comments

Comments
 (0)