jsonwebtoken/
decoding.rs

1use std::borrow::Cow;
2
3use serde::de::DeserializeOwned;
4
5use crate::algorithms::AlgorithmFamily;
6use crate::crypto::verify;
7use crate::errors::{new_error, ErrorKind, Result};
8use crate::header::Header;
9use crate::pem::decoder::PemEncodedKey;
10use crate::serialization::from_jwt_part_claims;
11use crate::validation::{validate, Validation};
12
13/// The return type of a successful call to [decode](fn.decode.html).
14#[derive(Debug)]
15pub struct TokenData<T> {
16    /// The decoded JWT header
17    pub header: Header,
18    /// The decoded JWT claims
19    pub claims: T,
20}
21
22/// Takes the result of a rsplit and ensure we only get 2 parts
23/// Errors if we don't
24macro_rules! expect_two {
25    ($iter:expr) => {{
26        let mut i = $iter;
27        match (i.next(), i.next(), i.next()) {
28            (Some(first), Some(second), None) => (first, second),
29            _ => return Err(new_error(ErrorKind::InvalidToken)),
30        }
31    }};
32}
33
34#[derive(Debug, Clone, PartialEq)]
35pub(crate) enum DecodingKeyKind<'a> {
36    SecretOrDer(Cow<'a, [u8]>),
37    RsaModulusExponent { n: Cow<'a, str>, e: Cow<'a, str> },
38}
39
40/// All the different kind of keys we can use to decode a JWT
41/// This key can be re-used so make sure you only initialize it once if you can for better performance
42#[derive(Debug, Clone, PartialEq)]
43pub struct DecodingKey<'a> {
44    pub(crate) family: AlgorithmFamily,
45    pub(crate) kind: DecodingKeyKind<'a>,
46}
47
48impl<'a> DecodingKey<'a> {
49    /// If you're using HMAC, use this.
50    pub fn from_secret(secret: &'a [u8]) -> Self {
51        DecodingKey {
52            family: AlgorithmFamily::Hmac,
53            kind: DecodingKeyKind::SecretOrDer(Cow::Borrowed(secret)),
54        }
55    }
56
57    /// If you're using HMAC with a base64 encoded, use this.
58    pub fn from_base64_secret(secret: &str) -> Result<Self> {
59        let out = base64::decode(&secret)?;
60        Ok(DecodingKey {
61            family: AlgorithmFamily::Hmac,
62            kind: DecodingKeyKind::SecretOrDer(Cow::Owned(out)),
63        })
64    }
65
66    /// If you are loading a public RSA key in a PEM format, use this.
67    pub fn from_rsa_pem(key: &'a [u8]) -> Result<Self> {
68        let pem_key = PemEncodedKey::new(key)?;
69        let content = pem_key.as_rsa_key()?;
70        Ok(DecodingKey {
71            family: AlgorithmFamily::Rsa,
72            kind: DecodingKeyKind::SecretOrDer(Cow::Owned(content.to_vec())),
73        })
74    }
75
76    /// If you have (n, e) RSA public key components, use this.
77    pub fn from_rsa_components(modulus: &'a str, exponent: &'a str) -> Self {
78        DecodingKey {
79            family: AlgorithmFamily::Rsa,
80            kind: DecodingKeyKind::RsaModulusExponent {
81                n: Cow::Borrowed(modulus),
82                e: Cow::Borrowed(exponent),
83            },
84        }
85    }
86
87    /// If you have a ECDSA public key in PEM format, use this.
88    pub fn from_ec_pem(key: &'a [u8]) -> Result<Self> {
89        let pem_key = PemEncodedKey::new(key)?;
90        let content = pem_key.as_ec_public_key()?;
91        Ok(DecodingKey {
92            family: AlgorithmFamily::Ec,
93            kind: DecodingKeyKind::SecretOrDer(Cow::Owned(content.to_vec())),
94        })
95    }
96
97    /// If you know what you're doing and have a RSA DER encoded public key, use this.
98    pub fn from_rsa_der(der: &'a [u8]) -> Self {
99        DecodingKey {
100            family: AlgorithmFamily::Rsa,
101            kind: DecodingKeyKind::SecretOrDer(Cow::Borrowed(der)),
102        }
103    }
104
105    /// If you know what you're doing and have a RSA EC encoded public key, use this.
106    pub fn from_ec_der(der: &'a [u8]) -> Self {
107        DecodingKey {
108            family: AlgorithmFamily::Ec,
109            kind: DecodingKeyKind::SecretOrDer(Cow::Borrowed(der)),
110        }
111    }
112
113    /// Convert self to `DecodingKey<'static>`.
114    pub fn into_static(self) -> DecodingKey<'static> {
115        use DecodingKeyKind::*;
116        let DecodingKey { family, kind } = self;
117        let static_kind = match kind {
118            SecretOrDer(key) => SecretOrDer(Cow::Owned(key.into_owned())),
119            RsaModulusExponent { n, e } => {
120                RsaModulusExponent { n: Cow::Owned(n.into_owned()), e: Cow::Owned(e.into_owned()) }
121            }
122        };
123        DecodingKey { family, kind: static_kind }
124    }
125
126    pub(crate) fn as_bytes(&self) -> &[u8] {
127        match &self.kind {
128            DecodingKeyKind::SecretOrDer(b) => &b,
129            DecodingKeyKind::RsaModulusExponent { .. } => unreachable!(),
130        }
131    }
132}
133
134/// Decode and validate a JWT
135///
136/// If the token or its signature is invalid or the claims fail validation, it will return an error.
137///
138/// ```rust
139/// use serde::{Deserialize, Serialize};
140/// use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};
141///
142/// #[derive(Debug, Serialize, Deserialize)]
143/// struct Claims {
144///    sub: String,
145///    company: String
146/// }
147///
148/// let token = "a.jwt.token".to_string();
149/// // Claims is a struct that implements Deserialize
150/// let token_message = decode::<Claims>(&token, &DecodingKey::from_secret("secret".as_ref()), &Validation::new(Algorithm::HS256));
151/// ```
152pub fn decode<T: DeserializeOwned>(
153    token: &str,
154    key: &DecodingKey,
155    validation: &Validation,
156) -> Result<TokenData<T>> {
157    for alg in &validation.algorithms {
158        if key.family != alg.family() {
159            return Err(new_error(ErrorKind::InvalidAlgorithm));
160        }
161    }
162
163    let (signature, message) = expect_two!(token.rsplitn(2, '.'));
164    let (claims, header) = expect_two!(message.rsplitn(2, '.'));
165    let header = Header::from_encoded(header)?;
166
167    if !validation.algorithms.contains(&header.alg) {
168        return Err(new_error(ErrorKind::InvalidAlgorithm));
169    }
170
171    if !verify(signature, message, key, header.alg)? {
172        return Err(new_error(ErrorKind::InvalidSignature));
173    }
174
175    let (decoded_claims, claims_map): (T, _) = from_jwt_part_claims(claims)?;
176    validate(&claims_map, validation)?;
177
178    Ok(TokenData { header, claims: decoded_claims })
179}
180
181/// Decode a JWT without any signature verification/validations.
182///
183/// NOTE: Do not use this unless you know what you are doing! If the token's signature is invalid, it will *not* return an error.
184///
185/// ```rust
186/// use serde::{Deserialize, Serialize};
187/// use jsonwebtoken::{dangerous_insecure_decode, Validation, Algorithm};
188///
189/// #[derive(Debug, Serialize, Deserialize)]
190/// struct Claims {
191///     sub: String,
192///     company: String
193/// }
194///
195/// let token = "a.jwt.token".to_string();
196/// // Claims is a struct that implements Deserialize
197/// let token_message = dangerous_insecure_decode::<Claims>(&token);
198/// ```
199pub fn dangerous_insecure_decode<T: DeserializeOwned>(token: &str) -> Result<TokenData<T>> {
200    let (_, message) = expect_two!(token.rsplitn(2, '.'));
201    let (claims, header) = expect_two!(message.rsplitn(2, '.'));
202    let header = Header::from_encoded(header)?;
203
204    let (decoded_claims, _): (T, _) = from_jwt_part_claims(claims)?;
205
206    Ok(TokenData { header, claims: decoded_claims })
207}
208
209/// Decode and validate a JWT without any signature verification.
210///
211/// If the token is invalid or the claims fail validation, it will return an error.
212///
213/// NOTE: Do not use this unless you know what you are doing! If the token's signature is invalid, it will *not* return an error.
214///
215/// ```rust
216/// use serde::{Deserialize, Serialize};
217/// use jsonwebtoken::{dangerous_insecure_decode_with_validation, Validation, Algorithm};
218///
219/// #[derive(Debug, Serialize, Deserialize)]
220/// struct Claims {
221///    sub: String,
222///    company: String
223/// }
224///
225/// let token = "a.jwt.token";
226/// // Claims is a struct that implements Deserialize
227/// let token_message = dangerous_insecure_decode_with_validation::<Claims>(&token, &Validation::new(Algorithm::HS256));
228/// ```
229pub fn dangerous_insecure_decode_with_validation<T: DeserializeOwned>(
230    token: &str,
231    validation: &Validation,
232) -> Result<TokenData<T>> {
233    let (_, message) = expect_two!(token.rsplitn(2, '.'));
234    let (claims, header) = expect_two!(message.rsplitn(2, '.'));
235    let header = Header::from_encoded(header)?;
236
237    if !validation.algorithms.contains(&header.alg) {
238        return Err(new_error(ErrorKind::InvalidAlgorithm));
239    }
240
241    let (decoded_claims, claims_map): (T, _) = from_jwt_part_claims(claims)?;
242    validate(&claims_map, validation)?;
243
244    Ok(TokenData { header, claims: decoded_claims })
245}
246
247/// Decode a JWT without any signature verification/validations. DEPRECATED.
248#[deprecated(
249    note = "This function has been renamed to `dangerous_insecure_decode` and will be removed in a later version."
250)]
251pub fn dangerous_unsafe_decode<T: DeserializeOwned>(token: &str) -> Result<TokenData<T>> {
252    dangerous_insecure_decode(token)
253
254}
255
256/// Decode a JWT without any signature verification/validations and return its [Header](struct.Header.html).
257///
258/// If the token has an invalid format (ie 3 parts separated by a `.`), it will return an error.
259///
260/// ```rust
261/// use jsonwebtoken::decode_header;
262///
263/// let token = "a.jwt.token".to_string();
264/// let header = decode_header(&token);
265/// ```
266pub fn decode_header(token: &str) -> Result<Header> {
267    let (_, message) = expect_two!(token.rsplitn(2, '.'));
268    let (_, header) = expect_two!(message.rsplitn(2, '.'));
269    Header::from_encoded(header)
270}