diff --git a/i18n/en-US/age_plugin_yubikey.ftl b/i18n/en-US/age_plugin_yubikey.ftl index 9129c7a..42e115d 100644 --- a/i18n/en-US/age_plugin_yubikey.ftl +++ b/i18n/en-US/age_plugin_yubikey.ftl @@ -187,8 +187,12 @@ plugin-err-pin-required = A PIN is required for {-yubikey} with serial {$yub ## Errors +err-mgmt-key-auth = Failed to authenticate with the PIN-protected management key. +rec-mgmt-key-auth = + Check whether your management key is using the TDES algorithm. + AES is not supported yet: {$aes_url} err-custom-mgmt-key = Custom unprotected non-TDES management keys are not supported. -rec-custom-mgmt-key = +rec-change-mgmt-key = You can use the {-yubikey} Manager CLI to change to a protected management key: {" "}{$cmd} diff --git a/src/error.rs b/src/error.rs index 3a48a0b..1674ffa 100644 --- a/src/error.rs +++ b/src/error.rs @@ -21,6 +21,7 @@ pub enum Error { InvalidSlot(u8), InvalidTouchPolicy(String), Io(io::Error), + ManagementKeyAuth, MultipleCommands, MultipleYubiKeys, NoEmptySlots(Serial), @@ -50,12 +51,19 @@ impl From for Error { // manually to provide the error output we want. impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + const CHANGE_MGMT_KEY_CMD: &str = + "ykman piv access change-management-key -a TDES --protect"; + const CHANGE_MGMT_KEY_URL: &str = "https://developers.yubico.com/yubikey-manager/"; + match self { Error::CustomManagementKey => { wlnfl!(f, "err-custom-mgmt-key")?; - let cmd = "ykman piv access change-management-key --protect"; - let url = "https://developers.yubico.com/yubikey-manager/"; - wlnfl!(f, "rec-custom-mgmt-key", cmd = cmd, url = url)?; + wlnfl!( + f, + "rec-change-mgmt-key", + cmd = CHANGE_MGMT_KEY_CMD, + url = CHANGE_MGMT_KEY_URL + )?; } Error::InvalidFlagCommand(flag, command) => wlnfl!( f, @@ -78,6 +86,17 @@ impl fmt::Debug for Error { expected = "always, cached, never", )?, Error::Io(e) => wlnfl!(f, "err-io", err = e.to_string())?, + Error::ManagementKeyAuth => { + let aes_url = "https://github.com/str4d/age-plugin-yubikey/issues/92"; + wlnfl!(f, "err-mgmt-key-auth")?; + wlnfl!(f, "rec-mgmt-key-auth", aes_url = aes_url)?; + wlnfl!( + f, + "rec-change-mgmt-key", + cmd = CHANGE_MGMT_KEY_CMD, + url = CHANGE_MGMT_KEY_URL + )?; + } Error::MultipleCommands => wlnfl!(f, "err-multiple-commands")?, Error::MultipleYubiKeys => wlnfl!(f, "err-multiple-yubikeys")?, Error::NoEmptySlots(serial) => { diff --git a/src/key.rs b/src/key.rs index b942c21..d86a0ad 100644 --- a/src/key.rs +++ b/src/key.rs @@ -354,30 +354,35 @@ pub(crate) fn manage(yubikey: &mut YubiKey) -> Result<(), Error> { yubikey.change_pin(pin.as_bytes(), new_pin.as_bytes())?; } - if let Ok(mgm_key) = MgmKey::get_protected(yubikey) { - yubikey.authenticate(mgm_key)?; - } else { - // Try to authenticate with the default management key. - yubikey - .authenticate(MgmKey::default()) - .map_err(|_| Error::CustomManagementKey)?; + match MgmKey::get_protected(yubikey) { + Ok(mgm_key) => yubikey.authenticate(mgm_key).map_err(|e| match e { + yubikey::Error::AuthenticationError => Error::ManagementKeyAuth, + _ => e.into(), + })?, + Err(yubikey::Error::AuthenticationError) => Err(Error::ManagementKeyAuth)?, + _ => { + // Try to authenticate with the default management key. + yubikey + .authenticate(MgmKey::default()) + .map_err(|_| Error::CustomManagementKey)?; - // Migrate to a PIN-protected management key. - let mgm_key = MgmKey::generate(); - eprintln!(); - eprintln!("{}", fl!("mgr-changing-mgmt-key")); - eprint!("... "); - mgm_key.set_protected(yubikey).map_err(|e| { - eprintln!( - "{}", - fl!( - "mgr-changing-mgmt-key-error", - management_key = hex::encode(mgm_key.as_ref()), - ) - ); - e - })?; - eprintln!("{}", fl!("mgr-changing-mgmt-key-success")); + // Migrate to a PIN-protected management key. + let mgm_key = MgmKey::generate(); + eprintln!(); + eprintln!("{}", fl!("mgr-changing-mgmt-key")); + eprint!("... "); + mgm_key.set_protected(yubikey).map_err(|e| { + eprintln!( + "{}", + fl!( + "mgr-changing-mgmt-key-error", + management_key = hex::encode(mgm_key.as_ref()), + ) + ); + e + })?; + eprintln!("{}", fl!("mgr-changing-mgmt-key-success")); + } } Ok(())