bc_envelope/extension/
secret.rs

1use anyhow::{ bail, Result };
2use bc_components::{ KeyDerivationMethod, SymmetricKey, EncryptedKey };
3use crate::{ Envelope, Error };
4use known_values;
5
6impl Envelope {
7    pub fn lock_subject(
8        &self,
9        method: KeyDerivationMethod,
10        secret: impl Into<Vec<u8>>
11    ) -> Result<Self> {
12        let content_key = SymmetricKey::new();
13        // Lock the content key using the specified derivation method
14        let encrypted_key = EncryptedKey::lock(method, secret, &content_key);
15        // Add a hasSecret assertion with the EncryptedKey
16        Ok(
17            self
18                .encrypt_subject(&content_key)?
19                .add_assertion(known_values::HAS_SECRET, encrypted_key)
20        )
21    }
22
23    pub fn unlock_subject(&self, secret: impl Into<Vec<u8>>) -> Result<Self> {
24        // Find and attempt to unlock each EncryptedKey in hasSecret assertions
25        let secret = secret.into();
26        for assertion in self.assertions_with_predicate(known_values::HAS_SECRET) {
27            let obj = assertion.as_object().unwrap();
28            if !obj.is_obscured() {
29                let encrypted_key = obj.extract_subject::<EncryptedKey>()?;
30                if let Ok(content_key) = encrypted_key.unlock(secret.clone()) {
31                    return self.decrypt_subject(&content_key);
32                }
33            }
34        }
35        // No matching secret unlock succeeded
36        bail!(Error::UnknownSecret)
37    }
38
39    pub fn add_secret(
40        &self,
41        method: KeyDerivationMethod,
42        secret: impl Into<Vec<u8>>,
43        content_key: &SymmetricKey
44    ) -> Self {
45        // Lock the content key using the specified derivation method
46        let encrypted_key = EncryptedKey::lock(method, secret, content_key);
47        // Add a hasSecret assertion with the EncryptedKey
48        self.add_assertion(known_values::HAS_SECRET, encrypted_key)
49    }
50}
51
52impl Envelope {
53    pub fn lock(&self, method: KeyDerivationMethod, secret: impl Into<Vec<u8>>) -> Self {
54        self.wrap_envelope().lock_subject(method, secret).unwrap()
55    }
56
57    pub fn unlock(&self, secret: impl Into<Vec<u8>>) -> Result<Self> {
58        self.unlock_subject(secret)?.unwrap_envelope()
59    }
60}