From 2372645ee1d29b613d7c039238c703cbfdd77701 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 30 May 2021 21:59:54 +0100 Subject: [PATCH] Provide parsing for sshkey::Id and Nonce and so on Signed-off-by: Ian Jackson --- src/sshkeys.rs | 22 ++++++++++++++++++++++ src/utils.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/sshkeys.rs b/src/sshkeys.rs index d9a79103..635ae685 100644 --- a/src/sshkeys.rs +++ b/src/sshkeys.rs @@ -154,6 +154,28 @@ impl Debug for Nonce { } } +impl FromStr for KeySpec { + type Err = anyhow::Error; + #[throws(anyhow::Error)] + fn from_str(s: &str) -> KeySpec { + (||{ + let (id, nonce) = s.split_once(':') + .ok_or_else(|| anyhow!("missing `:`"))?; + let id = id.try_into().context("bad id")?; + let nonce = nonce.parse().context("bad nonce")?; + Ok::<_,AE>(KeySpec { id, nonce }) + })().context("failed to parse ssh key spec")? + } +} + +impl FromStr for Nonce { + type Err = anyhow::Error; + #[throws(anyhow::Error)] + fn from_str(s: &str) -> Nonce { + Nonce(parse_fixed_hex(s).ok_or_else(|| anyhow!("bad nonce syntax"))?) + } +} + impl PerScope { pub fn check(&self, ag: &AccountsGuard, authed_key: &KeySpec, auth_in: Authorisation) diff --git a/src/utils.rs b/src/utils.rs index 75500470..e2b1faa2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -649,6 +649,20 @@ pub fn fmt_hex(f: &mut Formatter, buf: &[u8]) { for v in buf { write!(f, "{:02x}", v)?; } } +#[throws(as Option)] +pub fn parse_fixed_hex(s: &str) -> [u8; N] { + if s.len() != N*2 || ! s.is_ascii() { throw!() } + let mut buf = [0u8; N]; + for (h, o) in izip!( + s.as_bytes().chunks(2), + buf.iter_mut(), + ) { + let h = str::from_utf8(h).ok()?; + *o = u8::from_str_radix(h,16).ok()?; + } + buf +} + #[macro_export] macro_rules! format_by_fmt_hex { ($trait:ty, for $self:ty, . $($memb:tt)+) => { @@ -660,3 +674,15 @@ macro_rules! format_by_fmt_hex { } } } + +#[test] +fn test_parse_hex(){ + assert_eq!( parse_fixed_hex(""), Some([ ]) ); + assert_eq!( parse_fixed_hex("41" ), Some([b'A' ]) ); + assert_eq!( parse_fixed_hex("4165"), Some([b'A', b'e']) ); + assert_eq!( parse_fixed_hex("4165"), Some([b'A', b'e']) ); + assert_eq!( parse_fixed_hex("41" ), None::<[_;0]> ); + assert_eq!( parse_fixed_hex("41" ), None::<[_;2]> ); + assert_eq!( parse_fixed_hex("1" ), None::<[_;1]> ); + assert_eq!( parse_fixed_hex("xy" ), None::<[_;1]> ); +} -- 2.30.2