From eed2dad08fc86ed028e55767ab31e53f49121acc Mon Sep 17 00:00:00 2001 From: shimun Date: Sun, 21 Jun 2020 22:28:34 +0200 Subject: [PATCH] create new token if none exists --- src/cli.rs | 18 +++++++++++++----- src/luks.rs | 23 ++++++++++++++++++++--- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 20cd88c..0e0de73 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -12,7 +12,7 @@ use std::io::Write; use std::process::exit; use std::thread; -use crate::luks::LuksDevice; +use crate::luks::{Fido2LuksToken, LuksDevice}; use crate::util::sha256; use std::borrow::Cow; use std::collections::HashSet; @@ -27,6 +27,12 @@ impl Display for HexEncoded { } } +impl AsRef<[u8]> for HexEncoded { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + impl FromStr for HexEncoded { type Err = hex::FromHexError; @@ -628,10 +634,12 @@ pub fn run_cli() -> Fido2LuksResult<()> { tokens.push((id, token)); } } - if tokens.is_empty() { - unimplemented!("// TODO: create new token") - } - let count = tokens.len(); + let count = if tokens.is_empty() { + dev.add_token(&Fido2LuksToken::with_credentials(&credentials.ids.0, *slot))?; + 1 + } else { + tokens.len() + }; for (id, mut token) in tokens { token .credential diff --git a/src/luks.rs b/src/luks.rs index ce96c48..2c6b9df 100644 --- a/src/luks.rs +++ b/src/luks.rs @@ -87,6 +87,13 @@ impl LuksDevice { Ok(None) } + pub fn add_token(&mut self, data: &Fido2LuksToken) -> Fido2LuksResult<()> { + self.device + .token_handle() + .json_set(TokenInput::AddToken(&serde_json::to_value(&data).unwrap()))?; + Ok(()) + } + pub fn remove_token(&mut self, token: u32) -> Fido2LuksResult<()> { self.device .token_handle() @@ -274,14 +281,24 @@ pub struct Fido2LuksToken { } impl Fido2LuksToken { - fn new(credential_id: impl AsRef<[u8]>, slot: u32) -> Self { + pub fn new(credential_id: impl AsRef<[u8]>, slot: u32) -> Self { + Self::with_credentials(std::iter::once(credential_id), slot) + } + + pub fn with_credentials, B: AsRef<[u8]>>( + credentials: I, + slot: u32, + ) -> Self { Self { - credential: vec![hex::encode(credential_id)].into_iter().collect(), + credential: credentials + .into_iter() + .map(|cred| hex::encode(cred.as_ref())) + .collect(), keyslots: vec![slot.to_string()].into_iter().collect(), ..Default::default() } } - fn default_type() -> &'static str { + pub fn default_type() -> &'static str { "fido2luks" } }