Add Key type

This commit is contained in:
Andrey Golovizin 2023-04-10 22:44:47 +02:00
parent c282177afb
commit d9080af78a
4 changed files with 48 additions and 24 deletions

View file

@ -3,6 +3,8 @@ use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use log::debug;
use serde::{Deserialize, Serialize};
use crate::keys::Key;
const BASE_URL: &str = "https://api.azirevpn.com";
#[derive(Serialize, Deserialize, Debug)]
@ -60,13 +62,13 @@ pub(crate) fn get_locations() -> anyhow::Result<Locations> {
Ok(response)
}
pub(crate) fn add_ip(username: &str, token: &str, public_key: &str) -> anyhow::Result<Addresses> {
pub(crate) fn add_ip(username: &str, token: &str, public_key: &Key) -> anyhow::Result<Addresses> {
let url = format!("{}/v2/ip/add", BASE_URL);
let response: Addresses = ureq::post(&url)
.send_form(&[
("username", username),
("token", token),
("key", public_key),
("key", &public_key.to_base64()),
])?
.into_json()?;
debug!("response = {:?}", &response);

View file

@ -3,16 +3,43 @@ use gethostname::gethostname;
use log::debug;
use x25519_dalek::{PublicKey, StaticSecret};
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use crate::dirs::get_data_dir;
const KEY_SIZE: usize = 32;
#[derive(Debug)]
pub(crate) struct Key([u8; KEY_SIZE]);
impl Key {
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)
}
fn read(path: &Path) -> anyhow::Result<Self> {
let key_data = std::fs::read_to_string(path)?;
Self::try_from_base64(&key_data)
}
fn write(&self, path: &Path) -> anyhow::Result<()> {
std::fs::write(path, self.to_base64())?;
Ok(())
}
}
#[derive(Debug)]
pub(crate) struct WireguardKeyPair {
pub public_key: String,
pub private_key: String,
pub public_key: Key,
pub private_key: Key,
}
pub(crate) fn get_keys(machine: Option<&PathBuf>) -> Result<WireguardKeyPair, anyhow::Error> {
@ -28,18 +55,18 @@ pub(crate) fn get_keys(machine: Option<&PathBuf>) -> Result<WireguardKeyPair, an
std::fs::create_dir_all(&key_path)?;
let private_key_path = key_path.join("key");
let private_key = if private_key_path.is_file() {
std::fs::read_to_string(private_key_path)?
Key::read(&private_key_path)?
} else {
let key = generate_private_key()?;
std::fs::write(private_key_path, key.as_bytes())?;
let key = generate_private_key();
key.write(&private_key_path)?;
key
};
let public_key_path = key_path.join("pubkey");
let public_key = if public_key_path.is_file() {
std::fs::read_to_string(public_key_path)?
Key::read(&public_key_path)?
} else {
let key = generate_public_key(&private_key)?;
std::fs::write(public_key_path, key.as_bytes())?;
let key = generate_public_key(&private_key);
key.write(&public_key_path)?;
key
};
Ok(WireguardKeyPair {
@ -48,17 +75,12 @@ pub(crate) fn get_keys(machine: Option<&PathBuf>) -> Result<WireguardKeyPair, an
})
}
fn generate_private_key() -> anyhow::Result<String> {
let private_key = StaticSecret::random();
Ok(BASE64_STANDARD.encode(private_key.to_bytes()))
fn generate_private_key() -> Key {
Key(StaticSecret::random().to_bytes())
}
fn generate_public_key(private_key: &str) -> anyhow::Result<String> {
let mut key_data = [0u8; KEY_SIZE];
let key_bytes = BASE64_STANDARD.decode(private_key)?;
assert_eq!(key_bytes.len(), KEY_SIZE);
key_data[0..KEY_SIZE].copy_from_slice(&key_bytes);
let key = StaticSecret::from(key_data);
fn generate_public_key(private_key: &Key) -> Key {
let key = StaticSecret::from(private_key.0);
let pubkey = PublicKey::from(&key);
Ok(BASE64_STANDARD.encode(pubkey.to_bytes()))
Key(pubkey.to_bytes())
}

View file

@ -125,7 +125,7 @@ fn write_config(
keys: &WireguardKeyPair,
) -> Result<(), anyhow::Error> {
writeln!(output, "[Interface]")?;
writeln!(output, "PrivateKey = {}", &keys.private_key)?;
writeln!(output, "PrivateKey = {}", &keys.private_key.to_base64())?;
let allowed_addresses = if config_opts.no_ipv6 {
vec![IpAddr::V4(config.ipv4.address)]
} else {