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