steel_crypto/
key_store.rs1use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
3
4#[derive(Debug, thiserror::Error)]
6#[error("decryption failed")]
7pub struct DecryptError;
8
9pub struct KeyStore {
11 private_key: RsaPrivateKey,
13 pub public_key_der: Vec<u8>,
15}
16
17impl KeyStore {
18 #[must_use]
20 pub fn create() -> Self {
21 log::debug!("Creating encryption keys...");
22 let private_key = Self::generate_private_key();
23
24 let public_key = RsaPublicKey::from(&private_key);
25 let public_key_der =
26 crate::public_key_to_bytes(&public_key).expect("Failed to encode public key");
27
28 Self {
29 private_key,
30 public_key_der,
31 }
32 }
33
34 pub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, DecryptError> {
36 self.private_key
37 .decrypt(Pkcs1v15Encrypt, ciphertext)
38 .map_err(|_| DecryptError)
39 }
40
41 fn generate_private_key() -> RsaPrivateKey {
42 let mut rng = rand::rng();
44
45 RsaPrivateKey::new(&mut rng, 1024).expect("Failed to generate a key")
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn decrypt_reports_no_reason_for_failure() {
55 let ks = KeyStore::create();
56 let public_key = RsaPublicKey::from(&ks.private_key);
57 let secret = b"0123456789abcdef";
58
59 let ciphertext = public_key
60 .encrypt(&mut rand::rng(), Pkcs1v15Encrypt, secret)
61 .unwrap();
62 assert_eq!(ks.decrypt(&ciphertext).unwrap(), secret);
63
64 assert!(ks.decrypt(&[]).is_err());
66 assert!(ks.decrypt(&[0; 128]).is_err());
67 }
68
69 #[test]
70 fn public_key_der_round_trips() {
71 let ks = KeyStore::create();
72 let decoded = crate::public_key_from_bytes(&ks.public_key_der).unwrap();
73 assert_eq!(decoded, RsaPublicKey::from(&ks.private_key));
74 }
75}