ppaass_crypto/crypto/
rsa.rs1use std::{fmt::Debug, path::Path, sync::Arc};
2use std::{fs, io::Read};
3
4use crate::error::CryptoError;
5use rand::rngs::OsRng;
6use rsa::{
7 pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey, LineEnding},
8 Pkcs1v15Encrypt,
9};
10use rsa::{RsaPrivateKey, RsaPublicKey};
11
12const DEFAULT_AGENT_PRIVATE_KEY_PATH: &str = "AgentPrivateKey.pem";
13const DEFAULT_AGENT_PUBLIC_KEY_PATH: &str = "AgentPublicKey.pem";
14const DEFAULT_PROXY_PRIVATE_KEY_PATH: &str = "ProxyPrivateKey.pem";
15const DEFAULT_PROXY_PUBLIC_KEY_PATH: &str = "ProxyPublicKey.pem";
16
17pub trait RsaCryptoFetcher {
22 fn fetch(&self, user_token: impl AsRef<str>) -> Result<Option<&RsaCrypto>, CryptoError>;
24}
25
26impl<T> RsaCryptoFetcher for Arc<T>
27where
28 T: RsaCryptoFetcher,
29{
30 fn fetch(&self, user_token: impl AsRef<str>) -> Result<Option<&RsaCrypto>, CryptoError> {
31 RsaCryptoFetcher::fetch(self.as_ref(), user_token)
32 }
33}
34
35impl<T> RsaCryptoFetcher for &T
36where
37 T: RsaCryptoFetcher,
38{
39 fn fetch(&self, user_token: impl AsRef<str>) -> Result<Option<&RsaCrypto>, CryptoError> {
40 RsaCryptoFetcher::fetch(*self, user_token)
41 }
42}
43
44impl<T> RsaCryptoFetcher for &mut T
45where
46 T: RsaCryptoFetcher,
47{
48 fn fetch(&self, user_token: impl AsRef<str>) -> Result<Option<&RsaCrypto>, CryptoError> {
49 RsaCryptoFetcher::fetch(*self, user_token)
50 }
51}
52
53#[derive(Debug)]
55pub struct RsaCrypto {
56 private_key: RsaPrivateKey,
58 public_key: RsaPublicKey,
60}
61
62impl RsaCrypto {
63 pub fn new<A, B>(mut public_key_read: A, mut private_key_read: B) -> Result<Self, CryptoError>
64 where
65 A: Read + Debug,
66 B: Read + Debug,
67 {
68 let mut public_key_string = String::new();
69 public_key_read.read_to_string(&mut public_key_string)?;
70 let public_key = RsaPublicKey::from_public_key_pem(&public_key_string)
71 .map_err(|e| CryptoError::Other(format!("{e:?}")))?;
72 let mut private_key_string = String::new();
73 private_key_read.read_to_string(&mut private_key_string)?;
74 let private_key = RsaPrivateKey::from_pkcs8_pem(&private_key_string)
75 .map_err(|e| CryptoError::Other(format!("{e:?}")))?;
76 Ok(Self {
77 public_key,
78 private_key,
79 })
80 }
81
82 pub fn encrypt(&self, target: &[u8]) -> Result<Vec<u8>, CryptoError> {
83 let result = self
84 .public_key
85 .encrypt(&mut OsRng, Pkcs1v15Encrypt, target.as_ref())
86 .map_err(|e| CryptoError::Other(format!("{e:?}")))?;
87 Ok(result)
88 }
89
90 pub fn decrypt(&self, target: &[u8]) -> Result<Vec<u8>, CryptoError> {
91 let result = self
92 .private_key
93 .decrypt(Pkcs1v15Encrypt, target.as_ref())
94 .map_err(|e| CryptoError::Other(format!("{e:?}")))?;
95 Ok(result)
96 }
97}
98
99pub fn generate_agent_key_pairs(base_dir: &str, user_token: &str) -> Result<(), CryptoError> {
100 let private_key_path = format!("{base_dir}/{user_token}/{DEFAULT_AGENT_PRIVATE_KEY_PATH}");
101 let private_key_path = Path::new(private_key_path.as_str());
102 let public_key_path = format!("{base_dir}/{user_token}/{DEFAULT_AGENT_PUBLIC_KEY_PATH}");
103 let public_key_path = Path::new(public_key_path.as_str());
104 generate_rsa_key_pairs(private_key_path, public_key_path)
105}
106
107pub fn generate_proxy_key_pairs(base_dir: &str, user_token: &str) -> Result<(), CryptoError> {
108 let private_key_path = format!("{base_dir}/{user_token}/{DEFAULT_PROXY_PRIVATE_KEY_PATH}");
109 let private_key_path = Path::new(private_key_path.as_str());
110 let public_key_path = format!("{base_dir}/{user_token}/{DEFAULT_PROXY_PUBLIC_KEY_PATH}");
111 let public_key_path = Path::new(public_key_path.as_str());
112 generate_rsa_key_pairs(private_key_path, public_key_path)
113}
114
115fn generate_rsa_key_pairs(
116 private_key_path: &Path,
117 public_key_path: &Path,
118) -> Result<(), CryptoError> {
119 let private_key = RsaPrivateKey::new(&mut OsRng, 2048).expect("Fail to generate private key");
120 let public_key = RsaPublicKey::from(&private_key);
121 let private_key_pem = private_key
122 .to_pkcs8_pem(LineEnding::CRLF)
123 .expect("Fail to generate pem for private key.");
124 let public_key_pem = public_key
125 .to_public_key_pem(LineEnding::CRLF)
126 .expect("Fail to generate pem for public key.");
127 match private_key_path.parent() {
128 None => {
129 println!("Write private key: {:?}", private_key_path.to_str());
130 fs::write(private_key_path, private_key_pem.as_bytes())?;
131 }
132 Some(parent) => {
133 if !parent.exists() {
134 println!("Create parent directory :{:?}", parent.to_str());
135 fs::create_dir_all(parent)?;
136 }
137 println!("Write private key: {:?}", private_key_path.to_str());
138 fs::write(private_key_path, private_key_pem.as_bytes())?;
139 }
140 };
141 match public_key_path.parent() {
142 None => {
143 println!("Write public key: {:?}", public_key_path.to_str());
144 fs::write(public_key_path, public_key_pem.as_bytes())?;
145 }
146 Some(parent) => {
147 if !parent.exists() {
148 println!("Create parent directory :{:?}", parent.to_str());
149 fs::create_dir_all(parent)?;
150 }
151 println!("Write public key: {:?}", public_key_path.to_str());
152 fs::write(public_key_path, public_key_pem.as_bytes())?;
153 }
154 };
155 Ok(())
156}