rust_license_key/
crypto.rs1use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
13use base64::Engine;
14use ed25519_dalek::{
15 Signature, Signer, SigningKey, Verifier, VerifyingKey, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH,
16 SIGNATURE_LENGTH,
17};
18use rand::rngs::OsRng;
19
20use crate::error::{LicenseError, Result};
21
22#[derive(Debug)]
48pub struct KeyPair {
49 signing_key: SigningKey,
51}
52
53impl KeyPair {
54 pub fn generate() -> Result<Self> {
68 let mut csprng = OsRng;
70 let signing_key = SigningKey::generate(&mut csprng);
71
72 Ok(Self { signing_key })
73 }
74
75 pub fn from_private_key_base64(private_key_base64: &str) -> Result<Self> {
86 let private_key_bytes = BASE64_STANDARD.decode(private_key_base64).map_err(|e| {
87 LicenseError::InvalidPrivateKey {
88 reason: format!("invalid base64 encoding: {}", e),
89 }
90 })?;
91
92 if private_key_bytes.len() != SECRET_KEY_LENGTH {
93 return Err(LicenseError::InvalidPrivateKey {
94 reason: format!(
95 "invalid key length: expected {} bytes, got {}",
96 SECRET_KEY_LENGTH,
97 private_key_bytes.len()
98 ),
99 });
100 }
101
102 let key_bytes: [u8; SECRET_KEY_LENGTH] =
103 private_key_bytes
104 .try_into()
105 .map_err(|_| LicenseError::InvalidPrivateKey {
106 reason: "failed to convert key bytes".to_string(),
107 })?;
108
109 let signing_key = SigningKey::from_bytes(&key_bytes);
110
111 Ok(Self { signing_key })
112 }
113
114 pub fn from_private_key_bytes(private_key_bytes: &[u8]) -> Result<Self> {
120 if private_key_bytes.len() != SECRET_KEY_LENGTH {
121 return Err(LicenseError::InvalidPrivateKey {
122 reason: format!(
123 "invalid key length: expected {} bytes, got {}",
124 SECRET_KEY_LENGTH,
125 private_key_bytes.len()
126 ),
127 });
128 }
129
130 let key_bytes: [u8; SECRET_KEY_LENGTH] =
131 private_key_bytes
132 .try_into()
133 .map_err(|_| LicenseError::InvalidPrivateKey {
134 reason: "failed to convert key bytes".to_string(),
135 })?;
136
137 let signing_key = SigningKey::from_bytes(&key_bytes);
138
139 Ok(Self { signing_key })
140 }
141
142 pub fn public_key(&self) -> PublicKey {
144 PublicKey {
145 verifying_key: self.signing_key.verifying_key(),
146 }
147 }
148
149 pub fn private_key_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
156 self.signing_key.to_bytes()
157 }
158
159 pub fn private_key_base64(&self) -> String {
166 BASE64_STANDARD.encode(self.signing_key.to_bytes())
167 }
168
169 pub fn public_key_base64(&self) -> String {
173 self.public_key().to_base64()
174 }
175
176 pub fn sign(&self, data: &[u8]) -> [u8; SIGNATURE_LENGTH] {
186 let signature = self.signing_key.sign(data);
187 signature.to_bytes()
188 }
189
190 pub fn sign_base64(&self, data: &[u8]) -> String {
200 BASE64_STANDARD.encode(self.sign(data))
201 }
202}
203
204#[derive(Debug, Clone)]
223pub struct PublicKey {
224 verifying_key: VerifyingKey,
226}
227
228impl PublicKey {
229 pub fn from_base64(public_key_base64: &str) -> Result<Self> {
235 let public_key_bytes = BASE64_STANDARD.decode(public_key_base64).map_err(|e| {
236 LicenseError::InvalidPublicKey {
237 reason: format!("invalid base64 encoding: {}", e),
238 }
239 })?;
240
241 Self::from_bytes(&public_key_bytes)
242 }
243
244 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
250 if bytes.len() != PUBLIC_KEY_LENGTH {
251 return Err(LicenseError::InvalidPublicKey {
252 reason: format!(
253 "invalid key length: expected {} bytes, got {}",
254 PUBLIC_KEY_LENGTH,
255 bytes.len()
256 ),
257 });
258 }
259
260 let key_bytes: [u8; PUBLIC_KEY_LENGTH] =
261 bytes
262 .try_into()
263 .map_err(|_| LicenseError::InvalidPublicKey {
264 reason: "failed to convert key bytes".to_string(),
265 })?;
266
267 let verifying_key =
268 VerifyingKey::from_bytes(&key_bytes).map_err(|e| LicenseError::InvalidPublicKey {
269 reason: format!("invalid public key: {}", e),
270 })?;
271
272 Ok(Self { verifying_key })
273 }
274
275 pub fn to_bytes(&self) -> [u8; PUBLIC_KEY_LENGTH] {
277 self.verifying_key.to_bytes()
278 }
279
280 pub fn to_base64(&self) -> String {
282 BASE64_STANDARD.encode(self.verifying_key.to_bytes())
283 }
284
285 pub fn verify(&self, data: &[u8], signature_bytes: &[u8]) -> Result<()> {
296 if signature_bytes.len() != SIGNATURE_LENGTH {
297 return Err(LicenseError::InvalidSignature);
298 }
299
300 let sig_bytes: [u8; SIGNATURE_LENGTH] = signature_bytes
301 .try_into()
302 .map_err(|_| LicenseError::InvalidSignature)?;
303
304 let signature = Signature::from_bytes(&sig_bytes);
305
306 self.verifying_key
307 .verify(data, &signature)
308 .map_err(|_| LicenseError::InvalidSignature)
309 }
310
311 pub fn verify_base64(&self, data: &[u8], signature_base64: &str) -> Result<()> {
322 let signature_bytes = BASE64_STANDARD
323 .decode(signature_base64)
324 .map_err(|_| LicenseError::InvalidSignature)?;
325
326 self.verify(data, &signature_bytes)
327 }
328}
329
330pub fn generate_key_pair_base64() -> Result<(String, String)> {
352 let key_pair = KeyPair::generate()?;
353 Ok((key_pair.private_key_base64(), key_pair.public_key_base64()))
354}
355
356#[cfg(test)]
357mod tests {
358 use super::*;
359
360 #[test]
361 fn test_key_pair_generation() {
362 let key_pair = KeyPair::generate().expect("Key generation should succeed");
363
364 assert_eq!(key_pair.private_key_bytes().len(), SECRET_KEY_LENGTH);
366 assert_eq!(key_pair.public_key().to_bytes().len(), PUBLIC_KEY_LENGTH);
367 }
368
369 #[test]
370 fn test_key_pair_from_private_key() {
371 let original = KeyPair::generate().expect("Key generation should succeed");
372 let private_key_base64 = original.private_key_base64();
373
374 let restored =
375 KeyPair::from_private_key_base64(&private_key_base64).expect("Should restore key pair");
376
377 assert_eq!(
379 original.public_key().to_bytes(),
380 restored.public_key().to_bytes()
381 );
382 }
383
384 #[test]
385 fn test_public_key_from_base64() {
386 let key_pair = KeyPair::generate().expect("Key generation should succeed");
387 let public_key_base64 = key_pair.public_key_base64();
388
389 let public_key =
390 PublicKey::from_base64(&public_key_base64).expect("Should parse public key");
391
392 assert_eq!(public_key.to_bytes(), key_pair.public_key().to_bytes());
393 }
394
395 #[test]
396 fn test_sign_and_verify() {
397 let key_pair = KeyPair::generate().expect("Key generation should succeed");
398 let data = b"This is the license payload data";
399
400 let signature = key_pair.sign(data);
402
403 let public_key = key_pair.public_key();
405 public_key
406 .verify(data, &signature)
407 .expect("Signature should be valid");
408 }
409
410 #[test]
411 fn test_sign_and_verify_base64() {
412 let key_pair = KeyPair::generate().expect("Key generation should succeed");
413 let data = b"This is the license payload data";
414
415 let signature_base64 = key_pair.sign_base64(data);
417
418 let public_key = key_pair.public_key();
420 public_key
421 .verify_base64(data, &signature_base64)
422 .expect("Signature should be valid");
423 }
424
425 #[test]
426 fn test_verify_invalid_signature() {
427 let key_pair = KeyPair::generate().expect("Key generation should succeed");
428 let data = b"This is the license payload data";
429 let wrong_data = b"This is different data";
430
431 let signature = key_pair.sign(data);
433
434 let public_key = key_pair.public_key();
436 assert!(public_key.verify(wrong_data, &signature).is_err());
437 }
438
439 #[test]
440 fn test_verify_with_wrong_key() {
441 let key_pair_1 = KeyPair::generate().expect("Key generation should succeed");
442 let key_pair_2 = KeyPair::generate().expect("Key generation should succeed");
443 let data = b"This is the license payload data";
444
445 let signature = key_pair_1.sign(data);
447
448 let public_key_2 = key_pair_2.public_key();
450 assert!(public_key_2.verify(data, &signature).is_err());
451 }
452
453 #[test]
454 fn test_invalid_private_key_length() {
455 let invalid_key = BASE64_STANDARD.encode(vec![0u8; 16]); let result = KeyPair::from_private_key_base64(&invalid_key);
457 assert!(result.is_err());
458 }
459
460 #[test]
461 fn test_invalid_public_key_length() {
462 let invalid_key = BASE64_STANDARD.encode(vec![0u8; 16]); let result = PublicKey::from_base64(&invalid_key);
464 assert!(result.is_err());
465 }
466
467 #[test]
468 fn test_invalid_base64_encoding() {
469 let result = KeyPair::from_private_key_base64("not valid base64!!!");
470 assert!(result.is_err());
471
472 let result = PublicKey::from_base64("not valid base64!!!");
473 assert!(result.is_err());
474 }
475
476 #[test]
477 fn test_generate_key_pair_base64_convenience() {
478 let (private_key, public_key) =
479 generate_key_pair_base64().expect("Key generation should succeed");
480
481 let key_pair = KeyPair::from_private_key_base64(&private_key)
483 .expect("Should create key pair from private key");
484
485 assert_eq!(key_pair.public_key_base64(), public_key);
487 }
488}