added: comment field to luks header data

This commit is contained in:
shimun 2022-04-15 17:06:11 +02:00
parent 2255f224a5
commit 1f0d555cea
Signed by: shimun
GPG Key ID: E81D8382DC2F971B
3 changed files with 50 additions and 9 deletions

View File

@ -330,6 +330,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
Command::AddKey { Command::AddKey {
exclusive, exclusive,
generate_credential, generate_credential,
comment,
.. ..
} => { } => {
let (existing_secret, existing_credential) = let (existing_secret, existing_credential) =
@ -339,7 +340,14 @@ pub fn run_cli() -> Fido2LuksResult<()> {
.as_ref() .as_ref()
.map(core::slice::from_ref) .map(core::slice::from_ref)
.unwrap_or_default(); .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 (new_secret, cred) = if *generate_credential && luks2 {
let cred = make_credential_id( let cred = make_credential_id(
Some(derive_credential_name(luks.device.as_path()).as_str()), Some(derive_credential_name(luks.device.as_path()).as_str()),
@ -372,6 +380,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
Some(&cred.id[..]) Some(&cred.id[..])
.filter(|_| !luks.disable_token || *generate_credential) .filter(|_| !luks.disable_token || *generate_credential)
.filter(|_| luks2), .filter(|_| luks2),
comment.as_deref().map(String::from),
)?; )?;
if *exclusive { if *exclusive {
let destroyed = luks_dev.remove_keyslots(&[added_slot])?; let destroyed = luks_dev.remove_keyslots(&[added_slot])?;
@ -407,6 +416,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
.filter(|_| !luks.disable_token) .filter(|_| !luks.disable_token)
.filter(|_| luks2) .filter(|_| luks2)
.map(|cred| &cred.id[..]), .map(|cred| &cred.id[..]),
None,
) )
} else { } else {
let slot = luks_dev.replace_key( let slot = luks_dev.replace_key(
@ -554,8 +564,13 @@ pub fn run_cli() -> Fido2LuksResult<()> {
continue; continue;
} }
println!( println!(
"{}:\n\tSlots: {}\n\tCredentials: {}", "{}{}:\n\tSlots: {}\n\tCredentials: {}",
id, id,
token
.comment
.as_deref()
.map(|comment| format!(" - {}", comment))
.unwrap_or_default(),
if token.keyslots.is_empty() { if token.keyslots.is_empty() {
"None".into() "None".into()
} else { } else {
@ -581,6 +596,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
TokenCommand::Add { TokenCommand::Add {
device, device,
credentials, credentials,
comment,
slot, slot,
} => { } => {
let mut dev = LuksDevice::load(device)?; let mut dev = LuksDevice::load(device)?;
@ -592,7 +608,11 @@ pub fn run_cli() -> Fido2LuksResult<()> {
} }
} }
let count = if tokens.is_empty() { 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 1
} else { } else {
tokens.len() tokens.len()

View File

@ -189,6 +189,9 @@ pub enum Command {
luks: LuksParameters, luks: LuksParameters,
#[structopt(flatten)] #[structopt(flatten)]
credentials: Credentials, credentials: Credentials,
/// Comment to be associated with this credential
#[structopt(long = "comment")]
comment: Option<String>,
#[structopt(flatten)] #[structopt(flatten)]
authenticator: AuthenticatorParameters, authenticator: AuthenticatorParameters,
#[structopt(flatten)] #[structopt(flatten)]
@ -295,6 +298,9 @@ pub enum TokenCommand {
long = "creds" long = "creds"
)] )]
credentials: CommaSeparated<HexEncoded>, credentials: CommaSeparated<HexEncoded>,
/// Comment to be associated with this credential
#[structopt(long = "comment")]
comment: Option<String>,
/// Slot to which the credentials will be added /// Slot to which the credentials will be added
#[structopt(long = "slot", env = "FIDO2LUKS_DEVICE_SLOT")] #[structopt(long = "slot", env = "FIDO2LUKS_DEVICE_SLOT")]
slot: u32, slot: u32,

View File

@ -142,6 +142,7 @@ impl LuksDevice {
old_secret: &[u8], old_secret: &[u8],
iteration_time: Option<u64>, iteration_time: Option<u64>,
credential_id: Option<&[u8]>, credential_id: Option<&[u8]>,
comment: Option<String>,
) -> Fido2LuksResult<u32> { ) -> Fido2LuksResult<u32> {
if let Some(millis) = iteration_time { if let Some(millis) = iteration_time {
self.device.settings_handle().set_iteration_time(millis) self.device.settings_handle().set_iteration_time(millis)
@ -152,7 +153,7 @@ impl LuksDevice {
.add_by_passphrase(None, old_secret, secret)?; .add_by_passphrase(None, old_secret, secret)?;
if let Some(id) = credential_id { if let Some(id) = credential_id {
self.device.token_handle().json_set(TokenInput::AddToken( 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; )? as u32;
if let Some(id) = credential_id { if let Some(id) = credential_id {
if self.is_luks2()? { if self.is_luks2()? {
let token = self.find_token(slot)?.map(|(t, _)| t); let (token_id, token_data) = match self.find_token(slot)? {
let json = serde_json::to_value(&Fido2LuksToken::new(id, slot)).unwrap(); Some((id, data)) => (Some(id), Some(data)),
if let Some(token) = token { _ => (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 self.device
.token_handle() .token_handle()
.json_set(TokenInput::ReplaceToken(token, &json))?; .json_set(TokenInput::ReplaceToken(token, &json))?;
@ -315,16 +325,19 @@ pub struct Fido2LuksToken {
pub type_: String, pub type_: String,
pub credential: HashSet<String>, pub credential: HashSet<String>,
pub keyslots: HashSet<String>, pub keyslots: HashSet<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
} }
impl Fido2LuksToken { impl Fido2LuksToken {
pub fn new(credential_id: impl AsRef<[u8]>, slot: u32) -> Self { pub fn new(credential_id: impl AsRef<[u8]>, slot: u32, comment: Option<String>) -> Self {
Self::with_credentials(std::iter::once(credential_id), slot) Self::with_credentials(std::iter::once(credential_id), slot, comment)
} }
pub fn with_credentials<I: IntoIterator<Item = B>, B: AsRef<[u8]>>( pub fn with_credentials<I: IntoIterator<Item = B>, B: AsRef<[u8]>>(
credentials: I, credentials: I,
slot: u32, slot: u32,
comment: Option<String>,
) -> Self { ) -> Self {
Self { Self {
credential: credentials credential: credentials
@ -332,6 +345,7 @@ impl Fido2LuksToken {
.map(|cred| hex::encode(cred.as_ref())) .map(|cred| hex::encode(cred.as_ref()))
.collect(), .collect(),
keyslots: vec![slot.to_string()].into_iter().collect(), keyslots: vec![slot.to_string()].into_iter().collect(),
comment,
..Default::default() ..Default::default()
} }
} }
@ -346,6 +360,7 @@ impl Default for Fido2LuksToken {
type_: Self::default_type().into(), type_: Self::default_type().into(),
credential: HashSet::new(), credential: HashSet::new(),
keyslots: HashSet::new(), keyslots: HashSet::new(),
comment: None,
} }
} }
} }