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, SaveError> { Ok(postcard::to_allocvec(&self.save_data)?) } pub fn is_valid(&self) -> Result { 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 { 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) }