diff --git a/proto b/proto index 9305cdc..c2ff3f0 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 9305cdcaeee44337a269db3336193127e38f9e21 +Subproject commit c2ff3f0a1e6cc12320c9353197c3bbba7de50185 diff --git a/src/error.rs b/src/error.rs index 2f7e1d2..8624420 100644 --- a/src/error.rs +++ b/src/error.rs @@ -25,6 +25,8 @@ pub enum WorkerError { IO, #[error("UTF8 conversion failed")] UTF8Conversion, + #[error("Cannot find key serial number")] + SerialNotFound, } impl From for WorkerError { diff --git a/src/gpg.rs b/src/gpg.rs index 9c19a33..35e58ff 100644 --- a/src/gpg.rs +++ b/src/gpg.rs @@ -223,7 +223,8 @@ pub fn factory_reset_key() -> Result<(), WorkerError> { } } -pub fn check_card() -> Result<(), WorkerError> { +// returns serial number of yubikey if detected +pub fn check_card() -> Result { let out = Command::new("ykman") .args(["list"]) .output() @@ -245,9 +246,20 @@ pub fn check_card() -> Result<(), WorkerError> { if keys_found != 1 { return Err(WorkerError::MultipleKeysPresent); } - Ok(()) + let out_split: Vec<&str> = out_str.split_whitespace().collect(); + for (i, &item) in out_split.iter().enumerate() { + if item == "Serial:" { + if let Some(serial) = out_split.get(i + 1) { + return Ok(serial.to_string()); + } else { + return Err(WorkerError::SerialNotFound); + } + } + } + Err(WorkerError::SerialNotFound) } +#[allow(dead_code)] pub fn get_fingerprint() -> Result { let out = Command::new("gpg") .args(["--list-keys"]) @@ -274,7 +286,7 @@ pub fn get_fingerprint() -> Result { pub struct ProvisioningInfo { pub pgp: String, pub ssh: String, - pub fingerprint: String, + pub serial: String, } pub async fn provision_key( @@ -287,10 +299,14 @@ pub async fn provision_key( let check_duration = Duration::from_secs(config.smartcard_retry_interval); let mut check_interval = interval(check_duration); let mut fail_counter = 0; + let serial: String; loop { check_interval.tick().await; match check_card() { - Ok(_) => break, + Ok(res) => { + serial = res; + break; + } Err(e) => match e { WorkerError::NoKeysFound => { info!( @@ -306,7 +322,7 @@ pub async fn provision_key( }, } } - debug!("Key found"); + debug!("Key with serial ({serial}) found"); let (gpg_home, mut gpg_process) = init_gpg()?; debug!("Temporary GPG session crated"); debug!("Resetting card to factory"); @@ -320,7 +336,6 @@ pub async fn provision_key( &job.email, )?; debug!("OpenPGP key for {} created", &job.email); - let fingerprint = get_fingerprint()?; let pgp = export_public(gpg_command, &gpg_home, &job.email)?; let ssh = export_ssh(gpg_command, &gpg_home, &job.email)?; key_to_card(gpg_command, &config.gpg_debug_level, &gpg_home, &job.email)?; @@ -336,9 +351,5 @@ pub async fn provision_key( } debug!("Temp home cleared"); info!("Yubikey openpgp provisioning completed."); - Ok(ProvisioningInfo { - pgp, - ssh, - fingerprint, - }) + Ok(ProvisioningInfo { pgp, ssh, serial }) } diff --git a/src/main.rs b/src/main.rs index 04515c0..d34b6ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -110,7 +110,7 @@ async fn main() -> Result<(), WorkerError> { success: true, public_key: key_info.pgp, ssh_key: key_info.ssh, - fingerprint: key_info.fingerprint, + yubikey_serial: key_info.serial, error: "".into(), }; let request = tonic::Request::new(job_status); @@ -124,7 +124,7 @@ async fn main() -> Result<(), WorkerError> { success: false, public_key: "".into(), ssh_key: "".into(), - fingerprint: "".into(), + yubikey_serial: "".into(), error: err.to_string(), }; let request = tonic::Request::new(job_status);