From e86cd8113c828eac0083dc0336fc1a51e645e2a1 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 12 Feb 2023 20:47:58 +0000 Subject: [PATCH] Intercept PIN errors and replace with PUK errors as necessary Once iqlusioninc/yubikey.rs#479 is part of a `yubikey` release we can migrate to, this will mean that users get correctly notified of incorrect PUK entry, instead of being told it is an incorrect PIN issue. --- i18n/en-US/age_plugin_yubikey.ftl | 7 ++++++- src/error.rs | 11 ++++++++++- src/key.rs | 8 +++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/i18n/en-US/age_plugin_yubikey.ftl b/i18n/en-US/age_plugin_yubikey.ftl index 08d4f24..8783093 100644 --- a/i18n/en-US/age_plugin_yubikey.ftl +++ b/i18n/en-US/age_plugin_yubikey.ftl @@ -223,10 +223,15 @@ rec-yk-no-service-win = {" "}{$url} err-yk-not-found = Please insert the {-yubikey} you want to set up -err-yk-wrong-pin = Invalid PIN ({$tries} tries remaining before it is blocked) err-yk-general = Error while communicating with {-yubikey}: {$err} err-yk-general-cause = Cause: {$inner_err} +err-yk-wrong-pin = Invalid {$pin_kind} ({$tries -> + [one] {$tries} try remaining + *[other] {$tries} tries remaining +} before it is blocked) +err-yk-pin-locked = {$pin_kind} locked + err-ux-A = Did this not do what you expected? Could an error be more useful? err-ux-B = Tell us # Put (len(A) - len(B) - 46) spaces here. diff --git a/src/error.rs b/src/error.rs index 5987001..b71335b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -25,10 +25,12 @@ pub enum Error { MultipleYubiKeys, NoEmptySlots(Serial), NoMatchingSerial(Serial), + PukLocked, SlotHasNoIdentity(RetiredSlotId), SlotIsNotEmpty(RetiredSlotId), TimedOut, UseListForSingleSlot, + WrongPuk(u8), YubiKey(yubikey::Error), } @@ -84,6 +86,7 @@ impl fmt::Debug for Error { Error::NoMatchingSerial(serial) => { wlnfl!(f, "err-no-matching-serial", serial = serial.to_string())? } + Error::PukLocked => wlnfl!(f, "err-yk-pin-locked", pin_kind = "PUK")?, Error::SlotHasNoIdentity(slot) => { wlnfl!(f, "err-slot-has-no-identity", slot = slot_to_ui(slot))? } @@ -92,6 +95,9 @@ impl fmt::Debug for Error { } Error::TimedOut => wlnfl!(f, "err-timed-out")?, Error::UseListForSingleSlot => wlnfl!(f, "err-use-list-for-single")?, + Error::WrongPuk(tries) => { + wlnfl!(f, "err-yk-wrong-pin", pin_kind = "PUK", tries = tries)? + } Error::YubiKey(e) => match e { yubikey::Error::NotFound => wlnfl!(f, "err-yk-not-found")?, yubikey::Error::PcscError { @@ -135,7 +141,10 @@ impl fmt::Debug for Error { wlnfl!(f, "rec-yk-no-service-pcscd", apt = apt)?; } } - yubikey::Error::WrongPin { tries } => wlnfl!(f, "err-yk-wrong-pin", tries = tries)?, + yubikey::Error::PinLocked => wlnfl!(f, "err-yk-pin-locked", pin_kind = "PIN")?, + yubikey::Error::WrongPin { tries } => { + wlnfl!(f, "err-yk-wrong-pin", pin_kind = "PIN", tries = tries)? + } e => { wlnfl!(f, "err-yk-general", err = e.to_string())?; use std::error::Error; diff --git a/src/key.rs b/src/key.rs index bb1dfd0..ca23248 100644 --- a/src/key.rs +++ b/src/key.rs @@ -333,7 +333,13 @@ pub(crate) fn manage(yubikey: &mut YubiKey) -> Result<(), Error> { } }; let new_pin = new_pin.expose_secret(); - yubikey.change_puk(current_puk.as_bytes(), new_pin.as_bytes())?; + yubikey + .change_puk(current_puk.as_bytes(), new_pin.as_bytes()) + .map_err(|e| match e { + yubikey::Error::PinLocked => Error::PukLocked, + yubikey::Error::WrongPin { tries } => Error::WrongPuk(tries), + _ => Error::YubiKey(e), + })?; yubikey.change_pin(pin.as_bytes(), new_pin.as_bytes())?; }