include_crypt_crypto/
key.rs

1use rand::{rngs::OsRng, Rng};
2use std::{convert::TryFrom, ops::Deref};
3
4/// The default key size.
5pub const DEFAULT_KEY_LEN: usize = super::xor::XOR_KEY_LEN;
6
7/// A simple symmetric encryption key which will be stored as a vector of bytes.
8pub struct EncryptionKey {
9    data: Vec<u8>,
10}
11
12impl EncryptionKey {
13    /// Creates a new key from the specified hex string.
14    pub fn new(key: &'_ str, key_len: usize) -> Result<Self, String> {
15        // Remove the optional trailing '0x' and convert to vector
16        //
17        let mut key = hex::decode(key.trim_start_matches("0x")).map_err(|e| e.to_string())?;
18
19        // Extend the key if it is smaller than the default key length.
20        //
21        if key.len() != key_len {
22            key = key.into_iter().cycle().take(DEFAULT_KEY_LEN).collect::<Vec<_>>();
23        }
24
25        Ok(Self { data: key })
26    }
27
28    /// Generates a random key with the specified size.
29    pub fn random(key_len: usize) -> Self {
30        let mut key = vec![0u8; key_len];
31        let mut rng = OsRng::default();
32        rng.fill(&mut key[..]);
33
34        Self { data: key }
35    }
36
37    /// Converts the key into a string.
38    pub fn as_str(&self) -> String { hex::encode(&self.data) }
39}
40
41impl Default for EncryptionKey {
42    fn default() -> Self { Self::random(DEFAULT_KEY_LEN) }
43}
44
45impl Deref for EncryptionKey {
46    type Target = Vec<u8>;
47
48    fn deref(&self) -> &Self::Target { &self.data }
49}
50
51impl AsRef<EncryptionKey> for EncryptionKey {
52    fn as_ref(&self) -> &Self { &self }
53}
54
55impl TryFrom<String> for EncryptionKey {
56    type Error = String;
57
58    fn try_from(value: String) -> Result<Self, Self::Error> { Self::new(value.as_str(), DEFAULT_KEY_LEN) }
59}
60
61impl TryFrom<&str> for EncryptionKey {
62    type Error = String;
63
64    fn try_from(value: &str) -> Result<Self, Self::Error> { Self::new(value, DEFAULT_KEY_LEN) }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test]
72    fn test_new_key() {
73        let key = EncryptionKey::new("0xaabbccddeeff", DEFAULT_KEY_LEN).unwrap();
74        assert_eq!(key.data.len(), DEFAULT_KEY_LEN);
75        assert_eq!(
76            key.data,
77            vec![
78                0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
79                0xff, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0xaa, 0xbb
80            ]
81        );
82
83        let key = EncryptionKey::new("0xaabbccddeeff", 6).unwrap();
84        assert_eq!(key.data.len(), 6);
85        assert_eq!(key.data, vec![0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]);
86
87        assert_eq!(EncryptionKey::try_from("0xa").is_err(), true);
88        assert_eq!(EncryptionKey::try_from("0xaab").is_err(), true);
89    }
90
91    #[test]
92    fn test_as_str() {
93        let key = EncryptionKey::try_from("0xaabbccddeeff").unwrap();
94        assert_eq!(
95            key.as_str(),
96            "aabbccddeeffaabbccddeeffaabbccddeeffaabbccddeeffaabbccddeeffaabb"
97        );
98
99        let key = EncryptionKey::new("0xaabbccddeeff", 6).unwrap();
100        assert_eq!(key.as_str(), "aabbccddeeff");
101    }
102}