From 1f0d555cea1a6dd55bb20bbd9ffb41c23b4954e6 Mon Sep 17 00:00:00 2001 From: shimun Date: Fri, 15 Apr 2022 17:06:11 +0200 Subject: [PATCH] added: comment field to luks header data --- src/cli.rs | 26 +++++++++++++++++++++++--- src/cli_args/mod.rs | 6 ++++++ src/luks.rs | 27 +++++++++++++++++++++------ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 26653e9..c4239de 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -330,6 +330,7 @@ pub fn run_cli() -> Fido2LuksResult<()> { Command::AddKey { exclusive, generate_credential, + comment, .. } => { let (existing_secret, existing_credential) = @@ -339,7 +340,14 @@ pub fn run_cli() -> Fido2LuksResult<()> { .as_ref() .map(core::slice::from_ref) .unwrap_or_default(); - existing_credential.iter().for_each(|cred| log(&|| format!("using credential to unlock container: {}", hex::encode(&cred.id)))); + existing_credential.iter().for_each(|cred| { + log(&|| { + format!( + "using credential to unlock container: {}", + hex::encode(&cred.id) + ) + }) + }); let (new_secret, cred) = if *generate_credential && luks2 { let cred = make_credential_id( Some(derive_credential_name(luks.device.as_path()).as_str()), @@ -372,6 +380,7 @@ pub fn run_cli() -> Fido2LuksResult<()> { Some(&cred.id[..]) .filter(|_| !luks.disable_token || *generate_credential) .filter(|_| luks2), + comment.as_deref().map(String::from), )?; if *exclusive { let destroyed = luks_dev.remove_keyslots(&[added_slot])?; @@ -407,6 +416,7 @@ pub fn run_cli() -> Fido2LuksResult<()> { .filter(|_| !luks.disable_token) .filter(|_| luks2) .map(|cred| &cred.id[..]), + None, ) } else { let slot = luks_dev.replace_key( @@ -554,8 +564,13 @@ pub fn run_cli() -> Fido2LuksResult<()> { continue; } println!( - "{}:\n\tSlots: {}\n\tCredentials: {}", + "{}{}:\n\tSlots: {}\n\tCredentials: {}", id, + token + .comment + .as_deref() + .map(|comment| format!(" - {}", comment)) + .unwrap_or_default(), if token.keyslots.is_empty() { "None".into() } else { @@ -581,6 +596,7 @@ pub fn run_cli() -> Fido2LuksResult<()> { TokenCommand::Add { device, credentials, + comment, slot, } => { let mut dev = LuksDevice::load(device)?; @@ -592,7 +608,11 @@ pub fn run_cli() -> Fido2LuksResult<()> { } } let count = if tokens.is_empty() { - dev.add_token(&Fido2LuksToken::with_credentials(&credentials.0, *slot))?; + dev.add_token(&Fido2LuksToken::with_credentials( + &credentials.0, + *slot, + comment.as_deref().map(String::from), + ))?; 1 } else { tokens.len() diff --git a/src/cli_args/mod.rs b/src/cli_args/mod.rs index b884939..618b8f2 100644 --- a/src/cli_args/mod.rs +++ b/src/cli_args/mod.rs @@ -189,6 +189,9 @@ pub enum Command { luks: LuksParameters, #[structopt(flatten)] credentials: Credentials, + /// Comment to be associated with this credential + #[structopt(long = "comment")] + comment: Option, #[structopt(flatten)] authenticator: AuthenticatorParameters, #[structopt(flatten)] @@ -295,6 +298,9 @@ pub enum TokenCommand { long = "creds" )] credentials: CommaSeparated, + /// Comment to be associated with this credential + #[structopt(long = "comment")] + comment: Option, /// Slot to which the credentials will be added #[structopt(long = "slot", env = "FIDO2LUKS_DEVICE_SLOT")] slot: u32, diff --git a/src/luks.rs b/src/luks.rs index 5ad6d5c..dc14d6a 100644 --- a/src/luks.rs +++ b/src/luks.rs @@ -142,6 +142,7 @@ impl LuksDevice { old_secret: &[u8], iteration_time: Option, credential_id: Option<&[u8]>, + comment: Option, ) -> Fido2LuksResult { if let Some(millis) = iteration_time { self.device.settings_handle().set_iteration_time(millis) @@ -152,7 +153,7 @@ impl LuksDevice { .add_by_passphrase(None, old_secret, secret)?; if let Some(id) = credential_id { self.device.token_handle().json_set(TokenInput::AddToken( - &serde_json::to_value(&Fido2LuksToken::new(id, slot)).unwrap(), + &serde_json::to_value(&Fido2LuksToken::new(id, slot, comment)).unwrap(), ))?; } @@ -216,9 +217,18 @@ impl LuksDevice { )? as u32; if let Some(id) = credential_id { if self.is_luks2()? { - let token = self.find_token(slot)?.map(|(t, _)| t); - let json = serde_json::to_value(&Fido2LuksToken::new(id, slot)).unwrap(); - if let Some(token) = token { + let (token_id, token_data) = match self.find_token(slot)? { + Some((id, data)) => (Some(id), Some(data)), + _ => (None, None), + }; + let json = serde_json::to_value(&Fido2LuksToken::new( + id, + slot, + // retain comment on replace + token_data.map(|data| data.comment).flatten(), + )) + .unwrap(); + if let Some(token) = token_id { self.device .token_handle() .json_set(TokenInput::ReplaceToken(token, &json))?; @@ -315,16 +325,19 @@ pub struct Fido2LuksToken { pub type_: String, pub credential: HashSet, pub keyslots: HashSet, + #[serde(skip_serializing_if = "Option::is_none")] + pub comment: Option, } impl Fido2LuksToken { - pub fn new(credential_id: impl AsRef<[u8]>, slot: u32) -> Self { - Self::with_credentials(std::iter::once(credential_id), slot) + pub fn new(credential_id: impl AsRef<[u8]>, slot: u32, comment: Option) -> Self { + Self::with_credentials(std::iter::once(credential_id), slot, comment) } pub fn with_credentials, B: AsRef<[u8]>>( credentials: I, slot: u32, + comment: Option, ) -> Self { Self { credential: credentials @@ -332,6 +345,7 @@ impl Fido2LuksToken { .map(|cred| hex::encode(cred.as_ref())) .collect(), keyslots: vec![slot.to_string()].into_iter().collect(), + comment, ..Default::default() } } @@ -346,6 +360,7 @@ impl Default for Fido2LuksToken { type_: Self::default_type().into(), credential: HashSet::new(), keyslots: HashSet::new(), + comment: None, } } }