1use pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePublicKey};
5use rsa::{
6 Pkcs1v15Sign, RsaPrivateKey, RsaPublicKey, pkcs1::DecodeRsaPrivateKey, rand_core::OsRng,
7};
8use sha2::{Digest, Sha256};
9
10use crate::{Signer, SignerError};
11
12pub struct RsaSigner {
14 private_key: RsaPrivateKey,
15 public_key: RsaPublicKey,
16 cached_public_key_pem: Vec<u8>,
17}
18
19impl RsaSigner {
20 fn from_key_pair(
21 private_key: RsaPrivateKey,
22 public_key: RsaPublicKey,
23 ) -> Result<Self, SignerError> {
24 let cached_public_key_pem = public_key
25 .to_public_key_pem(pkcs8::LineEnding::LF)
26 .map_err(|e| SignerError::Pkcs8(e.to_string()))?
27 .into_bytes();
28 Ok(Self {
29 private_key,
30 public_key,
31 cached_public_key_pem,
32 })
33 }
34
35 pub fn generate(key_size: usize) -> Result<Self, SignerError> {
36 let private_key = RsaPrivateKey::new(&mut OsRng, key_size)
37 .map_err(|e| SignerError::Rsa(e.to_string()))?;
38 let public_key = private_key.to_public_key();
39 Self::from_key_pair(private_key, public_key)
40 }
41
42 pub fn from_pem(pem: &str) -> Result<Self, SignerError> {
43 use crate::pem_loader::{PemKind, classify_pem};
44
45 let private_key =
46 match classify_pem(pem) {
47 PemKind::Pkcs1Rsa => RsaPrivateKey::from_pkcs1_pem(pem)
48 .map_err(|e| SignerError::Rsa(e.to_string()))?,
49 PemKind::Pkcs8 => RsaPrivateKey::from_pkcs8_pem(pem)
50 .map_err(|e| SignerError::Pkcs8(e.to_string()))?,
51 _ => return Err(SignerError::UnknownKeyFormat),
52 };
53
54 let public_key = private_key.to_public_key();
55 Self::from_key_pair(private_key, public_key)
56 }
57
58 pub fn to_pem(&self) -> Result<String, SignerError> {
59 use pkcs8::EncodePrivateKey;
60
61 self.private_key
62 .to_pkcs8_pem(pkcs8::LineEnding::LF)
63 .map(|pem| pem.to_string())
64 .map_err(|e| SignerError::Pkcs8(e.to_string()))
65 }
66
67 pub fn public_key_to_pem(&self) -> Result<String, SignerError> {
68 self.public_key
69 .to_public_key_pem(pkcs8::LineEnding::LF)
70 .map_err(|e| SignerError::Pkcs8(e.to_string()))
71 }
72
73 pub fn verify_with_public_key(
74 data: &[u8],
75 public_key_pem: &[u8],
76 signature: &[u8],
77 ) -> Result<(), SignerError> {
78 let public_key_str = std::str::from_utf8(public_key_pem)
79 .map_err(|e| SignerError::InvalidPublicKey(e.to_string()))?;
80 let public_key = RsaPublicKey::from_public_key_pem(public_key_str)
81 .map_err(|e| SignerError::InvalidPublicKey(e.to_string()))?;
82 let hash = Sha256::digest(data);
83 public_key
84 .verify(Pkcs1v15Sign::new::<Sha256>(), &hash, signature)
85 .map_err(|_| SignerError::VerificationFailed)
86 }
87}
88
89impl Signer for RsaSigner {
90 fn algorithm(&self) -> &'static str {
91 "rsa"
92 }
93
94 fn public_key(&self) -> &[u8] {
95 &self.cached_public_key_pem
96 }
97
98 fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SignerError> {
99 let hash = Sha256::digest(data);
100 self.private_key
101 .sign(Pkcs1v15Sign::new::<Sha256>(), &hash)
102 .map_err(|e| SignerError::Rsa(e.to_string()))
103 }
104
105 fn verify(&self, data: &[u8], signature: &[u8]) -> Result<(), SignerError> {
106 let hash = Sha256::digest(data);
107 self.public_key
108 .verify(Pkcs1v15Sign::new::<Sha256>(), &hash, signature)
109 .map_err(|_| SignerError::VerificationFailed)
110 }
111}