1use serde::{Deserialize, Serialize};
6
7use crate::crypto::{
8 Aes256GcmParams, Argon2IdKeyProducer, Argon2idParams, KeyEnvelope, KeyEnvelopeType,
9 blob_header::KdfAlgorithm, crypto, decrypt_in_place,
10};
11
12pub trait KeyWrapper: Send {
13 fn envelope_type(&self) -> KeyEnvelopeType;
15 fn to_bytes(&self) -> Result<Vec<u8>, crate::error::Error>;
17}
18
19pub trait KdfBasedKeyWrapper: KeyWrapper {
20 fn kdf_algorithm(&self) -> KdfAlgorithm;
21 fn update_salt(&mut self, salt: Vec<u8>) -> Result<(), crate::error::Error>;
22 fn unwrap_key(&self, password: &str) -> Result<Vec<u8>, crate::error::Error>;
23 fn impl_to_bytes(&self) -> Result<Vec<u8>, crate::error::Error>;
24 fn kdf_wrapper_to_bytes(&self) -> Result<Vec<u8>, crate::error::Error> {
25 let mut buffer = Vec::<u8>::with_capacity(32);
26 buffer.extend(self.kdf_algorithm().to_bytes());
27 buffer.extend(self.impl_to_bytes()?);
28 Ok(buffer)
29 }
30}
31
32#[derive(Clone, Serialize, Deserialize)]
33pub enum AnyKeyWrapper {
34 Argon2id(Argon2idKeyWrapper),
35 Pgp(PgpKeyWrapper),
36 Age(AgeKeyWrapper),
37}
38
39impl KeyWrapper for AnyKeyWrapper {
40 fn envelope_type(&self) -> KeyEnvelopeType {
41 match self {
42 AnyKeyWrapper::Argon2id(_) => KeyEnvelopeType::Kdf,
43 AnyKeyWrapper::Pgp(_) => KeyEnvelopeType::Pgp,
44 AnyKeyWrapper::Age(_) => KeyEnvelopeType::Age,
45 }
46 }
47
48 fn to_bytes(&self) -> Result<Vec<u8>, crate::error::Error> {
49 match self {
50 AnyKeyWrapper::Argon2id(kw) => kw.to_bytes(),
51 AnyKeyWrapper::Pgp(kw) => kw.to_bytes(),
52 AnyKeyWrapper::Age(kw) => kw.to_bytes(),
53 }
54 }
55}
56
57impl AnyKeyWrapper {
58 pub fn as_kdf_based(&self) -> Option<&dyn KdfBasedKeyWrapper> {
59 match self {
60 AnyKeyWrapper::Argon2id(kw) => Some(kw),
61 _ => None,
62 }
63 }
64 pub fn expect_kdf_based(&self) -> Result<&dyn KdfBasedKeyWrapper, crate::error::Error> {
65 let opt = self.as_kdf_based();
66 match opt {
67 Some(x) => Ok(x),
68 None => Err(crate::error::Error::LogicError(
69 "Expecting a KDF based key wrapper".to_string(),
70 )),
71 }
72 }
73}
74
75#[derive(Clone, Serialize, Deserialize)]
76pub struct Argon2idKeyWrapper {
77 version: u8,
78 parameters: Argon2idParams,
79 wrapped_key: Vec<u8>,
80 authentication_data: Vec<u8>,
81}
82
83impl KdfBasedKeyWrapper for Argon2idKeyWrapper {
84 fn kdf_algorithm(&self) -> KdfAlgorithm {
85 KdfAlgorithm::Argon2id
86 }
87
88 fn update_salt(&mut self, salt: Vec<u8>) -> Result<(), crate::error::Error> {
89 use crate::crypto::random;
90 self.parameters.salt = salt;
91 self.wrapped_key = random::get_rand_bytes(self.wrapped_key.len())?;
93 self.authentication_data = random::get_rand_bytes(self.authentication_data.len())?;
94 Ok(())
95 }
96
97 fn unwrap_key(&self, password: &str) -> Result<Vec<u8>, crate::error::Error> {
98 let mut dek = self.wrapped_key.clone();
99 let kek = Argon2IdKeyProducer::new(password, &self.parameters)
100 .get_key()
101 .clone();
102 decrypt_in_place(
103 &mut dek,
104 &<[u8; 32]>::try_from(kek)
105 .map_err(|e| crate::error::Error::DecryptionError("".to_string()))?,
106 &Aes256GcmParams {
107 nonce: vec![0u8; 12],
108 },
109 &self.authentication_data,
110 )?;
111 Ok(dek)
112 }
113
114 fn impl_to_bytes(&self) -> Result<Vec<u8>, crate::error::Error> {
115 Ok(bincode::serialize(self)
116 .map_err(|e| crate::error::Error::SerializationError(e.to_string()))?)
117 }
118}
119
120impl KeyWrapper for Argon2idKeyWrapper {
121 fn envelope_type(&self) -> KeyEnvelopeType {
122 KeyEnvelopeType::Kdf
123 }
124
125 fn to_bytes(&self) -> Result<Vec<u8>, crate::error::Error> {
126 self.kdf_wrapper_to_bytes()
127 }
128}
129
130impl Argon2idKeyWrapper {
131 const CURRENT_VERSION: u8 = 1;
132 pub fn new(
133 password: &str,
134 parameters: &Argon2idParams,
135 dek: &Vec<u8>,
136 ) -> Result<Self, crate::error::Error> {
137 let key_prod = Argon2IdKeyProducer::new(password, ¶meters);
138 Self::construct_inst(&key_prod, dek)
139 }
140 pub fn with_default_parameters(
141 password: &str,
142 dek: &Vec<u8>,
143 ) -> Result<Self, crate::error::Error> {
144 let key_prod = Argon2IdKeyProducer::with_default_parameters(password);
145 Self::construct_inst(&key_prod, dek)
146 }
147 fn construct_inst(
148 key_prod: &Argon2IdKeyProducer,
149 dek: &Vec<u8>,
150 ) -> Result<Self, crate::error::Error> {
151 let mut inst = Self {
152 version: Self::CURRENT_VERSION,
153 parameters: key_prod.get_parameters().clone(),
154 wrapped_key: dek.clone(),
155 authentication_data: vec![],
156 };
157 let aes256gcm_params = Aes256GcmParams {
158 nonce: vec![0u8; 12],
159 };
160 inst.authentication_data = crypto::encrypt_in_place(
161 &mut inst.wrapped_key,
162 &key_prod.get_key().clone().try_into().unwrap(),
163 &aes256gcm_params,
164 )?;
165 Ok(inst)
166 }
167 pub fn from_bytes(data: &[u8]) -> Result<Self, crate::error::Error> {
168 bincode::deserialize(data)
169 .map_err(|e| crate::error::Error::DeserializationError(e.to_string()))
170 }
171}
172
173#[derive(Clone, Serialize, Deserialize)]
174pub(crate) struct PgpKeyWrapper {}
175
176impl KeyWrapper for PgpKeyWrapper {
177 fn envelope_type(&self) -> KeyEnvelopeType {
178 KeyEnvelopeType::Pgp
179 }
180
181 fn to_bytes(&self) -> Result<Vec<u8>, crate::error::Error> {
182 todo!("Not implemented yet: serialization of PgpKeyWrapper")
183 }
184}
185impl PgpKeyWrapper {
186 pub fn from_bytes(data: &[u8]) -> Result<Self, crate::error::Error> {
187 todo!()
188 }
189}
190
191#[derive(Clone, Serialize, Deserialize)]
192pub(crate) struct AgeKeyWrapper {}
193
194impl KeyWrapper for AgeKeyWrapper {
195 fn envelope_type(&self) -> KeyEnvelopeType {
196 KeyEnvelopeType::Age
197 }
198
199 fn to_bytes(&self) -> Result<Vec<u8>, crate::error::Error> {
200 todo!("Not implemented yet: serialization of AgeKeyWrapper")
201 }
202}
203impl AgeKeyWrapper {
204 pub fn from_bytes(data: &[u8]) -> Result<Self, crate::error::Error> {
205 todo!()
206 }
207}
208
209pub(crate) fn from_key_envelope(
210 key_envelope: &KeyEnvelope,
211) -> Result<AnyKeyWrapper, crate::error::Error> {
212 match key_envelope.envelope_type {
213 KeyEnvelopeType::Invalid => Err(crate::error::Error::DeserializationError(
214 "Invalid key envelop type tag".to_string(),
215 )),
216 KeyEnvelopeType::Kdf => {
217 let data = key_envelope.envelope_data();
218 let (kdf_algo, pos_after_kdf_algo) = KdfAlgorithm::from_bytes(data)?;
219 match kdf_algo {
220 KdfAlgorithm::Invalid => {
221 return Err(crate::error::Error::DeserializationError(
222 "Invalid KDF algorithm tag".to_string(),
223 ));
224 }
225 KdfAlgorithm::Argon2id => Ok(AnyKeyWrapper::Argon2id(
226 Argon2idKeyWrapper::from_bytes(&data[pos_after_kdf_algo..])?,
227 )),
228 }
229 }
230 KeyEnvelopeType::Pgp => Ok(AnyKeyWrapper::Pgp(PgpKeyWrapper::from_bytes(
231 &key_envelope.envelope_data(),
232 )?)),
233 KeyEnvelopeType::Age => Ok(AnyKeyWrapper::Age(AgeKeyWrapper::from_bytes(
234 &key_envelope.envelope_data(),
235 )?)),
236 }
237}