crypto_ext/asymmetric/encryption/
mod.rs1use openssl::rsa::Padding;
2use openssl::rsa::Rsa;
3use openssl::symm::Cipher;
4use crate::{get_path_relative_to_working_directory, get_static_filepath, read_file, read_or_create_and_write};
5use crate::passphrase::generate_passphrase;
6
7#[cfg(test)]
8mod tests;
9
10const RSA_SIZE: u32 = 4096;
11
12pub struct EncryptionParameters {
15 pub rsa_public_key_pem: String,
16}
17
18pub struct DecryptionParameters {
21 pub rsa_passphrase: String,
22 pub rsa_private_key_pem: String,
23}
24
25pub fn setup(path_to_encryption_parameters: Option<&str>) -> Result<(EncryptionParameters, DecryptionParameters), String> {
28 let relative_path = get_path_relative_to_working_directory(path_to_encryption_parameters, ".rsa_passphrase");
29 let boxed_passphrase_path = get_static_filepath(relative_path.as_str());
30 if boxed_passphrase_path.is_err() {
31 return Err(boxed_passphrase_path.err().unwrap());
32 }
33 let passphrase_path = boxed_passphrase_path.unwrap();
34
35
36 let boxed_passphrase = get_or_create_passphrase(passphrase_path.as_str());
37 if boxed_passphrase.is_err() {
38 return Err(boxed_passphrase.err().unwrap());
39 }
40 let passphrase = boxed_passphrase.unwrap();
41
42
43 let relative_path = get_path_relative_to_working_directory(path_to_encryption_parameters, ".rsa_public_key");
44 let boxed_public_key_path = get_static_filepath(relative_path.as_str());
45 if boxed_public_key_path.is_err() {
46 return Err(boxed_public_key_path.err().unwrap());
47 }
48 let public_key_path = boxed_public_key_path.unwrap();
49
50
51 let relative_path = get_path_relative_to_working_directory(path_to_encryption_parameters, ".rsa_private_key");
52 let boxed_private_key_path = get_static_filepath(relative_path.as_str());
53 if boxed_private_key_path.is_err() {
54 return Err(boxed_private_key_path.err().unwrap());
55 }
56 let private_key_path = boxed_private_key_path.unwrap();
57
58
59 let boxed_keys = get_or_create_private_public_keys(passphrase.as_str(), public_key_path.as_str(), private_key_path.as_str());
60 if boxed_keys.is_err() {
61 return Err(boxed_keys.err().unwrap());
62 }
63
64 let (private_key, public_key) = boxed_keys.unwrap();
65
66 let encryption_params = EncryptionParameters {
67 rsa_public_key_pem: public_key,
68 };
69
70 let decryption_params = DecryptionParameters {
71 rsa_passphrase: passphrase,
72 rsa_private_key_pem: private_key
73 };
74
75 Ok((encryption_params, decryption_params))
76}
77
78pub fn get_encryption_params(path_to_encryption_parameters: Option<&str>) -> Result<EncryptionParameters, String> {
81 let relative_path = get_path_relative_to_working_directory(path_to_encryption_parameters, ".rsa_public_key");
82 let boxed_public_key_path = get_static_filepath(relative_path.as_str());
83 if boxed_public_key_path.is_err() {
84 return Err(boxed_public_key_path.err().unwrap());
85 }
86 let public_key_path = boxed_public_key_path.unwrap();
87
88
89 let boxed_public_key = read_file(public_key_path.as_str());
90 if boxed_public_key.is_err() {
91 let message = boxed_public_key.err().unwrap();
92 return Err(message)
93 }
94 let boxed_public_key = String::from_utf8(boxed_public_key.unwrap());
95 let public_key = boxed_public_key.unwrap();
96
97 let encryption_params = EncryptionParameters {
98 rsa_public_key_pem: public_key,
99 };
100
101 Ok(encryption_params)
102}
103
104pub fn get_decryption_params(path_to_encryption_parameters: Option<&str>) -> Result<DecryptionParameters, String> {
107 let relative_path = get_path_relative_to_working_directory(path_to_encryption_parameters, ".rsa_passphrase");
108 let boxed_passphrase_path = get_static_filepath(relative_path.as_str());
109 if boxed_passphrase_path.is_err() {
110 return Err(boxed_passphrase_path.err().unwrap());
111 }
112 let passphrase_path = boxed_passphrase_path.unwrap();
113
114
115 let boxed_passphrase = get_or_create_passphrase(passphrase_path.as_str());
116 if boxed_passphrase.is_err() {
117 return Err(boxed_passphrase.err().unwrap());
118 }
119 let passphrase = boxed_passphrase.unwrap();
120
121
122 let relative_path = get_path_relative_to_working_directory(path_to_encryption_parameters, ".rsa_private_key");
123 let boxed_private_key_path = get_static_filepath(relative_path.as_str());
124 if boxed_private_key_path.is_err() {
125 return Err(boxed_private_key_path.err().unwrap());
126 }
127 let private_key_path = boxed_private_key_path.unwrap();
128
129 let boxed_private_key = read_file(private_key_path.as_str());
130 if boxed_private_key.is_err() {
131 let message = boxed_private_key.err().unwrap();
132 return Err(message)
133 }
134 let boxed_private_key = String::from_utf8(boxed_private_key.unwrap());
135 let private_key = boxed_private_key.unwrap();
136
137 let decryption_params = DecryptionParameters {
138 rsa_passphrase: passphrase,
139 rsa_private_key_pem: private_key
140 };
141
142 Ok(decryption_params)
143}
144
145pub fn encrypt(params: EncryptionParameters, data: &[u8]) -> Result<Vec<u8>, String> {
173 let boxed_rsa = Rsa::public_key_from_pem(params.rsa_public_key_pem.as_bytes());
174 if boxed_rsa.is_err() {
175 let message = boxed_rsa.err().unwrap().to_string();
176 return Err(message)
177 }
178 let rsa = boxed_rsa.unwrap();
179 let mut buffer : Vec<u8> = vec![0; rsa.size() as usize];
180 let boxed_encrypt = rsa.public_encrypt(data, &mut buffer, Padding::PKCS1);
181 if boxed_encrypt.is_err() {
182 let message = boxed_encrypt.err().unwrap().to_string();
183 return Err(message)
184 }
185 let _ = boxed_encrypt.unwrap();
186 Ok(buffer)
187}
188
189
190pub fn decrypt(params: DecryptionParameters, data: &[u8]) -> Result<Vec<u8>, String> {
214 let boxed_rsa = Rsa::private_key_from_pem_passphrase(params.rsa_private_key_pem.as_bytes(), params.rsa_passphrase.as_bytes());
215 if boxed_rsa.is_err() {
216 let message = boxed_rsa.err().unwrap().to_string();
217 return Err(message)
218 }
219 let rsa = boxed_rsa.unwrap();
220 let mut buffer: Vec<u8> = vec![0; rsa.size() as usize];
221 let boxed_decrypt = rsa.private_decrypt(data, &mut buffer, Padding::PKCS1);
222 if boxed_decrypt.is_err() {
223 let message = boxed_decrypt.err().unwrap().to_string();
224 return Err(message)
225 }
226 let _ = boxed_decrypt.unwrap();
227
228 let as_string = String::from_utf8(buffer).expect("Found invalid UTF-8");
229
230 let as_filtered_string = as_string.trim_end_matches(char::from(0));
231
232 let as_vector = as_filtered_string.as_bytes().to_vec();
233
234 Ok(as_vector)
235}
236
237
238fn get_or_create_passphrase(path: &str) -> Result<String, String> {
241
242 let boxed_passphrase = generate_passphrase();
243 if boxed_passphrase.is_err() {
244 let message = boxed_passphrase.err().unwrap();
245 return Err(message)
246 }
247
248 let passphrase = boxed_passphrase.unwrap();
249
250 let boxed_passphrase = read_or_create_and_write(path, passphrase.as_bytes());
251 if boxed_passphrase.is_err() {
252 let message = boxed_passphrase.err().unwrap();
253 return Err(message)
254 }
255
256 let boxed_passphrase = String::from_utf8(boxed_passphrase.unwrap());
257 let passphrase = boxed_passphrase.unwrap();
258 Ok(passphrase)
259}
260
261fn get_or_create_private_public_keys(passphrase: &str, public_key_path: &str, private_key_path: &str) -> Result<(String, String), String> {
262 let rsa = Rsa::generate(RSA_SIZE).unwrap();
263
264 let boxed_private_key = rsa.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), passphrase.as_bytes());
265 let boxed_private_key = String::from_utf8(boxed_private_key.unwrap());
266 let private_key = boxed_private_key.unwrap();
267
268 let boxed_private_key = read_or_create_and_write(private_key_path, private_key.as_bytes());
269 if boxed_private_key.is_err() {
270 let message = boxed_private_key.err().unwrap();
271 return Err(message)
272 }
273 let boxed_private_key = String::from_utf8(boxed_private_key.unwrap());
274 let private_key = boxed_private_key.unwrap();
275
276
277 let boxed_public_key = rsa.public_key_to_pem();
278 let boxed_public_key = String::from_utf8(boxed_public_key.unwrap());
279 let public_key = boxed_public_key.unwrap();
280
281 let boxed_public_key = read_or_create_and_write(public_key_path, public_key.as_bytes());
282 if boxed_public_key.is_err() {
283 let message = boxed_public_key.err().unwrap();
284 return Err(message)
285 }
286 let boxed_public_key = String::from_utf8(boxed_public_key.unwrap());
287 let public_key = boxed_public_key.unwrap();
288
289 Ok((private_key.to_string(), public_key.to_string()))
290}
291