jsonwebtoken_rustcrypto/crypto/
rsa.rs1use crate::errors::{ErrorKind, Result};
3use crate::serialization::{b64_decode, b64_encode};
4use crate::{errors, Algorithm};
5use rsa::SignatureScheme;
6use rsa::{pss::Pss, Pkcs1v15Sign, RsaPrivateKey, RsaPublicKey};
7use sha2::{Digest, Sha256, Sha384, Sha512};
8
9pub(crate) fn sign(alg: Algorithm, key: &RsaPrivateKey, message: &str) -> Result<String> {
13 let digest: Vec<u8> = match alg {
14 Algorithm::RS256 | Algorithm::PS256 => {
20 let mut hasher = Sha256::new();
21 hasher.update(message.as_bytes());
22 let d = hasher.finalize();
23 d.as_slice().to_vec()
24 }
25 Algorithm::RS384 | Algorithm::PS384 => {
26 let mut hasher = Sha384::new();
27 hasher.update(message.as_bytes());
28 let d = hasher.finalize();
29 d.as_slice().to_vec()
30 }
31 Algorithm::RS512 | Algorithm::PS512 => {
32 let mut hasher = Sha512::new();
33 hasher.update(message.as_bytes());
34 let d = hasher.finalize();
35 d.as_slice().to_vec()
36 }
37 _ => unimplemented!(),
38 };
39
40 let signatures_scheme_pkcs = match alg {
41 Algorithm::RS256 => Some(Pkcs1v15Sign::new::<Sha256>()),
42 Algorithm::RS384 => Some(Pkcs1v15Sign::new::<Sha384>()),
43 Algorithm::RS512 => Some(Pkcs1v15Sign::new::<Sha512>()),
44 _ => None,
45 };
46
47 let signatures_scheme_pss = match alg {
48 Algorithm::PS256 => Some(Pss::new_with_salt::<Sha256>(digest.len())),
49 Algorithm::PS384 => Some(Pss::new_with_salt::<Sha384>(digest.len())),
50 Algorithm::PS512 => Some(Pss::new_with_salt::<Sha512>(digest.len())),
51 _ => None,
52 };
53
54 let mut rng = rand::thread_rng();
55
56 let signature = if let Some(signatures_scheme) = signatures_scheme_pkcs {
57 signatures_scheme.sign(Some(&mut rng), key, &digest).expect("failed to sign pkcs")
59 } else if let Some(signatures_scheme) = signatures_scheme_pss {
60 signatures_scheme.sign(Some(&mut rng), key, &digest).expect("failed to sign pss")
62 } else {
63 return Err(ErrorKind::InvalidAlgorithmName.into());
64 };
65
66 Ok(b64_encode(&signature))
67}
68
69pub(crate) fn verify(
71 alg: Algorithm,
72 signature: &str,
73 message: &str,
74 key: &RsaPublicKey,
75) -> Result<bool> {
76 let digest: Vec<u8> = match alg {
77 Algorithm::RS256 | Algorithm::PS256 => {
83 let mut hasher = Sha256::new();
84 hasher.update(message.as_bytes());
85 let d = hasher.finalize();
86 d.iter().copied().collect()
87 }
88 Algorithm::RS384 | Algorithm::PS384 => {
89 let mut hasher = Sha384::new();
90 hasher.update(message.as_bytes());
91 let d = hasher.finalize();
92 d.iter().copied().collect()
93 }
94 Algorithm::RS512 | Algorithm::PS512 => {
95 let mut hasher = Sha512::new();
96 hasher.update(message.as_bytes());
97 let d = hasher.finalize();
98 d.iter().copied().collect()
99 }
100 _ => unimplemented!(),
104 };
105
106 let signature_bytes = b64_decode(signature)?;
107
108 let signatures_scheme_pkcs = match alg {
109 Algorithm::RS256 => Some(Pkcs1v15Sign::new::<Sha256>()),
110 Algorithm::RS384 => Some(Pkcs1v15Sign::new::<Sha384>()),
111 Algorithm::RS512 => Some(Pkcs1v15Sign::new::<Sha512>()),
112 _ => None,
113 };
114
115 let signatures_scheme_pss = match alg {
116 Algorithm::PS256 => Some(Pss::new_with_salt::<Sha256>(digest.len())),
117 Algorithm::PS384 => Some(Pss::new_with_salt::<Sha384>(digest.len())),
118 Algorithm::PS512 => Some(Pss::new_with_salt::<Sha512>(digest.len())),
119 _ => None,
120 };
121
122 if let Some(signatures_scheme) = signatures_scheme_pkcs {
123 signatures_scheme
124 .verify(key, &digest, &signature_bytes)
125 .map_err(|_| errors::new_error(ErrorKind::InvalidSignature))?;
126 } else if let Some(signatures_scheme) = signatures_scheme_pss {
127 signatures_scheme
128 .verify(key, &digest, &signature_bytes)
129 .map_err(|_| errors::new_error(ErrorKind::InvalidSignature))?;
130 } else {
131 return Err(ErrorKind::InvalidAlgorithmName.into());
132 };
133
134 Ok(true)
135}