bc_envelope/extension/
secret.rs1use bc_components::{EncryptedKey, KeyDerivationMethod, SymmetricKey};
2use known_values;
3
4use crate::{Envelope, Error, Result};
5
6impl Envelope {
7 pub fn lock_subject(
8 &self,
9 method: KeyDerivationMethod,
10 secret: impl AsRef<[u8]>,
11 ) -> Result<Self> {
12 let content_key = SymmetricKey::new();
13 let encrypted_key = EncryptedKey::lock(method, secret, &content_key)?;
15 Ok(self
17 .encrypt_subject(&content_key)
18 .expect("Encrypt subject")
19 .add_assertion(known_values::HAS_SECRET, encrypted_key))
20 }
21
22 pub fn unlock_subject(&self, secret: impl AsRef<[u8]>) -> Result<Self> {
23 for assertion in
25 self.assertions_with_predicate(known_values::HAS_SECRET)
26 {
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.as_ref()) {
31 return self.decrypt_subject(&content_key);
32 }
33 }
34 }
35 Err(Error::UnknownSecret)
37 }
38
39 pub fn is_locked_with_password(&self) -> bool {
40 self.assertions_with_predicate(known_values::HAS_SECRET)
43 .iter()
44 .any(|assertion| {
45 let obj = assertion.as_object().unwrap();
46 if let Ok(encrypted_key) = obj.extract_subject::<EncryptedKey>()
47 {
48 encrypted_key.is_password_based()
49 } else {
50 false
51 }
52 })
53 }
54
55 pub fn is_locked_with_ssh_agent(&self) -> bool {
56 self.assertions_with_predicate(known_values::HAS_SECRET)
59 .iter()
60 .any(|assertion| {
61 let obj = assertion.as_object().unwrap();
62 if let Ok(encrypted_key) = obj.extract_subject::<EncryptedKey>()
63 {
64 encrypted_key.is_ssh_agent()
65 } else {
66 false
67 }
68 })
69 }
70
71 pub fn add_secret(
72 &self,
73 method: KeyDerivationMethod,
74 secret: impl AsRef<[u8]>,
75 content_key: &SymmetricKey,
76 ) -> Result<Self> {
77 let encrypted_key = EncryptedKey::lock(method, secret, content_key)?;
79 Ok(self.add_assertion(known_values::HAS_SECRET, encrypted_key))
81 }
82}
83
84impl Envelope {
85 pub fn lock(
86 &self,
87 method: KeyDerivationMethod,
88 secret: impl AsRef<[u8]>,
89 ) -> Result<Self> {
90 self.wrap().lock_subject(method, secret)
91 }
92
93 pub fn unlock(&self, secret: impl AsRef<[u8]>) -> Result<Self> {
94 self.unlock_subject(secret)?.try_unwrap()
95 }
96}