use base64::prelude::{Engine as _, BASE64_STANDARD}; use x25519_dalek::{PublicKey, StaticSecret}; use crate::config::MachineConfig; const KEY_SIZE: usize = 32; #[derive(Debug)] pub(crate) struct Key([u8; KEY_SIZE]); impl Key { pub(crate) fn try_from_base64(data: &str) -> anyhow::Result { let mut key_data = [0u8; KEY_SIZE]; let key_bytes = BASE64_STANDARD.decode(data)?; assert_eq!(key_bytes.len(), KEY_SIZE); key_data[0..KEY_SIZE].copy_from_slice(&key_bytes); Ok(Self(key_data)) } pub(crate) fn to_base64(&self) -> String { BASE64_STANDARD.encode(self.0) } } #[derive(Debug)] pub(crate) struct WireguardKeyPair { pub public_key: Key, pub private_key: Key, } pub(crate) fn get_keys(machine_config: &MachineConfig) -> Result { let private_key = if machine_config.has_key() { machine_config.key()? } else { let key = generate_private_key(); machine_config.save_key(&key)?; key }; let public_key = generate_public_key(&private_key); Ok(WireguardKeyPair { private_key, public_key, }) } fn generate_private_key() -> Key { Key(StaticSecret::random().to_bytes()) } fn generate_public_key(private_key: &Key) -> Key { let key = StaticSecret::from(private_key.0); let pubkey = PublicKey::from(&key); Key(pubkey.to_bytes()) }