azirevpn/src/keys.rs
2023-04-15 13:56:12 +02:00

56 lines
1.4 KiB
Rust

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<Self> {
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<WireguardKeyPair, anyhow::Error> {
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())
}