hacker-challenge/src/persistence.rs

80 lines
2.1 KiB
Rust

use crate::{datastore::NodeInfo, grpc::challenge::Keys};
use detee_sgx::SgxError;
use serde::{Deserialize, Serialize};
use serde_with::{base64::Base64, serde_as};
impl SealedFile for KeysFile {}
impl SealedFile for NodeInfo {}
#[serde_as]
#[derive(Serialize, Deserialize)]
pub struct KeysFile {
random: String,
#[serde_as(as = "Base64")]
keypair: Vec<u8>,
token: String,
}
impl From<Keys> 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 From<KeysFile> for Keys {
fn from(kf: KeysFile) -> Keys {
Keys { keypair: kf.keypair, token_address: kf.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<Self, SealError> {
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<SgxError> for SealError {
fn from(e: SgxError) -> Self {
SealError::Attack(e.to_string())
}
}
impl From<serde_json::Error> for SealError {
fn from(e: serde_json::Error) -> Self {
SealError::Error(e.to_string())
}
}
impl From<std::io::Error> for SealError {
fn from(e: std::io::Error) -> Self {
SealError::Error(e.to_string())
}
}