use crate::crypto::verify;
use crate::Host;
use crate::HostInfo;
use ed25519_dalek;
use std::convert::TryFrom;
use std::fmt::Formatter;
#[derive(Debug)]
pub struct RemoteHost {
info: HostInfo,
pubkey: ed25519_dalek::PublicKey,
}
impl RemoteHost {
pub fn new(info: &HostInfo) -> Result<RemoteHost, signature::Error> {
let pubkey = ed25519_dalek::PublicKey::try_from(info.id)?;
let remote_host = RemoteHost {
info: info.clone(),
pubkey,
};
match &info.sig {
Some(_) => {}
None => return Err(signature::Error::new()),
}
print!("{:?}\n", remote_host.info.sig.as_ref().unwrap());
print!("{:?}\n", info.sig.as_ref().unwrap());
remote_host.verify_self()?;
Ok(remote_host)
}
}
impl Host for RemoteHost {
fn info(&self) -> &HostInfo {
&self.info
}
fn verify_msg(&self, msg: &[u8], sig: &[u8]) -> Result<(), signature::Error> {
verify(&self.pubkey, msg, sig)
}
}
impl std::fmt::Display for RemoteHost {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{{\"type\":\"remote\",\"info\":{}}}", self.info)
}
}
#[cfg(test)]
mod tests {
use super::Host;
use super::HostInfo;
use super::RemoteHost;
use crate::LocalHost;
use serde_json;
#[test]
fn test_remote_host_serde_json() {
let local_host = LocalHost::new(None).unwrap();
let serialized = serde_json::to_string(local_host.info()).unwrap();
let deserialized: HostInfo = serde_json::from_str(&serialized).unwrap();
assert_eq!(local_host.info(), &deserialized);
let remote_host = RemoteHost::new(&deserialized).unwrap();
assert!(matches!(remote_host.verify_self(), Ok(())));
let msg = "this is the message".as_bytes();
let sig = local_host.sign_msg(msg);
assert!(matches!(remote_host.verify_msg(msg, &sig), Ok(())));
}
}