use crate::datastore::NodeInfo; use crate::grpc::challenge::Keys; use detee_sgx::SgxError; use serde::{Deserialize, Serialize}; use serde_with::{base64::Base64, serde_as}; use std::io::Write; use once_cell::sync::Lazy; use std::sync::Mutex; pub struct Logfile {} static LOG_MUTEX: Lazy> = Lazy::new(|| Mutex::new(())); impl Logfile { pub fn append(path: &str, msg: &str) -> Result<(), Box> { let _lock = LOG_MUTEX.lock(); let mut file = std::fs::OpenOptions::new().create(true).append(true).open(path)?; file.write_all(msg.as_bytes())?; Ok(()) } } impl SealedFile for KeysFile {} impl SealedFile for NodeInfo {} #[serde_as] #[derive(Serialize, Deserialize)] pub struct KeysFile { random: String, #[serde_as(as = "Base64")] keypair: Vec, token: String, } impl From for KeysFile { fn from(keys: Keys) -> Self { use rand::{distributions::Alphanumeric, Rng}; let random: String = rand::thread_rng().sample_iter(&Alphanumeric).take(128).map(char::from).collect(); Self { keypair: keys.keypair, token: keys.token_address, random } } } impl Into for KeysFile { fn into(self) -> Keys { Keys { keypair: self.keypair, token_address: self.token } } } pub trait SealedFile: Serialize + for<'de> Deserialize<'de> { fn write(&self, path: &str) -> Result<(), SealError> { let serialized = serde_json::to_string(&self)?; let sealed = detee_sgx::SealingConfig::new()?.seal_data(serialized.into_bytes())?; std::fs::write(path, sealed).map_err(Into::into) } fn read(path: &str) -> Result { let sealed = std::fs::read(path)?; let serialized = detee_sgx::SealingConfig::new()?.un_seal_data(sealed)?; serde_json::from_slice(&serialized).map_err(Into::into) } } #[derive(Debug)] pub enum SealError { Error(String), Attack(String), } impl std::fmt::Display for SealError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { SealError::Error(e) => write!(f, "Error: {}", e), SealError::Attack(e) => write!(f, "SealError: {}", e), } } } impl From for SealError { fn from(e: SgxError) -> Self { SealError::Attack(e.to_string()) } } impl From for SealError { fn from(e: serde_json::Error) -> Self { SealError::Error(e.to_string()) } } impl From for SealError { fn from(e: std::io::Error) -> Self { SealError::Error(e.to_string()) } }