Skip to main content

secret_vault/
ring_encryption.rs

1use crate::{SecretVaultKey, SecretVaultResult};
2
3use async_trait::async_trait;
4use kms_aead::ring_encryption::RingAeadEncryption;
5use kms_aead::*;
6use ring::rand::SystemRandom;
7use secret_vault_value::*;
8
9use crate::encryption::*;
10
11pub struct SecretVaultRingAeadEncryption {
12    ring_encryption: RingAeadEncryption,
13    vault_secret: DataEncryptionKey,
14}
15
16impl SecretVaultRingAeadEncryption {
17    pub fn new() -> SecretVaultResult<Self> {
18        Self::with_algorithm(&ring::aead::AES_256_GCM)
19    }
20
21    pub fn with_algorithm(algo: &'static ring::aead::Algorithm) -> SecretVaultResult<Self> {
22        let ring_encryption = RingAeadEncryption::with_algorithm(algo, SystemRandom::new())?;
23        let vault_secret = ring_encryption.generate_data_encryption_key()?;
24
25        Ok(Self {
26            ring_encryption,
27            vault_secret,
28        })
29    }
30}
31
32#[async_trait]
33impl SecretVaultEncryption for SecretVaultRingAeadEncryption {
34    async fn encrypt_value(
35        &self,
36        secret_vault_key: &SecretVaultKey,
37        secret_value: &SecretValue,
38    ) -> SecretVaultResult<EncryptedSecretValue> {
39        let encrypted = self
40            .ring_encryption
41            .encrypt_value(secret_vault_key.to_aad(), secret_value, &self.vault_secret)
42            .await?;
43        Ok(encrypted.into())
44    }
45
46    async fn decrypt_value(
47        &self,
48        secret_vault_key: &SecretVaultKey,
49        encrypted_secret_value: &EncryptedSecretValue,
50    ) -> SecretVaultResult<SecretValue> {
51        Ok(self
52            .ring_encryption
53            .decrypt_value(
54                secret_vault_key.to_aad(),
55                &encrypted_secret_value.clone().into(),
56                &self.vault_secret,
57            )
58            .await?)
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65    use crate::source_tests::*;
66    use crate::SecretName;
67    use proptest::prelude::*;
68    use proptest::strategy::ValueTree;
69    use proptest::test_runner::TestRunner;
70    use rvstruct::*;
71
72    async fn encryption_test_for(mock_secret_value: SecretValue) {
73        let mock_secret_name: SecretName = "test".to_string().into();
74        let mock_secret_vault_key: SecretVaultKey = SecretVaultKey::new(mock_secret_name);
75
76        let encryption = SecretVaultRingAeadEncryption::new().unwrap();
77
78        let encrypted_value = encryption
79            .encrypt_value(&mock_secret_vault_key, &mock_secret_value)
80            .await
81            .unwrap();
82        assert_ne!(
83            encrypted_value.value(),
84            mock_secret_value.ref_sensitive_value()
85        );
86
87        let decrypted_value = encryption
88            .decrypt_value(&mock_secret_vault_key, &encrypted_value)
89            .await
90            .unwrap();
91        assert_eq!(
92            decrypted_value.ref_sensitive_value(),
93            mock_secret_value.ref_sensitive_value()
94        );
95    }
96
97    #[tokio::test]
98    async fn secret_encryption_test() {
99        let mut runner = TestRunner::default();
100        encryption_test_for(
101            generate_secret_value()
102                .new_tree(&mut runner)
103                .unwrap()
104                .current(),
105        )
106        .await
107    }
108
109    #[tokio::test]
110    async fn big_secret_encryption_test() {
111        for sz in vec![5000, 32768, 65535] {
112            encryption_test_for(SecretValue::new("42".repeat(sz).as_bytes().to_vec())).await
113        }
114    }
115
116    #[tokio::test]
117    async fn wrong_secret_name_test_attest() {
118        let mock_secret_name1: SecretName = "test1".to_string().into();
119        let mock_secret_name2: SecretName = "test2".to_string().into();
120        let mock_secret_vault_key1: SecretVaultKey = SecretVaultKey::new(mock_secret_name1);
121        let mock_secret_vault_key2: SecretVaultKey = SecretVaultKey::new(mock_secret_name2);
122
123        let mock_secret_value = SecretValue::new("42".repeat(1024).as_bytes().to_vec());
124
125        let encryption = SecretVaultRingAeadEncryption::new().unwrap();
126        let encrypted_value = encryption
127            .encrypt_value(&mock_secret_vault_key1, &mock_secret_value)
128            .await
129            .unwrap();
130        encryption
131            .decrypt_value(&mock_secret_vault_key2, &encrypted_value)
132            .await
133            .expect_err("Unable to decrypt data");
134    }
135}