1use crate::errors::SecureError;
2use openssl::rsa::Rsa;
3use openssl::symm::Cipher;
4use rand::Rng;
5
6pub fn generate_secure_string(len: usize) -> String {
7 rand::rng()
8 .sample_iter(rand::distr::Alphanumeric)
9 .take(len)
10 .map(char::from)
11 .collect()
12}
13
14pub fn decrypt_rsa_private_key(
15 key: &str,
16 passphrase: &str,
17) -> Result<Rsa<openssl::pkey::Private>, SecureError> {
18 let decrypted = Rsa::private_key_from_pem_passphrase(key.as_bytes(), passphrase.as_bytes())
19 .map_err(|e| SecureError::PrivateKeyError(e.to_string()))?;
20
21 Ok(decrypted)
22}
23
24pub fn generate_rsa_key_pair(
27 passphrase: &str,
28) -> Result<(Rsa<openssl::pkey::Private>, String), SecureError> {
29 let rsa_key_pair: Rsa<openssl::pkey::Private> =
30 Rsa::generate(2048).map_err(|e| SecureError::PrivateKeyGenerateFailed(e.to_string()))?;
31
32 let cipher = Cipher::aes_256_cbc();
33
34 let pem = rsa_key_pair
35 .private_key_to_pem_passphrase(cipher, passphrase.as_bytes())
36 .map_err(|e| SecureError::PrivateKeyGenerateFailed(e.to_string()))?;
37
38 let pem_string =
39 String::from_utf8(pem).map_err(|e| SecureError::PrivateKeyError(e.to_string()))?;
40
41 Ok((rsa_key_pair, pem_string))
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn test_generate_secure_string() {
50 let len = 10;
51 let secure_string = generate_secure_string(len);
52 assert_eq!(secure_string.len(), len);
53 }
54
55 #[test]
56 fn test_generate_rsa_key_pair() {
57 let passphrase = "asdfasdf";
58 let (rsa_key_pair, pem_string) =
59 generate_rsa_key_pair(passphrase).expect("Failed to generate RSA key pair");
60 let modulus = rsa_key_pair.n().to_owned().expect("Failed to get modulus");
61 let bit_size = modulus.num_bits();
62 assert_eq!(bit_size, 2048, "The key size should be 2048 bits");
63 assert!(pem_string.contains("BEGIN RSA PRIVATE KEY"));
64 assert!(pem_string.contains("END RSA PRIVATE KEY"));
65 }
66}