PIV: Add MATCH policies

This commit is contained in:
Dain Nilsson 2024-08-16 14:36:57 +02:00
parent 1a4935b2aa
commit 11d4c6ed35
No known key found for this signature in database
GPG Key ID: F04367096FBA95E8
8 changed files with 64 additions and 9 deletions

View File

@ -656,7 +656,9 @@
"p_subject_desc": null,
"l_rfc4514_invalid": null,
"rfc4514_examples": null,
"s_allow_fingerprint": null,
"p_cert_options_desc": null,
"p_cert_options_bio_desc": null,
"s_overwrite_slot": null,
"p_overwrite_slot_desc": null,
"@p_overwrite_slot_desc": {

View File

@ -656,7 +656,9 @@
"p_subject_desc": "A distinguished name (DN) formatted in accordance to the RFC 4514 specification.",
"l_rfc4514_invalid": "Invalid RFC 4514 format",
"rfc4514_examples": "Examples:\nCN=Example Name\nCN=jsmith,DC=example,DC=net",
"s_allow_fingerprint": "Allow fingerprint",
"p_cert_options_desc": "Key algorithm to use, output format, and expiration date (certificate only).",
"p_cert_options_bio_desc": "Key algorithm to use, output format, expiration date (certificate only), and if biometrics can be used instead of PIN.",
"s_overwrite_slot": "Overwrite slot",
"p_overwrite_slot_desc": "This will permanently overwrite existing content in slot {slot}.",
"@p_overwrite_slot_desc": {

View File

@ -656,7 +656,9 @@
"p_subject_desc": "DN (nom distinctif) formaté conformément à la spécification RFC 4514.",
"l_rfc4514_invalid": "Format RFC 4514 non valide",
"rfc4514_examples": "Exemples\u00a0:\nCN=exemple de nom\nCN=jsmith,DC=exemple,DC=net",
"s_allow_fingerprint": null,
"p_cert_options_desc": "Algorithme clé à utiliser, format de sortie et date d'expiration (certificat uniquement).",
"p_cert_options_bio_desc": null,
"s_overwrite_slot": "Écraser slot",
"p_overwrite_slot_desc": "Cela écrasera définitivement le contenu du slot {slot}.",
"@p_overwrite_slot_desc": {

View File

@ -656,7 +656,9 @@
"p_subject_desc": "RFC 4514仕様に準拠した形式の識別名DN。",
"l_rfc4514_invalid": "無効なRFC 4514形式",
"rfc4514_examples": "例:\nCN=Example Name CN=jsmith,DC=example,\nDC=net",
"s_allow_fingerprint": null,
"p_cert_options_desc": "使用する鍵アルゴリズム、出力形式、および有効期限(証明書のみ)。",
"p_cert_options_bio_desc": null,
"s_overwrite_slot": "スロットを上書き",
"p_overwrite_slot_desc": "これにより、スロット{slot}内の既存コンテンツが完全に上書きされます。",
"@p_overwrite_slot_desc": {

View File

@ -656,7 +656,9 @@
"p_subject_desc": "Nazwa wyróżniająca (DN) sformatowana zgodnie ze specyfikacją RFC 4514.",
"l_rfc4514_invalid": "Nieprawidłowy format RFC 4514",
"rfc4514_examples": "Przykłady:\nCN=Przykładowa Nazwa\nCN=jkowalski,DC=przyklad,DC=pl",
"s_allow_fingerprint": null,
"p_cert_options_desc": "Algorytm klucza do użycia, format wyjściowy i data wygaśnięcia (tylko certyfikat).",
"p_cert_options_bio_desc": null,
"s_overwrite_slot": "Nadpisz slot",
"p_overwrite_slot_desc": "Spowoduje to trwałe nadpisanie istniejącej zawartości w slocie {slot}.",
"@p_overwrite_slot_desc": {

View File

@ -36,8 +36,9 @@ class GenerateKeyDialog extends ConsumerStatefulWidget {
final DevicePath devicePath;
final PivState pivState;
final PivSlot pivSlot;
const GenerateKeyDialog(this.devicePath, this.pivState, this.pivSlot,
{super.key});
final bool showMatch;
GenerateKeyDialog(this.devicePath, this.pivState, this.pivSlot, {super.key})
: showMatch = pivSlot.slot != SlotId.cardAuth && pivState.supportsBio;
@override
ConsumerState<ConsumerStatefulWidget> createState() =>
@ -53,6 +54,7 @@ class _GenerateKeyDialogState extends ConsumerState<GenerateKeyDialog> {
late DateTime _validTo;
late DateTime _validToDefault;
late DateTime _validToMax;
late bool _allowMatch;
bool _generating = false;
@override
@ -64,6 +66,8 @@ class _GenerateKeyDialogState extends ConsumerState<GenerateKeyDialog> {
_validToDefault = DateTime.utc(now.year + 1, now.month, now.day);
_validTo = _validToDefault;
_validToMax = DateTime.utc(now.year + 10, now.month, now.day);
_allowMatch = widget.showMatch;
}
@override
@ -117,6 +121,7 @@ class _GenerateKeyDialogState extends ConsumerState<GenerateKeyDialog> {
final result = await pivNotifier.generate(
widget.pivSlot.slot,
_keyType,
pinPolicy: getPinPolicy(widget.pivSlot.slot, _allowMatch),
parameters: switch (_generateType) {
GenerateType.publicKey =>
PivGenerateParameters.publicKey(),
@ -183,7 +188,9 @@ class _GenerateKeyDialogState extends ConsumerState<GenerateKeyDialog> {
l10n.s_options,
style: textTheme.bodyLarge,
),
Text(l10n.p_cert_options_desc),
Text(widget.showMatch
? l10n.p_cert_options_bio_desc
: l10n.p_cert_options_desc),
Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 4.0,
@ -238,6 +245,16 @@ class _GenerateKeyDialogState extends ConsumerState<GenerateKeyDialog> {
}
},
),
if (widget.showMatch)
FilterChip(
label: Text(l10n.s_allow_fingerprint),
selected: _allowMatch,
onSelected: (value) {
setState(() {
_allowMatch = value;
});
},
),
]),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4),

View File

@ -39,9 +39,10 @@ class ImportFileDialog extends ConsumerStatefulWidget {
final PivState pivState;
final PivSlot pivSlot;
final File file;
const ImportFileDialog(
this.devicePath, this.pivState, this.pivSlot, this.file,
{super.key});
final bool showMatch;
ImportFileDialog(this.devicePath, this.pivState, this.pivSlot, this.file,
{super.key})
: showMatch = pivSlot.slot != SlotId.cardAuth && pivState.supportsBio;
@override
ConsumerState<ConsumerStatefulWidget> createState() =>
@ -50,6 +51,7 @@ class ImportFileDialog extends ConsumerStatefulWidget {
class _ImportFileDialogState extends ConsumerState<ImportFileDialog> {
late String _data;
late bool _allowMatch;
PivExamineResult? _state;
String _password = '';
bool _passwordIsWrong = false;
@ -59,6 +61,8 @@ class _ImportFileDialogState extends ConsumerState<ImportFileDialog> {
@override
void initState() {
super.initState();
_allowMatch = widget.showMatch;
_init();
}
@ -214,9 +218,13 @@ class _ImportFileDialogState extends ConsumerState<ImportFileDialog> {
));
await ref
.read(pivSlotsProvider(widget.devicePath).notifier)
.import(widget.pivSlot.slot, _data,
password:
_password.isNotEmpty ? _password : null);
.import(
widget.pivSlot.slot,
_data,
password: _password.isNotEmpty ? _password : null,
pinPolicy: getPinPolicy(
widget.pivSlot.slot, _allowMatch),
);
await withContext(
(context) async {
Navigator.of(context).pop(true);
@ -284,6 +292,16 @@ class _ImportFileDialogState extends ConsumerState<ImportFileDialog> {
),
],
),
if (!unsupportedKey && widget.showMatch)
FilterChip(
label: Text(l10n.s_allow_fingerprint),
selected: _allowMatch,
onSelected: (value) {
setState(() {
_allowMatch = value;
});
},
),
],
if (certInfo != null) ...[
Text(

View File

@ -29,3 +29,13 @@ List<KeyType> getSupportedKeyTypes(Version version, bool isFips) => [
KeyType.eccp256,
KeyType.eccp384,
];
PinPolicy getPinPolicy(SlotId slot, bool match) {
if (match) {
if (slot == SlotId.signature) {
return PinPolicy.matchAlways;
}
return PinPolicy.matchOnce;
}
return PinPolicy.dfault;
}