jsonwebtoken/src/crypto/rsa.rs

63 lines
2.5 KiB
Rust
Raw Normal View History

2019-11-08 14:00:19 -05:00
use ring::{rand, signature};
2019-11-11 14:29:57 -05:00
use crate::algorithms::Algorithm;
2019-11-08 14:00:19 -05:00
use crate::errors::{ErrorKind, Result};
2019-11-11 14:29:57 -05:00
use crate::serialization::{b64_decode, b64_encode};
2019-11-11 14:16:34 -05:00
/// Only used internally when validating RSA, to map from our enum to the Ring param structs.
pub(crate) fn alg_to_rsa_parameters(alg: Algorithm) -> &'static signature::RsaParameters {
match alg {
Algorithm::RS256 => &signature::RSA_PKCS1_2048_8192_SHA256,
Algorithm::RS384 => &signature::RSA_PKCS1_2048_8192_SHA384,
Algorithm::RS512 => &signature::RSA_PKCS1_2048_8192_SHA512,
Algorithm::PS256 => &signature::RSA_PSS_2048_8192_SHA256,
Algorithm::PS384 => &signature::RSA_PSS_2048_8192_SHA384,
Algorithm::PS512 => &signature::RSA_PSS_2048_8192_SHA512,
_ => unreachable!("Tried to get RSA signature for a non-rsa algorithm"),
}
}
2019-11-11 14:29:57 -05:00
/// Only used internally when signing with RSA, to map from our enum to the Ring signing structs.
pub(crate) fn alg_to_rsa_signing(alg: Algorithm) -> &'static dyn signature::RsaEncoding {
match alg {
Algorithm::RS256 => &signature::RSA_PKCS1_SHA256,
Algorithm::RS384 => &signature::RSA_PKCS1_SHA384,
Algorithm::RS512 => &signature::RSA_PKCS1_SHA512,
Algorithm::PS256 => &signature::RSA_PSS_SHA256,
Algorithm::PS384 => &signature::RSA_PSS_SHA384,
Algorithm::PS512 => &signature::RSA_PSS_SHA512,
_ => unreachable!("Tried to get RSA signature for a non-rsa algorithm"),
}
}
2019-11-08 14:00:19 -05:00
/// The actual RSA signing + encoding
2019-12-29 12:42:35 -05:00
/// The key needs to be in PKCS8 format
2019-11-08 14:00:19 -05:00
/// Taken from Ring doc https://briansmith.org/rustdoc/ring/signature/index.html
2019-11-11 14:16:34 -05:00
pub(crate) fn sign(
2019-11-08 14:00:19 -05:00
alg: &'static dyn signature::RsaEncoding,
key: &[u8],
2020-11-17 08:17:40 -05:00
message: &[u8],
2019-11-08 14:00:19 -05:00
) -> Result<String> {
let key_pair = signature::RsaKeyPair::from_der(key)
.map_err(|e| ErrorKind::InvalidRsaKey(e.description_()))?;
2019-11-08 14:00:19 -05:00
let mut signature = vec![0; key_pair.public_modulus_len()];
let rng = rand::SystemRandom::new();
key_pair.sign(alg, &rng, message, &mut signature).map_err(|_| ErrorKind::RsaFailedSigning)?;
2019-11-08 14:00:19 -05:00
Ok(b64_encode(signature))
2019-11-11 14:16:34 -05:00
}
2019-12-29 15:50:06 -05:00
/// Checks that a signature is valid based on the (n, e) RSA pubkey components
2019-11-11 14:16:34 -05:00
pub(crate) fn verify_from_components(
2019-11-11 14:29:57 -05:00
alg: &'static signature::RsaParameters,
2019-12-29 15:50:06 -05:00
signature: &str,
2020-11-17 08:17:40 -05:00
message: &[u8],
components: (&[u8], &[u8]),
2019-11-11 14:29:57 -05:00
) -> Result<bool> {
2019-12-29 15:50:06 -05:00
let signature_bytes = b64_decode(signature)?;
let pubkey = signature::RsaPublicKeyComponents { n: components.0, e: components.1 };
2020-11-17 08:17:40 -05:00
let res = pubkey.verify(alg, message, &signature_bytes);
2019-11-11 14:16:34 -05:00
Ok(res.is_ok())
2019-11-08 14:00:19 -05:00
}