Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub enum WorkerError {
IO,
#[error("UTF8 conversion failed")]
UTF8Conversion,
#[error("Cannot find key serial number")]
SerialNotFound,
}

impl From<tonic::transport::Error> for WorkerError {
Expand Down
33 changes: 22 additions & 11 deletions src/gpg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, WorkerError> {
let out = Command::new("ykman")
.args(["list"])
.output()
Expand All @@ -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<String, WorkerError> {
let out = Command::new("gpg")
.args(["--list-keys"])
Expand All @@ -274,7 +286,7 @@ pub fn get_fingerprint() -> Result<String, WorkerError> {
pub struct ProvisioningInfo {
pub pgp: String,
pub ssh: String,
pub fingerprint: String,
pub serial: String,
}

pub async fn provision_key(
Expand All @@ -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!(
Expand All @@ -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");
Expand All @@ -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)?;
Expand All @@ -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 })
}
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down