This commit is contained in:
Dain Nilsson 2023-08-31 10:30:04 +02:00
commit 947b9f1079
No known key found for this signature in database
GPG Key ID: F04367096FBA95E8
7 changed files with 55 additions and 18 deletions

View File

@ -405,7 +405,7 @@ class SlotNode(RpcNode):
self.session.put_key(self.slot, private_key, pin_policy, touch_policy)
try:
metadata = self.session.get_slot_metadata(self.slot)
except (ApduError, BadResponseError):
except (ApduError, BadResponseError, NotSupportedError):
pass
certificate = _choose_cert(certs)

View File

@ -71,8 +71,21 @@ class _DesktopOathStateNotifier extends OathStateNotifier {
..setErrorHandler('state-reset', (_) async {
ref.invalidate(_sessionProvider(devicePath));
})
..setErrorHandler('auth-required', (_) async {
ref.invalidateSelf();
..setErrorHandler('auth-required', (e) async {
final key = ref.read(_oathLockKeyProvider(_session.devicePath));
if (key != null) {
final result =
await _session.command('validate', params: {'key': key});
if (result['valid']) {
ref.invalidateSelf();
return;
} else {
ref
.read(_oathLockKeyProvider(_session.devicePath).notifier)
.unsetKey();
}
}
throw e;
});
ref.onDispose(() {
_session
@ -81,17 +94,7 @@ class _DesktopOathStateNotifier extends OathStateNotifier {
});
final result = await _session.command('get');
_log.debug('application status', jsonEncode(result));
var oathState = OathState.fromJson(result['data']);
final key = ref.read(_oathLockKeyProvider(_session.devicePath));
if (oathState.locked && key != null) {
final result = await _session.command('validate', params: {'key': key});
if (result['valid']) {
oathState = oathState.copyWith(locked: false);
} else {
ref.read(_oathLockKeyProvider(_session.devicePath).notifier).unsetKey();
}
}
return oathState;
return OathState.fromJson(result['data']);
}
@override

View File

@ -428,6 +428,8 @@
"l_certificate_exported": "Certificate exported",
"l_import_file": "Import file",
"l_import_desc": "Import a key and/or certificate",
"l_importing_file": "Importing file\u2026",
"s_file_imported": "File imported",
"l_delete_certificate": "Delete certificate",
"l_delete_certificate_desc": "Remove the certificate from your YubiKey",
"s_issuer": "Issuer",

View File

@ -428,6 +428,8 @@
"l_certificate_exported": "証明書がエクスポートされました",
"l_import_file": "ファイルのインポート",
"l_import_desc": "キーや証明書のインポート",
"l_importing_file": "ファイルのインポート中\u2026",
"s_file_imported": "ファイル をインポートしました",
"l_delete_certificate": "証明書を削除",
"l_delete_certificate_desc": "YubiKeyか証明書の削除",
"s_issuer": "発行者",

View File

@ -113,6 +113,7 @@
}
},
"l_import_icon_pack_failed": "Błąd importu pakietu ikon: {message}",
"l_importing_file": "Importowanie pliku…",
"l_insert_or_tap_yk": "Podłącz lub przystaw YubiKey",
"l_insert_yk": "Podłącz klucz YubiKey",
"l_invalid_character_issuer": "Nieprawidłowy znak: „:” nie jest dozwolony w polu wydawcy",
@ -378,6 +379,7 @@
"s_factory_reset": "Ustawienia fabryczne",
"s_fido_disabled": "FIDO2 wyłączone",
"s_fido_pin_protection": "Ochrona FIDO kodem PIN",
"s_file_imported": "Plik został zaimportowany",
"s_fingerprint_added": "Dodano odcisk palca",
"s_fingerprint_deleted": "Odcisk palca został usunięty",
"s_fingerprint_renamed": "Zmieniono nazwę odcisku palca",

View File

@ -70,7 +70,13 @@ Future<void> handleUri(
OathState? state,
AppLocalizations l10n,
) async {
List<CredentialData> creds = CredentialData.fromUri(Uri.parse(qrData));
List<CredentialData> creds;
try {
creds = CredentialData.fromUri(Uri.parse(qrData));
} catch (_) {
showMessage(context, l10n.l_invalid_qr);
return;
}
if (creds.isEmpty) {
showMessage(context, l10n.l_qr_not_found);
} else if (creds.length == 1) {

View File

@ -20,7 +20,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../app/message.dart';
import '../../app/models.dart';
import '../../app/state.dart';
import '../../widgets/responsive_dialog.dart';
import '../models.dart';
import '../state.dart';
@ -47,6 +49,7 @@ class _ImportFileDialogState extends ConsumerState<ImportFileDialog> {
PivExamineResult? _state;
String _password = '';
bool _passwordIsWrong = false;
bool _importing = false;
@override
void initState() {
@ -153,10 +156,10 @@ class _ImportFileDialogState extends ConsumerState<ImportFileDialog> {
actions: [
TextButton(
key: keys.unlockButton,
onPressed: (keyType == null && certInfo == null)
onPressed: (keyType == null && certInfo == null) || _importing
? null
: () async {
final navigator = Navigator.of(context);
final withContext = ref.read(withContextProvider);
if (!await confirmOverwrite(
context,
@ -167,18 +170,37 @@ class _ImportFileDialogState extends ConsumerState<ImportFileDialog> {
return;
}
setState(() {
_importing = true;
});
void Function()? close;
try {
close = await withContext<void Function()>(
(context) async => showMessage(
context,
l10n.l_importing_file,
duration: const Duration(seconds: 30),
));
await ref
.read(pivSlotsProvider(widget.devicePath).notifier)
.import(widget.pivSlot.slot, _data,
password:
_password.isNotEmpty ? _password : null);
navigator.pop(true);
await withContext(
(context) async {
Navigator.of(context).pop(true);
showMessage(context, l10n.s_file_imported);
},
);
} catch (err) {
// TODO: More error cases
setState(() {
_passwordIsWrong = true;
_importing = false;
});
} finally {
close?.call();
}
},
child: Text(l10n.s_import),