jsonwebtoken_rustcrypto/
decoding.rs1use rsa::RsaPublicKey;
2use serde::de::DeserializeOwned;
3
4use crate::crypto::verify;
5use crate::errors::{new_error, ErrorKind, Result};
6use crate::header::Header;
7use crate::serialization::from_jwt_part_claims;
9use crate::validation::{validate, Validation};
10
11use base64::{engine::general_purpose::STANDARD, Engine};
12#[derive(Debug)]
14pub struct TokenData<T> {
15 pub header: Header,
17 pub claims: T,
19}
20
21macro_rules! expect_two {
24 ($iter:expr) => {{
25 let mut i = $iter;
26 match (i.next(), i.next(), i.next()) {
27 (Some(first), Some(second), None) => (first, second),
28 _ => return Err(new_error(ErrorKind::InvalidToken)),
29 }
30 }};
31}
32
33#[derive(Debug, Clone, PartialEq)]
36pub enum DecodingKey {
37 Hmac(Vec<u8>),
38 Rsa(rsa::RsaPublicKey),
39 }
41
42impl DecodingKey {
43 pub fn from_hmac_secret(secret: &[u8]) -> Self {
45 DecodingKey::Hmac(secret.to_vec())
46 }
47
48 pub fn from_base64_hmac_secret(secret: &str) -> Result<Self> {
50 Ok(DecodingKey::Hmac(STANDARD.decode(secret)?))
51 }
52
53 pub fn from_rsa(key: rsa::RsaPublicKey) -> Result<Self> {
54 Ok(DecodingKey::Rsa(key))
55 }
56
57 pub fn from_rsa_components(n: &str, e: &str) -> Result<Self> {
59 use crate::serialization::b64_decode;
60 let n = rsa::BigUint::from_bytes_be(&b64_decode(n)?);
61 let e = rsa::BigUint::from_bytes_be(&b64_decode(e)?);
62 Ok(DecodingKey::Rsa(
63 RsaPublicKey::new(n, e).map_err(|_| new_error(ErrorKind::InvalidKeyFormat))?,
64 ))
65 }
66}
67
68pub fn decode<T: DeserializeOwned>(
87 token: &str,
88 key: &DecodingKey,
89 validation: &Validation,
90) -> Result<TokenData<T>> {
91 let (signature, message) = expect_two!(token.rsplitn(2, '.'));
92 let (claims, header) = expect_two!(message.rsplitn(2, '.'));
93 let header = Header::from_encoded(header)?;
94
95 if !validation.algorithms.is_empty() & !&validation.algorithms.contains(&header.alg) {
96 return Err(new_error(ErrorKind::InvalidAlgorithm));
97 }
98
99 if !verify(signature, message, key, header.alg)? {
100 return Err(new_error(ErrorKind::InvalidSignature));
101 }
102
103 let (decoded_claims, claims_map): (T, _) = from_jwt_part_claims(claims)?;
104 validate(&claims_map, validation)?;
105
106 Ok(TokenData { header, claims: decoded_claims })
107}
108
109pub fn dangerous_insecure_decode<T: DeserializeOwned>(token: &str) -> Result<TokenData<T>> {
128 let (_, message) = expect_two!(token.rsplitn(2, '.'));
129 let (claims, header) = expect_two!(message.rsplitn(2, '.'));
130 let header = Header::from_encoded(header)?;
131
132 let (decoded_claims, _): (T, _) = from_jwt_part_claims(claims)?;
133
134 Ok(TokenData { header, claims: decoded_claims })
135}
136
137pub fn dangerous_insecure_decode_with_validation<T: DeserializeOwned>(
158 token: &str,
159 validation: &Validation,
160) -> Result<TokenData<T>> {
161 let (_, message) = expect_two!(token.rsplitn(2, '.'));
162 let (claims, header) = expect_two!(message.rsplitn(2, '.'));
163 let header = Header::from_encoded(header)?;
164
165 if !validation.algorithms.is_empty() & !&validation.algorithms.contains(&header.alg) {
166 return Err(new_error(ErrorKind::InvalidAlgorithm));
167 }
168
169 let (decoded_claims, claims_map): (T, _) = from_jwt_part_claims(claims)?;
170 validate(&claims_map, validation)?;
171
172 Ok(TokenData { header, claims: decoded_claims })
173}
174
175#[deprecated(
177 note = "This function has been renamed to `dangerous_insecure_decode` and will be removed in a later version."
178)]
179pub fn dangerous_unsafe_decode<T: DeserializeOwned>(token: &str) -> Result<TokenData<T>> {
180 dangerous_insecure_decode(token)
181}
182
183pub fn decode_header(token: &str) -> Result<Header> {
194 let (_, message) = expect_two!(token.rsplitn(2, '.'));
195 let (_, header) = expect_two!(message.rsplitn(2, '.'));
196 Header::from_encoded(header)
197}