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())?; }