2019-11-09 06:42:40 -05:00
|
|
|
use serde::de::DeserializeOwned;
|
|
|
|
|
2020-01-13 13:38:33 -05:00
|
|
|
use crate::algorithms::AlgorithmFamily;
|
2019-12-29 15:50:06 -05:00
|
|
|
use crate::crypto::verify;
|
2019-11-09 06:42:40 -05:00
|
|
|
use crate::errors::{new_error, ErrorKind, Result};
|
|
|
|
use crate::header::Header;
|
2019-12-29 15:50:06 -05:00
|
|
|
use crate::pem::decoder::PemEncodedKey;
|
2021-09-28 12:16:51 -04:00
|
|
|
use crate::serialization::{b64_decode, DecodedJwtPartClaims};
|
2019-11-09 06:42:40 -05:00
|
|
|
use crate::validation::{validate, Validation};
|
|
|
|
|
2019-11-14 13:43:43 -05:00
|
|
|
/// The return type of a successful call to [decode](fn.decode.html).
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct TokenData<T> {
|
|
|
|
/// The decoded JWT header
|
|
|
|
pub header: Header,
|
|
|
|
/// The decoded JWT claims
|
|
|
|
pub claims: T,
|
|
|
|
}
|
|
|
|
|
2019-11-09 06:42:40 -05:00
|
|
|
/// Takes the result of a rsplit and ensure we only get 2 parts
|
|
|
|
/// Errors if we don't
|
|
|
|
macro_rules! expect_two {
|
|
|
|
($iter:expr) => {{
|
|
|
|
let mut i = $iter;
|
|
|
|
match (i.next(), i.next(), i.next()) {
|
|
|
|
(Some(first), Some(second), None) => (first, second),
|
|
|
|
_ => return Err(new_error(ErrorKind::InvalidToken)),
|
|
|
|
}
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2019-12-29 15:50:06 -05:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2021-02-19 15:41:08 -05:00
|
|
|
pub(crate) enum DecodingKeyKind {
|
|
|
|
SecretOrDer(Vec<u8>),
|
|
|
|
RsaModulusExponent { n: Vec<u8>, e: Vec<u8> },
|
2019-11-09 06:42:40 -05:00
|
|
|
}
|
|
|
|
|
2019-12-29 15:50:06 -05:00
|
|
|
/// All the different kind of keys we can use to decode a JWT
|
|
|
|
/// This key can be re-used so make sure you only initialize it once if you can for better performance
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2021-02-19 15:41:08 -05:00
|
|
|
pub struct DecodingKey {
|
2020-01-13 13:38:33 -05:00
|
|
|
pub(crate) family: AlgorithmFamily,
|
2021-02-19 15:41:08 -05:00
|
|
|
pub(crate) kind: DecodingKeyKind,
|
2019-12-29 15:50:06 -05:00
|
|
|
}
|
2019-11-09 06:42:40 -05:00
|
|
|
|
2021-02-19 15:41:08 -05:00
|
|
|
impl DecodingKey {
|
2019-12-29 15:50:06 -05:00
|
|
|
/// If you're using HMAC, use this.
|
2021-02-19 15:41:08 -05:00
|
|
|
pub fn from_secret(secret: &[u8]) -> Self {
|
2020-01-13 13:38:33 -05:00
|
|
|
DecodingKey {
|
|
|
|
family: AlgorithmFamily::Hmac,
|
2021-02-19 15:41:08 -05:00
|
|
|
kind: DecodingKeyKind::SecretOrDer(secret.to_vec()),
|
2020-01-13 13:38:33 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-19 15:41:08 -05:00
|
|
|
/// If you're using HMAC with a base64 encoded secret, use this.
|
2020-02-28 02:20:41 -05:00
|
|
|
pub fn from_base64_secret(secret: &str) -> Result<Self> {
|
|
|
|
let out = base64::decode(&secret)?;
|
2021-02-19 15:41:08 -05:00
|
|
|
Ok(DecodingKey { family: AlgorithmFamily::Hmac, kind: DecodingKeyKind::SecretOrDer(out) })
|
2020-02-28 02:20:41 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// If you are loading a public RSA key in a PEM format, use this.
|
2021-02-19 15:41:08 -05:00
|
|
|
pub fn from_rsa_pem(key: &[u8]) -> Result<Self> {
|
2020-02-28 02:20:41 -05:00
|
|
|
let pem_key = PemEncodedKey::new(key)?;
|
|
|
|
let content = pem_key.as_rsa_key()?;
|
|
|
|
Ok(DecodingKey {
|
|
|
|
family: AlgorithmFamily::Rsa,
|
2021-02-19 15:41:08 -05:00
|
|
|
kind: DecodingKeyKind::SecretOrDer(content.to_vec()),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/// If you have (n, e) RSA public key components as strings, use this.
|
|
|
|
pub fn from_rsa_components(modulus: &str, exponent: &str) -> Result<Self> {
|
|
|
|
let n = b64_decode(modulus)?;
|
|
|
|
let e = b64_decode(exponent)?;
|
|
|
|
Ok(DecodingKey {
|
|
|
|
family: AlgorithmFamily::Rsa,
|
|
|
|
kind: DecodingKeyKind::RsaModulusExponent { n, e },
|
2020-02-28 02:20:41 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-02-19 15:41:08 -05:00
|
|
|
/// If you have (n, e) RSA public key components already decoded, use this.
|
|
|
|
pub fn from_rsa_raw_components(modulus: &[u8], exponent: &[u8]) -> Self {
|
2020-01-13 13:38:33 -05:00
|
|
|
DecodingKey {
|
|
|
|
family: AlgorithmFamily::Rsa,
|
2021-02-19 15:41:08 -05:00
|
|
|
kind: DecodingKeyKind::RsaModulusExponent { n: modulus.to_vec(), e: exponent.to_vec() },
|
2020-01-13 13:38:33 -05:00
|
|
|
}
|
2019-11-09 06:42:40 -05:00
|
|
|
}
|
|
|
|
|
2020-02-28 02:20:41 -05:00
|
|
|
/// If you have a ECDSA public key in PEM format, use this.
|
2021-02-19 15:41:08 -05:00
|
|
|
pub fn from_ec_pem(key: &[u8]) -> Result<Self> {
|
2020-02-28 02:20:41 -05:00
|
|
|
let pem_key = PemEncodedKey::new(key)?;
|
|
|
|
let content = pem_key.as_ec_public_key()?;
|
|
|
|
Ok(DecodingKey {
|
|
|
|
family: AlgorithmFamily::Ec,
|
2021-02-19 15:41:08 -05:00
|
|
|
kind: DecodingKeyKind::SecretOrDer(content.to_vec()),
|
2020-02-28 02:20:41 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-11-17 08:15:17 -05:00
|
|
|
/// If you have a EdDSA public key in PEM format, use this.
|
2021-02-19 15:41:08 -05:00
|
|
|
pub fn from_ed_pem(key: &[u8]) -> Result<Self> {
|
2020-11-17 08:15:17 -05:00
|
|
|
let pem_key = PemEncodedKey::new(key)?;
|
|
|
|
let content = pem_key.as_ed_public_key()?;
|
|
|
|
Ok(DecodingKey {
|
|
|
|
family: AlgorithmFamily::Ed,
|
2021-02-19 15:41:08 -05:00
|
|
|
kind: DecodingKeyKind::SecretOrDer(content.to_vec()),
|
2020-11-17 08:15:17 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-01-13 13:38:33 -05:00
|
|
|
/// If you know what you're doing and have a RSA DER encoded public key, use this.
|
2021-02-19 15:41:08 -05:00
|
|
|
pub fn from_rsa_der(der: &[u8]) -> Self {
|
2020-01-13 13:38:33 -05:00
|
|
|
DecodingKey {
|
|
|
|
family: AlgorithmFamily::Rsa,
|
2021-02-19 15:41:08 -05:00
|
|
|
kind: DecodingKeyKind::SecretOrDer(der.to_vec()),
|
2020-01-13 13:38:33 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// If you know what you're doing and have a RSA EC encoded public key, use this.
|
2021-02-19 15:41:08 -05:00
|
|
|
pub fn from_ec_der(der: &[u8]) -> Self {
|
2020-01-13 13:38:33 -05:00
|
|
|
DecodingKey {
|
|
|
|
family: AlgorithmFamily::Ec,
|
2021-02-19 15:41:08 -05:00
|
|
|
kind: DecodingKeyKind::SecretOrDer(der.to_vec()),
|
2020-01-13 13:38:33 -05:00
|
|
|
}
|
2019-12-29 15:50:06 -05:00
|
|
|
}
|
|
|
|
|
2020-11-17 08:15:17 -05:00
|
|
|
/// If you know what you're doing and have a Ed DER encoded public key, use this.
|
2021-02-19 15:41:08 -05:00
|
|
|
pub fn from_ed_der(der: &[u8]) -> Self {
|
2020-11-17 08:15:17 -05:00
|
|
|
DecodingKey {
|
|
|
|
family: AlgorithmFamily::Ed,
|
2021-02-19 15:41:08 -05:00
|
|
|
kind: DecodingKeyKind::SecretOrDer(der.to_vec()),
|
2020-11-17 08:15:17 -05:00
|
|
|
}
|
|
|
|
}
|
2019-12-29 15:50:06 -05:00
|
|
|
pub(crate) fn as_bytes(&self) -> &[u8] {
|
|
|
|
match &self.kind {
|
2021-08-18 04:31:52 -04:00
|
|
|
DecodingKeyKind::SecretOrDer(b) => b,
|
2019-12-29 15:50:06 -05:00
|
|
|
DecodingKeyKind::RsaModulusExponent { .. } => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
2019-11-09 06:42:40 -05:00
|
|
|
}
|
|
|
|
|
2021-02-19 15:17:59 -05:00
|
|
|
/// Verify signature of a JWT, and return header object and raw payload
|
2019-11-09 06:42:40 -05:00
|
|
|
///
|
2021-02-19 15:17:59 -05:00
|
|
|
/// If the token or its signature is invalid, it will return an error.
|
2021-09-28 04:04:51 -04:00
|
|
|
fn verify_signature<'a>(
|
2021-02-19 15:20:47 -05:00
|
|
|
token: &'a str,
|
2019-12-29 15:50:06 -05:00
|
|
|
key: &DecodingKey,
|
2019-11-09 06:42:40 -05:00
|
|
|
validation: &Validation,
|
2021-02-19 15:20:47 -05:00
|
|
|
) -> Result<(Header, &'a str)> {
|
2021-09-28 04:04:51 -04:00
|
|
|
if validation.validate_signature && validation.algorithms.is_empty() {
|
2021-03-22 16:24:20 -04:00
|
|
|
return Err(new_error(ErrorKind::MissingAlgorithm));
|
|
|
|
}
|
|
|
|
|
2021-09-28 04:04:51 -04:00
|
|
|
if validation.validate_signature {
|
|
|
|
for alg in &validation.algorithms {
|
|
|
|
if key.family != alg.family() {
|
|
|
|
return Err(new_error(ErrorKind::InvalidAlgorithm));
|
|
|
|
}
|
2020-01-13 13:38:33 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-29 15:50:06 -05:00
|
|
|
let (signature, message) = expect_two!(token.rsplitn(2, '.'));
|
2021-02-19 15:17:59 -05:00
|
|
|
let (payload, header) = expect_two!(message.rsplitn(2, '.'));
|
2019-12-29 15:50:06 -05:00
|
|
|
let header = Header::from_encoded(header)?;
|
2019-11-09 06:42:40 -05:00
|
|
|
|
2021-09-28 04:04:51 -04:00
|
|
|
if validation.validate_signature && !validation.algorithms.contains(&header.alg) {
|
2019-12-29 15:50:06 -05:00
|
|
|
return Err(new_error(ErrorKind::InvalidAlgorithm));
|
|
|
|
}
|
|
|
|
|
2021-09-28 04:04:51 -04:00
|
|
|
if validation.validate_signature && !verify(signature, message.as_bytes(), key, header.alg)? {
|
2019-12-29 15:50:06 -05:00
|
|
|
return Err(new_error(ErrorKind::InvalidSignature));
|
|
|
|
}
|
|
|
|
|
2021-02-19 15:20:47 -05:00
|
|
|
Ok((header, payload))
|
2021-02-19 15:17:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Decode and validate a JWT
|
|
|
|
///
|
|
|
|
/// If the token or its signature is invalid or the claims fail validation, it will return an error.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use serde::{Deserialize, Serialize};
|
|
|
|
/// use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};
|
|
|
|
///
|
|
|
|
/// #[derive(Debug, Serialize, Deserialize)]
|
|
|
|
/// struct Claims {
|
|
|
|
/// sub: String,
|
|
|
|
/// company: String
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// let token = "a.jwt.token".to_string();
|
|
|
|
/// // Claims is a struct that implements Deserialize
|
|
|
|
/// let token_message = decode::<Claims>(&token, &DecodingKey::from_secret("secret".as_ref()), &Validation::new(Algorithm::HS256));
|
|
|
|
/// ```
|
|
|
|
pub fn decode<T: DeserializeOwned>(
|
|
|
|
token: &str,
|
|
|
|
key: &DecodingKey,
|
|
|
|
validation: &Validation,
|
|
|
|
) -> Result<TokenData<T>> {
|
2021-02-19 15:20:47 -05:00
|
|
|
match verify_signature(token, key, validation) {
|
2021-02-19 15:17:59 -05:00
|
|
|
Err(e) => Err(e),
|
|
|
|
Ok((header, claims)) => {
|
2021-09-28 12:16:51 -04:00
|
|
|
let decoded_claims = DecodedJwtPartClaims::from_jwt_part_claims(claims)?;
|
|
|
|
let claims = decoded_claims.deserialize()?;
|
|
|
|
validate(decoded_claims.deserialize()?, validation)?;
|
2019-12-29 15:50:06 -05:00
|
|
|
|
2021-09-28 12:16:51 -04:00
|
|
|
Ok(TokenData { header, claims })
|
2021-02-19 15:17:59 -05:00
|
|
|
}
|
|
|
|
}
|
2019-11-09 06:42:40 -05:00
|
|
|
}
|
|
|
|
|
2019-11-14 13:43:43 -05:00
|
|
|
/// Decode a JWT without any signature verification/validations and return its [Header](struct.Header.html).
|
2019-11-09 06:42:40 -05:00
|
|
|
///
|
2019-11-14 13:43:43 -05:00
|
|
|
/// If the token has an invalid format (ie 3 parts separated by a `.`), it will return an error.
|
2019-11-09 06:42:40 -05:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use jsonwebtoken::decode_header;
|
|
|
|
///
|
|
|
|
/// let token = "a.jwt.token".to_string();
|
|
|
|
/// let header = decode_header(&token);
|
|
|
|
/// ```
|
|
|
|
pub fn decode_header(token: &str) -> Result<Header> {
|
|
|
|
let (_, message) = expect_two!(token.rsplitn(2, '.'));
|
|
|
|
let (_, header) = expect_two!(message.rsplitn(2, '.'));
|
|
|
|
Header::from_encoded(header)
|
|
|
|
}
|