diff --git a/src/error.rs b/src/error.rs index 6662137..2f5ed81 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,7 +2,7 @@ use std::fmt; use std::io; use yubikey_piv::{key::RetiredSlotId, Serial}; -use crate::USABLE_SLOTS; +use crate::util::slot_to_ui; pub enum Error { CustomManagementKey, @@ -84,12 +84,12 @@ impl fmt::Debug for Error { Error::SlotHasNoIdentity(slot) => writeln!( f, "Slot {} does not contain an age identity or compatible key.", - USABLE_SLOTS.iter().position(|s| s == slot).unwrap() + 1 + slot_to_ui(slot) )?, Error::SlotIsNotEmpty(slot) => writeln!( f, "Slot {} is not empty. Use --force to overwrite the slot.", - USABLE_SLOTS.iter().position(|s| s == slot).unwrap() + 1 + slot_to_ui(slot) )?, Error::TimedOut => { writeln!(f, "Timed out while waiting for a YubiKey to be inserted.")? diff --git a/src/main.rs b/src/main.rs index e6b9088..16d4027 100644 --- a/src/main.rs +++ b/src/main.rs @@ -100,15 +100,7 @@ struct PluginOptions { fn generate(opts: PluginOptions) -> Result<(), Error> { let serial = opts.serial.map(|s| s.into()); - let slot = opts - .slot - .map(|slot| { - USABLE_SLOTS - .get(slot as usize - 1) - .cloned() - .ok_or(Error::InvalidSlot(slot)) - }) - .transpose()?; + let slot = opts.slot.map(util::ui_to_slot).transpose()?; let pin_policy = opts .pin_policy .map(util::pin_policy_from_string) @@ -134,15 +126,7 @@ fn generate(opts: PluginOptions) -> Result<(), Error> { fn identity(opts: PluginOptions) -> Result<(), Error> { let serial = opts.serial.map(|s| s.into()); - let slot = opts - .slot - .map(|slot| { - USABLE_SLOTS - .get(slot as usize - 1) - .cloned() - .ok_or(Error::InvalidSlot(slot)) - }) - .transpose()?; + let slot = opts.slot.map(util::ui_to_slot).transpose()?; let mut yubikey = yubikey::open(serial)?; @@ -240,8 +224,7 @@ fn list(all: bool) -> Result<(), Error> { println!( "# Serial: {}, Slot: {}", yubikey.serial(), - // Use 1-indexing in the UI for niceness - USABLE_SLOTS.iter().position(|s| s == &slot).unwrap() + 1, + util::slot_to_ui(&slot), ); println!("# Name: {}", name); println!("# Created: {}", created); diff --git a/src/util.rs b/src/util.rs index 0a027a1..2f7c074 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,13 +1,27 @@ use x509_parser::{certificate::X509Certificate, der_parser::oid::Oid}; use yubikey_piv::{ + key::RetiredSlotId, policy::{PinPolicy, TouchPolicy}, Key, YubiKey, }; -use crate::{error::Error, p256::Recipient, yubikey::Stub, PLUGIN_NAME}; +use crate::{error::Error, p256::Recipient, yubikey::Stub, PLUGIN_NAME, USABLE_SLOTS}; pub(crate) const POLICY_EXTENSION_OID: &[u64] = &[1, 3, 6, 1, 4, 1, 41482, 3, 8]; +pub(crate) fn ui_to_slot(slot: u8) -> Result { + // Use 1-indexing in the UI for niceness + USABLE_SLOTS + .get(slot as usize - 1) + .cloned() + .ok_or(Error::InvalidSlot(slot)) +} + +pub(crate) fn slot_to_ui(slot: &RetiredSlotId) -> u8 { + // Use 1-indexing in the UI for niceness + USABLE_SLOTS.iter().position(|s| s == slot).unwrap() as u8 + 1 +} + pub(crate) fn pin_policy_from_string(s: String) -> Result { match s.as_str() { "always" => Ok(PinPolicy::Always),