From d2132b4ac2c560b6b00fe36baf321361e38323c9 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 11 Feb 2023 02:45:30 +0000 Subject: [PATCH] Prevent changing the default PIN to itself Closes str4d/age-plugin-yubikey#120. --- CHANGELOG.md | 2 ++ i18n/en-US/age_plugin_yubikey.ftl | 1 + src/key.rs | 35 ++++++++++++++++++------------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31680cb..63f3c65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ to 0.3.0 are beta releases. - When `age-plugin-yubikey` assists the user in changing their PIN from the default PIN, it no longer tells the user that PINs shorter than 6 characters are allowed, and instead loops until the user enters a PIN of valid length. + It also now prevents the user from setting their PIN to the default PIN, to + avoid creating a cycle. - More kinds of SmartCard readers are ignored when they have no SmartCard inserted. diff --git a/i18n/en-US/age_plugin_yubikey.ftl b/i18n/en-US/age_plugin_yubikey.ftl index b5315ac..a84e19c 100644 --- a/i18n/en-US/age_plugin_yubikey.ftl +++ b/i18n/en-US/age_plugin_yubikey.ftl @@ -135,6 +135,7 @@ mgr-enter-current-puk = Enter current PUK (default is {$default_puk}) mgr-choose-new-pin = Choose a new PIN/PUK mgr-repeat-new-pin = Repeat the PIN/PUK mgr-pin-mismatch = PINs don't match +mgr-nope-default-pin = You entered the default PIN again. You need to change it. mgr-changing-mgmt-key = ✨ Your {-yubikey} is using the default management key. diff --git a/src/key.rs b/src/key.rs index 0eb47a5..9aa81ed 100644 --- a/src/key.rs +++ b/src/key.rs @@ -284,20 +284,27 @@ pub(crate) fn manage(yubikey: &mut YubiKey) -> Result<(), Error> { let current_puk = Password::new() .with_prompt(fl!("mgr-enter-current-puk", default_puk = DEFAULT_PUK)) .interact()?; - let new_pin = request_pin( - |prev_error| { - if let Some(err) = prev_error { - eprintln!("{}", err); - } - Password::new() - .with_prompt(fl!("mgr-choose-new-pin")) - .with_confirmation(fl!("mgr-repeat-new-pin"), fl!("mgr-pin-mismatch")) - .interact() - .map(|pin| Result::<_, Infallible>::Ok(SecretString::new(pin))) - }, - yubikey.serial(), - )? - .unwrap(); + let new_pin = loop { + let pin = request_pin( + |prev_error| { + if let Some(err) = prev_error { + eprintln!("{}", err); + } + Password::new() + .with_prompt(fl!("mgr-choose-new-pin")) + .with_confirmation(fl!("mgr-repeat-new-pin"), fl!("mgr-pin-mismatch")) + .interact() + .map(|pin| Result::<_, Infallible>::Ok(SecretString::new(pin))) + }, + yubikey.serial(), + )? + .unwrap(); + if pin.expose_secret() == DEFAULT_PIN { + eprintln!("{}", fl!("mgr-nope-default-pin")); + } else { + break pin; + } + }; let new_pin = new_pin.expose_secret(); yubikey.change_puk(current_puk.as_bytes(), new_pin.as_bytes())?; yubikey.change_pin(pin.as_bytes(), new_pin.as_bytes())?;