chiark / gitweb /
Provide parsing for sshkey::Id and Nonce and so on
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 30 May 2021 20:59:54 +0000 (21:59 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 31 May 2021 23:14:40 +0000 (00:14 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/sshkeys.rs
src/utils.rs

index d9a791033dfaa8b90afb33197a8077097c90e7c7..635ae6854cdcbd3c2446bbe9653df86d6a65a18c 100644 (file)
@@ -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<KeySpec>)
index 75500470c42e9406546571ff1f153fd0ca3e481a..e2b1faa29b77d2fbf4786bd48b9861a4f5052eb6 100644 (file)
@@ -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<const N: usize>(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]>      );
+}