licenz_core/crypto/
rsa.rs1use super::SignatureAlgorithm;
7use crate::error::{LicenseError, Result};
8use pem::{encode, Pem};
9use rand::rngs::OsRng;
10use rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey};
11use rsa::pkcs1v15::{SigningKey, VerifyingKey};
12use rsa::pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey};
13use rsa::signature::{RandomizedSigner, SignatureEncoding, Verifier};
14use rsa::{RsaPrivateKey, RsaPublicKey};
15use sha2::Sha256;
16
17pub const DEFAULT_KEY_SIZE: usize = 3072;
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
22pub enum RsaKeySize {
23 Bits2048,
24 #[default]
25 Bits3072,
26 Bits4096,
27}
28
29impl RsaKeySize {
30 pub fn bits(&self) -> usize {
31 match self {
32 RsaKeySize::Bits2048 => 2048,
33 RsaKeySize::Bits3072 => 3072,
34 RsaKeySize::Bits4096 => 4096,
35 }
36 }
37}
38
39pub struct RsaSigner {
41 key_size: RsaKeySize,
42}
43
44impl Default for RsaSigner {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50impl RsaSigner {
51 pub fn new() -> Self {
53 Self {
54 key_size: RsaKeySize::default(),
55 }
56 }
57
58 pub fn with_key_size(key_size: RsaKeySize) -> Self {
60 Self { key_size }
61 }
62
63 fn parse_private_key(pem_str: &str) -> Result<RsaPrivateKey> {
65 let pem_str = pem_str.replace("\\n", "\n");
67
68 if let Ok(key) = RsaPrivateKey::from_pkcs8_pem(&pem_str) {
70 return Ok(key);
71 }
72
73 if let Ok(key) = RsaPrivateKey::from_pkcs1_pem(&pem_str) {
75 return Ok(key);
76 }
77
78 Err(LicenseError::InvalidKeyFormat(
79 "Could not parse RSA private key (tried PKCS#8 and PKCS#1 formats)".into(),
80 ))
81 }
82
83 fn parse_public_key(pem_str: &str) -> Result<RsaPublicKey> {
85 let pem_str = pem_str.replace("\\n", "\n");
87
88 if let Ok(key) = RsaPublicKey::from_public_key_pem(&pem_str) {
90 return Ok(key);
91 }
92
93 if let Ok(key) = RsaPublicKey::from_pkcs1_pem(&pem_str) {
95 return Ok(key);
96 }
97
98 Err(LicenseError::InvalidKeyFormat(
99 "Could not parse RSA public key (tried SPKI and PKCS#1 formats)".into(),
100 ))
101 }
102}
103
104impl SignatureAlgorithm for RsaSigner {
105 fn algorithm_id(&self) -> &'static str {
106 super::algorithm_ids::RSA_SHA256
107 }
108
109 fn sign(&self, data: &[u8], private_key_pem: &str) -> Result<Vec<u8>> {
110 let private_key = Self::parse_private_key(private_key_pem)?;
111 let signing_key = SigningKey::<Sha256>::new(private_key);
112 let mut rng = OsRng;
113
114 let signature = signing_key.sign_with_rng(&mut rng, data);
115 Ok(signature.to_bytes().to_vec())
116 }
117
118 fn verify(&self, data: &[u8], signature: &[u8], public_key_pem: &str) -> Result<()> {
119 let public_key = Self::parse_public_key(public_key_pem)?;
120 let verifying_key = VerifyingKey::<Sha256>::new(public_key);
121
122 let sig = rsa::pkcs1v15::Signature::try_from(signature).map_err(|e| {
123 LicenseError::VerificationFailed(format!("Invalid RSA signature format: {}", e))
124 })?;
125
126 verifying_key.verify(data, &sig).map_err(|e| {
127 LicenseError::VerificationFailed(format!("RSA signature verification failed: {}", e))
128 })
129 }
130
131 fn generate_keypair(&self) -> Result<(String, String)> {
132 let mut rng = OsRng;
133 let private_key = RsaPrivateKey::new(&mut rng, self.key_size.bits())
134 .map_err(|e| LicenseError::KeyGenerationFailed(e.to_string()))?;
135 let public_key = RsaPublicKey::from(&private_key);
136
137 let private_der = private_key
138 .to_pkcs8_der()
139 .map_err(|e| LicenseError::InvalidKeyFormat(e.to_string()))?;
140 let public_der = public_key
141 .to_public_key_der()
142 .map_err(|e| LicenseError::InvalidKeyFormat(e.to_string()))?;
143
144 let private_pem = encode(&Pem::new("PRIVATE KEY", private_der.as_bytes()));
145 let public_pem = encode(&Pem::new("PUBLIC KEY", public_der.as_bytes()));
146
147 Ok((private_pem, public_pem))
148 }
149
150 fn extract_public_key(&self, private_key_pem: &str) -> Result<String> {
151 let private_key = Self::parse_private_key(private_key_pem)?;
152 let public_key = RsaPublicKey::from(&private_key);
153
154 let public_der = public_key
155 .to_public_key_der()
156 .map_err(|e| LicenseError::InvalidKeyFormat(e.to_string()))?;
157 let public_pem = encode(&Pem::new("PUBLIC KEY", public_der.as_bytes()));
158
159 Ok(public_pem)
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166
167 #[test]
168 fn test_rsa_signer_algorithm_id() {
169 let signer = RsaSigner::new();
170 assert_eq!(signer.algorithm_id(), "RSA-SHA256");
171 }
172
173 #[test]
174 fn test_rsa_generate_keypair() {
175 let signer = RsaSigner::new();
176 let (private_pem, public_pem) = signer.generate_keypair().unwrap();
177
178 assert!(private_pem.contains("PRIVATE KEY"));
179 assert!(public_pem.contains("PUBLIC KEY"));
180 }
181
182 #[test]
183 fn test_rsa_sign_and_verify() {
184 let signer = RsaSigner::new();
185 let (private_pem, public_pem) = signer.generate_keypair().unwrap();
186
187 let data = b"Hello, World!";
188 let signature = signer.sign(data, &private_pem).unwrap();
189
190 assert!(!signature.is_empty());
191 assert!(signer.verify(data, &signature, &public_pem).is_ok());
192 }
193
194 #[test]
195 fn test_rsa_verify_wrong_data() {
196 let signer = RsaSigner::new();
197 let (private_pem, public_pem) = signer.generate_keypair().unwrap();
198
199 let data = b"Hello, World!";
200 let wrong_data = b"Goodbye, World!";
201 let signature = signer.sign(data, &private_pem).unwrap();
202
203 assert!(signer.verify(wrong_data, &signature, &public_pem).is_err());
204 }
205
206 #[test]
207 fn test_rsa_verify_wrong_key() {
208 let signer = RsaSigner::new();
209 let (private_pem, _) = signer.generate_keypair().unwrap();
210 let (_, other_public_pem) = signer.generate_keypair().unwrap();
211
212 let data = b"Hello, World!";
213 let signature = signer.sign(data, &private_pem).unwrap();
214
215 assert!(signer.verify(data, &signature, &other_public_pem).is_err());
216 }
217
218 #[test]
219 fn test_rsa_extract_public_key() {
220 let signer = RsaSigner::new();
221 let (private_pem, public_pem) = signer.generate_keypair().unwrap();
222
223 let extracted = signer.extract_public_key(&private_pem).unwrap();
224 assert_eq!(extracted, public_pem);
225 }
226
227 #[test]
228 fn test_rsa_key_sizes() {
229 assert_eq!(RsaKeySize::Bits2048.bits(), 2048);
230 assert_eq!(RsaKeySize::Bits3072.bits(), 3072);
231 assert_eq!(RsaKeySize::Bits4096.bits(), 4096);
232 }
233
234 #[test]
235 fn test_rsa_with_custom_key_size() {
236 let signer = RsaSigner::with_key_size(RsaKeySize::Bits2048);
237 let (private_pem, public_pem) = signer.generate_keypair().unwrap();
238
239 let data = b"Test data";
240 let signature = signer.sign(data, &private_pem).unwrap();
241 assert!(signer.verify(data, &signature, &public_pem).is_ok());
242 }
243}