use std::io::{BufReader, Read};
use anyhow::Result;
use aws_lc_rs::digest::{self, SHA256};
use base64::{Engine as _, engine::general_purpose::STANDARD};
use bishop::{BishopArt, DrawingOptions};
use whoami::{hostname, username};
use crate::MoshpitError;
fn generate_encoded_digest(key_bytes: &[u8]) -> String {
let sha256_digest = digest::digest(&SHA256, key_bytes);
STANDARD.encode(sha256_digest.as_ref())
}
pub fn extract_public_key_bytes<R: Read>(reader: R) -> Result<Vec<u8>> {
let mut reader = BufReader::new(reader);
let mut pk_file_bytes = String::new();
let _count = reader.read_to_string(&mut pk_file_bytes)?;
let split = pk_file_bytes.split_whitespace().collect::<Vec<&str>>();
if split.len() == 3 {
Ok(STANDARD.decode(split[1])?)
} else {
Err(MoshpitError::InvalidPublicKeyFormat.into())
}
}
pub fn fingerprint(key_bytes: &[u8]) -> Result<String> {
let encoded_digest = generate_encoded_digest(key_bytes);
let username = username().unwrap_or("unknown-user".to_string());
let hostname = hostname().unwrap_or("unknown-host".to_string());
Ok(format!("SHA256:{encoded_digest} {username}@{hostname}"))
}
#[must_use]
pub fn randomart(key_bytes: &[u8]) -> String {
let draw_opts = DrawingOptions {
top_text: "moshpit SHA256".to_string(),
bottom_text: "SHA256".to_string(),
..Default::default()
};
let digest = digest::digest(&SHA256, key_bytes);
let mut art = BishopArt::new();
art.input(digest.as_ref());
art.draw_with_opts(&draw_opts).clone()
}
#[must_use]
pub fn verify_fingerprint(fingerprint: &str, key_bytes: &[u8]) -> bool {
generate_encoded_digest(key_bytes) == fingerprint
}