jsonwebtoken/crypto/
rsa.rs
1use ring::{rand, signature};
2
3use crate::algorithms::Algorithm;
4use crate::errors::{ErrorKind, Result};
5use crate::serialization::{b64_decode, b64_encode};
6
7pub(crate) fn alg_to_rsa_parameters(alg: Algorithm) -> &'static signature::RsaParameters {
9 match alg {
10 Algorithm::RS256 => &signature::RSA_PKCS1_2048_8192_SHA256,
11 Algorithm::RS384 => &signature::RSA_PKCS1_2048_8192_SHA384,
12 Algorithm::RS512 => &signature::RSA_PKCS1_2048_8192_SHA512,
13 Algorithm::PS256 => &signature::RSA_PSS_2048_8192_SHA256,
14 Algorithm::PS384 => &signature::RSA_PSS_2048_8192_SHA384,
15 Algorithm::PS512 => &signature::RSA_PSS_2048_8192_SHA512,
16 _ => unreachable!("Tried to get RSA signature for a non-rsa algorithm"),
17 }
18}
19
20pub(crate) fn alg_to_rsa_signing(alg: Algorithm) -> &'static dyn signature::RsaEncoding {
22 match alg {
23 Algorithm::RS256 => &signature::RSA_PKCS1_SHA256,
24 Algorithm::RS384 => &signature::RSA_PKCS1_SHA384,
25 Algorithm::RS512 => &signature::RSA_PKCS1_SHA512,
26 Algorithm::PS256 => &signature::RSA_PSS_SHA256,
27 Algorithm::PS384 => &signature::RSA_PSS_SHA384,
28 Algorithm::PS512 => &signature::RSA_PSS_SHA512,
29 _ => unreachable!("Tried to get RSA signature for a non-rsa algorithm"),
30 }
31}
32
33pub(crate) fn sign(
37 alg: &'static dyn signature::RsaEncoding,
38 key: &[u8],
39 message: &[u8],
40) -> Result<String> {
41 let key_pair = signature::RsaKeyPair::from_der(key)
42 .map_err(|e| ErrorKind::InvalidRsaKey(e.to_string()))?;
43
44 let mut signature = vec![0; key_pair.public().modulus_len()];
45 let rng = rand::SystemRandom::new();
46 key_pair.sign(alg, &rng, message, &mut signature).map_err(|_| ErrorKind::RsaFailedSigning)?;
47
48 Ok(b64_encode(signature))
49}
50
51pub(crate) fn verify_from_components(
53 alg: &'static signature::RsaParameters,
54 signature: &str,
55 message: &[u8],
56 components: (&[u8], &[u8]),
57) -> Result<bool> {
58 let signature_bytes = b64_decode(signature)?;
59 let pubkey = signature::RsaPublicKeyComponents { n: components.0, e: components.1 };
60 let res = pubkey.verify(alg, message, &signature_bytes);
61 Ok(res.is_ok())
62}