ffsend_api/crypto/
key_set.rs1use url::Url;
2
3use super::hkdf::{derive_auth_key, derive_file_key, derive_meta_key};
4use super::{b64, rand_bytes};
5use crate::api::url::UrlBuilder;
6use crate::file::remote_file::RemoteFile;
7
8const KEY_NONCE_LEN: usize = 12;
10
11pub struct KeySet {
12 secret: Vec<u8>,
14
15 nonce: [u8; KEY_NONCE_LEN],
17
18 file_key: Option<Vec<u8>>,
20
21 auth_key: Option<Vec<u8>>,
23
24 meta_key: Option<Vec<u8>>,
26}
27
28impl KeySet {
29 pub fn new(secret: Vec<u8>, nonce: [u8; 12]) -> Self {
31 Self {
32 secret,
33 nonce,
34 file_key: None,
35 auth_key: None,
36 meta_key: None,
37 }
38 }
39
40 pub fn from(file: &RemoteFile, password: Option<&String>) -> Self {
46 let mut set = Self::new(file.secret_raw().clone(), [0; 12]);
48
49 set.derive();
51
52 if let Some(password) = password {
54 set.derive_auth_password(password, &UrlBuilder::download(&file, true));
55 }
56
57 set
58 }
59
60 pub fn generate(derive: bool) -> Self {
65 let mut secret = vec![0u8; 16];
67 let mut iv = [0u8; 12];
68
69 rand_bytes(&mut secret).expect("failed to generate crypto secure random secret");
71 rand_bytes(&mut iv).expect("failed to generate crypto secure random input vector");
72
73 let mut key = Self::new(secret, iv);
75
76 if derive {
78 key.derive();
79 }
80
81 key
82 }
83
84 pub fn derive(&mut self) {
87 self.file_key = Some(derive_file_key(&self.secret));
88 self.auth_key = Some(derive_auth_key(&self.secret, None, None));
89 self.meta_key = Some(derive_meta_key(&self.secret));
90 }
91
92 pub fn derive_auth_password(&mut self, pass: &str, url: &Url) {
95 self.auth_key = Some(derive_auth_key(&self.secret, Some(pass), Some(url)));
96 }
97
98 pub fn secret(&self) -> &[u8] {
100 &self.secret
101 }
102
103 pub fn secret_encoded(&self) -> String {
105 b64::encode(self.secret())
106 }
107
108 pub fn nonce(&self) -> &[u8] {
110 &self.nonce
111 }
112
113 pub fn set_nonce(&mut self, nonce: [u8; KEY_NONCE_LEN]) {
115 self.nonce = nonce;
116 }
117
118 pub fn file_key(&self) -> Option<&Vec<u8>> {
120 self.file_key.as_ref()
121 }
122
123 pub fn auth_key(&self) -> Option<&Vec<u8>> {
125 self.auth_key.as_ref()
126 }
127
128 pub fn auth_key_encoded(&self) -> Option<String> {
131 self.auth_key().map(|key| b64::encode(key))
132 }
133
134 pub fn meta_key(&self) -> Option<&Vec<u8>> {
136 self.meta_key.as_ref()
137 }
138}