1use crate::{
2 algorithms::Algorithm, crypto::SignFromKey, crypto::VerifyFromKey, errors::Error, log,
3};
4use rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey};
5use rsa::pkcs1v15::Signature;
6use rsa::pkcs8::{DecodePrivateKey, DecodePublicKey};
7use rsa::sha2::{Sha256, Sha384, Sha512};
8use rsa::signature::{RandomizedSigner, SignatureEncoding, SignerMut, Verifier};
9
10#[derive(Debug)]
11pub struct RsaSigningKey {
12 key: rsa::RsaPrivateKey,
13}
14
15impl RsaSigningKey {
16 pub fn from_pem(key_str: &str) -> Result<Self, Error> {
17 let rsa_key = match key_str.starts_with("-----BEGIN RSA PRIVATE KEY-----") {
18 true => match rsa::RsaPrivateKey::from_pkcs1_pem(key_str) {
19 Ok(val) => val,
20 Err(error) => {
21 log::error(error.to_string().as_str());
22 return Err(Error::PRIVATE_KEY_IDENTIFICATION_ERROR);
23 }
24 },
25 false => match rsa::RsaPrivateKey::from_pkcs8_pem(key_str) {
26 Ok(val) => val,
27 Err(error) => {
28 log::error(error.to_string().as_str());
29 return Err(Error::PRIVATE_KEY_IDENTIFICATION_ERROR);
30 }
31 },
32 };
33
34 Ok(RsaSigningKey { key: rsa_key })
35 }
36}
37
38impl SignFromKey for RsaSigningKey {
39 fn sign(&self, message: String, alg: Algorithm) -> Result<String, Error> {
40 let key = self.key.clone();
41
42 let mut rng = rand::thread_rng();
43 if alg.to_str().starts_with("RS") {
44 let sig: Signature = match alg {
45 Algorithm::RS256 => {
46 let mut signing_key = rsa::pkcs1v15::SigningKey::<Sha256>::new(key);
47 signing_key.sign(message.as_bytes())
48 }
49 Algorithm::RS384 => {
50 let mut signing_key = rsa::pkcs1v15::SigningKey::<Sha384>::new(key);
51 signing_key.sign(message.as_bytes())
52 }
53 Algorithm::RS512 => {
54 let mut signing_key = rsa::pkcs1v15::SigningKey::<Sha512>::new(key);
55 signing_key.sign(message.as_bytes())
56 }
57 _ => return Err(Error::UNKNOWN_ALGORITHM),
58 };
59 let bytes = sig.to_bytes();
60 Ok(base64_url::encode(&bytes))
61 } else {
62 let sig = match alg {
63 Algorithm::PS256 => {
64 let signing_key = rsa::pss::SigningKey::<Sha256>::new(key);
65 signing_key.sign_with_rng(&mut rng, message.as_bytes())
66 }
67 Algorithm::PS384 => {
68 let signing_key = rsa::pss::SigningKey::<Sha384>::new(key);
69 signing_key.sign_with_rng(&mut rng, message.as_bytes())
70 }
71 Algorithm::PS512 => {
72 let signing_key = rsa::pss::SigningKey::<Sha512>::new(key);
73 signing_key.sign_with_rng(&mut rng, message.as_bytes())
74 }
75 _ => return Err(Error::UNKNOWN_ALGORITHM),
76 };
77
78 let bytes = sig.to_bytes();
79 Ok(base64_url::encode(&bytes))
80 }
81 }
82}
83
84#[derive(Debug)]
85pub struct RsaVerifyingKey {
86 key: rsa::RsaPublicKey,
87}
88
89impl RsaVerifyingKey {
90 pub fn from_pem(key_str: &str) -> Result<Self, Error> {
91 let rsa_key = match key_str.starts_with("-----BEGIN RSA PUBLIC KEY-----") {
92 true => match rsa::RsaPublicKey::from_pkcs1_pem(key_str) {
93 Ok(val) => val,
94 Err(error) => {
95 log::error(error.to_string().as_str());
96 return Err(Error::PRIVATE_KEY_IDENTIFICATION_ERROR);
97 }
98 },
99 false => match rsa::RsaPublicKey::from_public_key_pem(key_str) {
100 Ok(val) => val,
101 Err(error) => {
102 log::error(error.to_string().as_str());
103 return Err(Error::PRIVATE_KEY_IDENTIFICATION_ERROR);
104 }
105 },
106 };
107
108 Ok(RsaVerifyingKey { key: rsa_key })
109 }
110}
111
112impl VerifyFromKey for RsaVerifyingKey {
113 fn verify(&self, message: String, signature: String, alg: Algorithm) -> Result<bool, Error> {
114 let key = self.key.clone();
115
116 let decoded_sig_data = match base64_url::decode(&signature) {
117 Ok(val) => val,
118 Err(error) => {
119 log::error(error.to_string().as_str());
120 return Err(Error::DECODING_ERROR);
121 }
122 };
123
124 if alg.to_str().starts_with("RS") {
125 let sig = match rsa::pkcs1v15::Signature::try_from(decoded_sig_data.as_slice()) {
126 Ok(val) => val,
127 Err(error) => {
128 log::error(error.to_string().as_str());
129 return Err(Error::SIGNATURE_IDENTIFICATION_FAILED);
130 }
131 };
132
133 let verification = match alg {
134 Algorithm::RS256 => {
135 let verifying_key = rsa::pkcs1v15::VerifyingKey::<Sha256>::new(key);
136 verifying_key.verify(message.as_bytes(), &sig)
137 }
138 Algorithm::RS384 => {
139 let verifying_key = rsa::pkcs1v15::VerifyingKey::<Sha384>::new(key);
140 verifying_key.verify(message.as_bytes(), &sig)
141 }
142 Algorithm::RS512 => {
143 let verifying_key = rsa::pkcs1v15::VerifyingKey::<Sha512>::new(key);
144 verifying_key.verify(message.as_bytes(), &sig)
145 }
146 _ => return Err(Error::UNKNOWN_ALGORITHM),
147 };
148
149 if verification.is_ok() {
150 return Ok(true);
151 } else {
152 match verification.err() {
153 Some(val) => {
154 log::error(val.to_string().as_str());
155 }
156 None => {}
157 }
158 return Ok(false);
159 }
160 } else {
161 let sig = match rsa::pss::Signature::try_from(decoded_sig_data.as_slice()) {
162 Ok(val) => val,
163 Err(error) => {
164 log::error(error.to_string().as_str());
165 return Err(Error::SIGNATURE_IDENTIFICATION_FAILED);
166 }
167 };
168
169 let verification = match alg {
170 Algorithm::RS256 => {
171 let verifying_key = rsa::pss::VerifyingKey::<Sha256>::new(key);
172 verifying_key.verify(message.as_bytes(), &sig)
173 }
174 Algorithm::RS384 => {
175 let verifying_key = rsa::pss::VerifyingKey::<Sha384>::new(key);
176 verifying_key.verify(message.as_bytes(), &sig)
177 }
178 Algorithm::RS512 => {
179 let verifying_key = rsa::pss::VerifyingKey::<Sha512>::new(key);
180 verifying_key.verify(message.as_bytes(), &sig)
181 }
182 _ => return Err(Error::UNKNOWN_ALGORITHM),
183 };
184
185 if verification.is_ok() {
186 return Ok(true);
187 } else {
188 match verification.err() {
189 Some(val) => {
190 log::error(val.to_string().as_str());
191 }
192 None => {}
193 }
194 return Ok(false);
195 }
196 }
197 }
198}
199
200pub fn sign_rsa(message: String, key: impl SignFromKey, alg: Algorithm) -> Result<String, Error> {
201 key.sign(message, alg)
202}
203
204pub fn verify_rsa(
205 message: String,
206 signature: String,
207 key: impl VerifyFromKey,
208 alg: Algorithm,
209) -> Result<bool, Error> {
210 key.verify(message, signature, alg)
211}