use std::{
fs::File,
io::{prelude::Write, BufReader},
};
use serde::{Deserialize, Serialize};
use crate::protocol::XWingKeypair;
pub struct DebugKeys {
pub controller_keypair: XWingKeypair,
pub breakpoint_keypair: XWingKeypair,
}
#[derive(Debug, Serialize, Deserialize)]
struct DebugKeysFile {
controller_private: [u8; x_wing::DECAPSULATION_KEY_SIZE],
breakpoint_private: [u8; x_wing::DECAPSULATION_KEY_SIZE],
}
fn read_debug_keys(path: &str) -> Option<DebugKeys> {
let fd = File::open(path).ok()?;
let reader = BufReader::new(fd);
let raw: DebugKeysFile = serde_cbor::from_reader(reader).ok()?;
Some(DebugKeys {
controller_keypair: XWingKeypair::from_decaps(&x_wing::DecapsulationKey::from(
raw.controller_private,
)),
breakpoint_keypair: XWingKeypair::from_decaps(&x_wing::DecapsulationKey::from(
raw.breakpoint_private,
)),
})
}
fn create_debug_keys(path: &str) -> Result<DebugKeys, ()> {
let controller_keypair = XWingKeypair::new();
let breakpoint_keypair = XWingKeypair::new();
let for_file = serde_cbor::to_vec(&DebugKeysFile {
controller_private: *controller_keypair.private_key.as_bytes(),
breakpoint_private: *breakpoint_keypair.private_key.as_bytes(),
})
.map_err(|_| ())?;
let mut fd = File::create(path).map_err(|_| ())?;
fd.write_all(&for_file).map_err(|_| ())?;
Ok(DebugKeys {
controller_keypair,
breakpoint_keypair,
})
}
pub(crate) fn get_debug_keys() -> Option<DebugKeys> {
let path = std::env::var("BM_USE_DEBUG_KEYS").ok()?;
match read_debug_keys(&path) {
Some(keys) => {
eprintln!("[WARNING] Using debug keys from disk.");
Some(keys)
}
None => match create_debug_keys(&path) {
Ok(keys) => {
eprintln!("[WARNING] Using new debug keys (and saving to disk.)");
Some(keys)
}
Err(err) => {
eprintln!("[WARNING] Could not read or create new debug keys: {err:?}");
None
}
},
}
}