use std::fs::File; use std::io::{ Write, Read }; use serde::{ Deserialize, Serialize }; use ring::{ signature::{ KeyPair, Ed25519KeyPair, UnparsedPublicKey, ED25519 }, rand, // hmac, digest, error::Unspecified, }; use rust_util::XResult; #[derive(Clone, Serialize, Deserialize)] pub struct SigningKeyPair { key_pair: Vec, } impl SigningKeyPair { pub fn new() -> Self { let rng = rand::SystemRandom::new(); let pkcs8 = Ed25519KeyPair::generate_pkcs8(&rng).unwrap(); // TODO ... SigningKeyPair{ key_pair: pkcs8.as_ref().to_vec(), } } pub fn key_pair(&self) -> Ed25519KeyPair { Ed25519KeyPair::from_pkcs8(&self.key_pair).unwrap() // TODO ... } pub fn public_key(&self) -> Vec { self.key_pair().public_key().as_ref().to_vec() } pub fn unparsed_public_key(&self) -> UnparsedPublicKey> { UnparsedPublicKey::new(&ED25519, self.public_key()) } pub fn read_from_file(file: &str) -> XResult { match File::open(file) { Err(e) => Err(rust_util::new_box_ioerror(&format!("Read from file failed: {}", e))), Ok(mut f) => { let mut buf = String::new(); match f.read_to_string(&mut buf) { Err(e) => Err(rust_util::new_box_ioerror(&format!("Read from file failed: {}", e))), Ok(_) => { let kp: Self = match serde_json::from_str(&buf) { Err(e) => return Err(rust_util::new_box_ioerror(&format!("Parse JSON failed: {}", e))), Ok(k) => k, }; Ok(kp) } } }, } } pub fn write_to_file(&self, file: &str) -> XResult<()> { if File::open(file).is_ok() { return Err(rust_util::new_box_ioerror(&format!("File exists: {}", file))); } let ser_bytes = match serde_json::to_string_pretty(self) { Err(e) => return Err(rust_util::new_box_ioerror(&format!("Serilize key pair failed: {}", e))), Ok(s) => s, }; match File::create(file) { Err(e) => Err(rust_util::new_box_ioerror(&format!("File create: {}, failed: {}", file, e))), Ok(mut f) => { match f.write_all(ser_bytes.as_bytes()) { Err(e) => Err(rust_util::new_box_ioerror(&format!("File create: {}, failed: {}", file, e))), Ok(_) => Ok(()), } }, } } } #[derive(Serialize, Deserialize)] pub struct SignedMessage { pub msg: Vec, pub sig: Option>, pub desc: Option, } impl SignedMessage { pub fn new(msg: Vec, desc: Option) -> Self { Self { msg, sig: None, desc, } } pub fn sign(&mut self, key_pair: &SigningKeyPair) { let sig = key_pair.key_pair().sign(&self.msg); self.sig = Some(sig.as_ref().to_vec()); } pub fn verify(&self, public_key: &[u8]) -> bool { match &self.sig { None => false, Some(sig) => { let verify_result = UnparsedPublicKey::new(&ED25519, &public_key).verify(&self.msg, sig); verify_result.is_ok() } } } } #[test] fn test_sign() { let signing_key_pair = SigningKeyPair::new(); let mut signed_message = SignedMessage::new( "Hello".as_bytes().to_vec(), Some("DESC".to_owned()) ); signed_message.sign(&signing_key_pair); assert!(signed_message.verify(&signing_key_pair.public_key())) }