use base64::Engine;
use ed25519_dalek::{Signature, Verifier, VerifyingKey};
use serde::{Deserialize, Serialize};
use crate::save::error::SaveError;
#[derive(Serialize, Deserialize)]
pub struct SignedSavefile {
pub authenticating_server: AuthenticatingServer,
pub save_data: crate::save::Savefile,
pub signature: Signature
}
#[derive(Serialize, Deserialize)]
pub struct AuthenticatingServer {
pub server: String,
pub server_build_id: String,
pub server_public_key: VerifyingKey,
}
impl SignedSavefile {
pub fn encoded_save_data(&self) -> Result<Vec<u8>, SaveError> {
Ok(postcard::to_allocvec(&self.save_data)?)
}
pub fn is_valid(&self) -> Result<bool, SaveError> {
let encoded_savefile = self.encoded_save_data()?;
Ok(self.authenticating_server.server_public_key.verify(&encoded_savefile, &self.signature).is_ok())
}
}
pub fn encode_public_key(public_key: &VerifyingKey) -> String {
base64::engine::general_purpose::URL_SAFE.encode(public_key)
}
pub fn decode_public_key(public_key: &str) -> Result<VerifyingKey, SaveError> {
let bytes = base64::engine::general_purpose::URL_SAFE.decode(public_key)?;
let key: [u8; 32] = bytes.try_into().ok().ok_or(SaveError::InvalidKeyLength(public_key.len()))?;
VerifyingKey::from_bytes(&key).ok().ok_or(SaveError::Ed25519Error)
}