Skip to main content

jwt/
jwt.rs

1//! Sign, parse, and verify JSON Web Tokens (JWT).
2//!
3//! # Two-step verification flow
4//!
5//! [`parse_header`] and [`parse_and_verify`] are separate so that you can
6//! inspect the header, especially the `kid` field (Key ID), before choosing
7//! which key to verify with. This is essential when the key must be looked up dynamically.
8//!
9//! # `no_std` support
10//!
11//! Disable default features (`default-features = false`) and provide your own
12//! [`Clock`] implementation for time-based claim verification (optional).
13//!
14//! # Example
15//!
16//! ```
17//! use jwt::*;
18//! use crypto::curve25519::ed25519;
19//!
20//! fn main() -> Result<(), Error> {
21//!     // 1. Generate an Ed25519 secret key.
22//!     let secret_key = ed25519::SecretKey::generate();
23//!
24//!     // 2. Build the header.
25//!     let header = Header {
26//!         typ: TokenType::JWT,
27//!         alg: Algorithm::EdDSA,
28//!         kid: Some("my-key-id".into()),
29//!         cty: None,
30//!         jku: None,
31//!         x5u: None,
32//!         x5c: None,
33//!         x5t: None,
34//!         x5t_s256: None,
35//!     };
36//!
37//!     // 3. Define the claims and sign.
38//!     let claims = serde_json::json!({ "sub": "user123", "exp": 9999999999_u64 });
39//!     let token = sign(&secret_key, &header, &claims)?;
40//!
41//!     // 4. Extract the public key for verification.
42//!     let public_key = secret_key.public_key();
43//!
44//!     // 5. Parse only the header first (e.g., to read `kid` for key lookup).
45//!     let parsed_header = parse_header(&token)?;
46//!     assert_eq!(parsed_header.kid.as_deref(), Some("my-key-id"));
47//!
48//!     // 6. Now verify and deserialize the claims.
49//!     let opts = VerifyOptions {
50//!         allowed_time_drift: core::time::Duration::from_secs(60),
51//!         exp: true,
52//!         nbf: false,
53//!         aud: None,
54//!         iss: None,
55//!         clock: Some(&jwt::SYSTEM_CLOCK),
56//!     };
57//!     let claims: serde_json::Value =
58//!         parse_and_verify(&public_key, &parsed_header, &token, &opts)?;
59//!     assert_eq!(claims["sub"], "user123");
60//!
61//!     Ok(())
62//! }
63//! ```
64//!
65//! # JSON Web Key (JWK) import and export
66//!
67//! Keys can be exported to and imported from JSON Web Keys (JWK) for publishing or later re-use.
68//! Every supported key type implements `From<&KeyType> for Jwk`, and the reverse conversion is
69//! available through `TryFrom<&Jwk>`. Use it when the key is only known at runtime, for example
70//! after fetching a JWKS document. P-256, P-384 and P-521 public keys are all supported.
71//!
72//! ```
73//! use jwt::*;
74//! use crypto::p256;
75//!
76//! fn main() -> Result<(), Error> {
77//!     // Generate a P-256 key pair.
78//!     let secret_key = p256::SecretKey::generate().map_err(|_| Error::InvalidKey)?;
79//!     let public_key = secret_key.public_key();
80//!
81//!     // Convert to a JWK (e.g. for publishing in a JWKS endpoint).
82//!     let jwk = Jwk::from(&public_key);
83//!     assert_eq!(jwk.algorithm, Algorithm::ES256);
84//!
85//!     // Parse the JWK back into a key (e.g. from a JWKS response).
86//!     let key = p256::PublicKey::try_from(&jwk)?;
87//!
88//!     let header = Header { typ: TokenType::JWT, alg: Algorithm::ES256, ..Default::default() };
89//!     let token = sign(&secret_key, &header, &serde_json::json!({"exp": 9999999999_u64, "nbf": 0_u64 }))?;
90//!     let parsed_header = parse_header(&token)?;
91//!     let _claims: serde_json::Value = parse_and_verify(&key, &parsed_header, &token, &VerifyOptions::default())?;
92//!
93//!     Ok(())
94//! }
95//! ```
96//!
97//! When the key type is not known ahead of time (for example a JWKS document that may contain
98//! several kinds of keys), use the [`Key`] enum. It inspects the JWK's `kty` and `crv` and selects the
99//! matching concrete key, preferring the secret variant when both halves are present. [`Key`]
100//! implements both [`Signer`] and [`Verifier`], so it can be passed straight to [`sign`] or
101//! [`parse_and_verify`]:
102//!
103//! ```
104//! use jwt::*;
105//! use crypto::curve25519::ed25519;
106//!
107//! fn main() -> Result<(), Error> {
108//!     let secret_key = ed25519::SecretKey::generate();
109//!
110//!     // A JWKS entry whose key type is only known at runtime.
111//!     let jwk = Jwk::from(&secret_key.public_key());
112//!     let key = Key::try_from(&jwk)?;
113//!     assert!(matches!(key, Key::Ed25519Public(_)));
114//!
115//!     let header = Header { typ: TokenType::JWT, alg: Algorithm::EdDSA, ..Default::default() };
116//!     let token = sign(&secret_key, &header, &serde_json::json!({"exp": 9999999999_u64, "nbf": 0_u64 }))?;
117//!     let parsed_header = parse_header(&token)?;
118//!     let _claims: serde_json::Value = parse_and_verify(&key, &parsed_header, &token, &VerifyOptions::default())?;
119//!
120//!     Ok(())
121//! }
122//! ```
123//!
124//! When a JWK derived from a secret key is decoded, the secret variant is preferred, so the same
125//! [`Key`] can be used for signing:
126//!
127//! ```
128//! use jwt::*;
129//! use crypto::curve25519::ed25519;
130//!
131//! fn main() -> Result<(), Error> {
132//!     let secret_key = ed25519::SecretKey::generate();
133//!     let jwk = Jwk::from(&secret_key);
134//!     let key = Key::try_from(&jwk)?;
135//!     assert!(matches!(key, Key::Ed25519Secret(_)));
136//!
137//!     let header = Header { typ: TokenType::JWT, alg: Algorithm::EdDSA, ..Default::default() };
138//!     let token = sign(&key, &header, &serde_json::json!({"exp": 9999999999_u64, "nbf": 0_u64 }))?;
139//!     let parsed_header = parse_header(&token)?;
140//!     let _claims: serde_json::Value = parse_and_verify(&key, &parsed_header, &token, &VerifyOptions::default())?;
141//!
142//!     Ok(())
143//! }
144//! ```
145
146#![cfg_attr(not(feature = "std"), no_std)]
147
148extern crate alloc;
149
150use alloc::{
151    string::{String, ToString},
152    vec::Vec,
153};
154use core::time::Duration;
155
156use serde::{Deserialize, Serialize, de::DeserializeOwned};
157use small_collections::SmallString;
158
159mod jwk;
160mod jwt_crypto;
161
162pub use jwk::*;
163pub use jwt_crypto::*;
164
165#[cfg(feature = "std")]
166pub static SYSTEM_CLOCK: SystemClock = SystemClock;
167
168#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
169pub struct Header {
170    /// The only valid value is "JWT"
171    /// https://tools.ietf.org/html/rfc7519#section-5.1
172    pub typ: TokenType,
173
174    /// ttps://tools.ietf.org/html/rfc7515#section-4.1.1
175    pub alg: Algorithm,
176
177    /// Content type
178    /// https://tools.ietf.org/html/rfc7519#section-5.2
179    #[serde(skip_serializing_if = "Option::is_none")]
180    pub cty: Option<SmallString<3>>,
181
182    /// JSON Key URL
183    /// https://tools.ietf.org/html/rfc7515#section-4.1.2
184    #[serde(skip_serializing_if = "Option::is_none")]
185    pub jku: Option<String>,
186
187    /// JSON Web Key
188    /// https://tools.ietf.org/html/rfc7515#section-4.1.3
189    // #[serde(skip_serializing_if = "Option::is_none")]
190    // pub jwk: Option<Jwk>,
191
192    /// Key ID
193    /// https://tools.ietf.org/html/rfc7515#section-4.1.4
194    #[serde(skip_serializing_if = "Option::is_none")]
195    pub kid: Option<SmallString<36>>, // 36 = UUID length
196
197    /// X.509 URL
198    /// https://tools.ietf.org/html/rfc7515#section-4.1.5
199    #[serde(skip_serializing_if = "Option::is_none")]
200    pub x5u: Option<String>,
201
202    /// X.509 certificate chain.
203    /// https://tools.ietf.org/html/rfc7515#section-4.1.6
204    #[serde(skip_serializing_if = "Option::is_none")]
205    pub x5c: Option<Vec<String>>,
206
207    /// X.509 SHA1 certificate Thumbprint
208    /// https://tools.ietf.org/html/rfc7515#section-4.1.7
209    #[serde(skip_serializing_if = "Option::is_none")]
210    pub x5t: Option<SmallString<27>>, // 27 = base64_encoded_length(20)
211
212    /// X.509 SHA256 certificate Thumbprint
213    /// https://tools.ietf.org/html/rfc7515#section-4.1.8
214    #[serde(skip_serializing_if = "Option::is_none")]
215    #[serde(rename = "x5t#S256")]
216    pub x5t_s256: Option<SmallString<43>>, // 43 = base64_encoded_length(32)
217}
218
219impl Default for Header {
220    fn default() -> Self {
221        Self {
222            typ: TokenType::JWT,
223            alg: Algorithm::EdDSA,
224            cty: None,
225            jku: None,
226            kid: None,
227            x5u: None,
228            x5c: None,
229            x5t: None,
230            x5t_s256: None,
231        }
232    }
233}
234
235/// Registered claim names from https://www.rfc-editor.org/rfc/rfc7519#section-4.1
236#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
237pub struct RegisteredClaims {
238    /// Issuer
239    /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.1
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub iss: Option<SmallString<20>>,
242
243    /// Subject
244    /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.2
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub sub: Option<SmallString<36>>, // 36 = UUID length
247
248    /// Audience
249    /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3
250    #[serde(skip_serializing_if = "Option::is_none")]
251    pub aud: Option<SmallString<20>>,
252
253    /// Expiration Time
254    /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4
255    #[serde(skip_serializing_if = "Option::is_none")]
256    pub exp: Option<u64>,
257
258    /// Not Before
259    /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5
260    #[serde(skip_serializing_if = "Option::is_none")]
261    pub nbf: Option<u64>,
262
263    /// Issued At
264    /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6
265    #[serde(skip_serializing_if = "Option::is_none")]
266    pub iat: Option<u64>,
267
268    /// JWT ID
269    /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7
270    #[serde(skip_serializing_if = "Option::is_none")]
271    pub jti: Option<SmallString<36>>,
272}
273
274#[derive(Debug, Default, PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
275pub enum TokenType {
276    #[default]
277    JWT,
278}
279
280/// The algorithms supported for signing / verifying JWTs
281#[derive(Copy, Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
282pub enum Algorithm {
283    /// HMAC using SHA-256
284    HS256,
285
286    /// HMAC using SHA-384
287    HS384,
288
289    /// HMAC using SHA-512
290    HS512,
291
292    /// BLAKE3 in keyed mode
293    BLAKE3,
294
295    /// Edwards-curve Digital Signature Algorithm (EdDSA)
296    EdDSA,
297
298    /// ECDSA using P-256 and SHA-256
299    ES256,
300
301    /// ECDSA using P-384 and SHA-384
302    ES384,
303
304    /// ECDSA using P-521 and SHA-512
305    ES512,
306
307    /// ML-DSA-44
308    #[serde(rename = "ML-DSA-44")]
309    MlDsa44,
310
311    /// ML-DSA-65
312    #[serde(rename = "ML-DSA-65")]
313    MlDsa65,
314
315    /// ML-DSA-87
316    #[serde(rename = "ML-DSA-87")]
317    MlDsa87,
318
319    /// RSASSA-PKCS1-v1.5 with SHA-256
320    RS256,
321
322    /// RSASSA-PKCS1-v1.5 with SHA-384
323    RS384,
324
325    /// RSASSA-PKCS1-v1.5 with SHA-512
326    RS512,
327
328    /// RSASSA-PSS with SHA-256
329    PS256,
330
331    /// RSASSA-PSS with SHA-384
332    PS384,
333
334    /// RSASSA-PSS with SHA-512
335    PS512,
336}
337
338impl Algorithm {
339    /// Returns the size of the signature of the algorithm, or, if the size can vary in size,
340    /// the upper bound supported by this package (e.g. 8192 bits / 1024 bytes for RSA).
341    /// This is used, among other things, to pre-allocate the output buffer to the correct size
342    /// when encoding a JWT.
343    #[inline]
344    pub(crate) fn signature_max_size(&self) -> usize {
345        match self {
346            Algorithm::BLAKE3 => 32,
347            Algorithm::HS256 => 32,
348            Algorithm::HS384 => 48,
349            Algorithm::HS512 => 64,
350            Algorithm::EdDSA => 64,
351            Algorithm::ES256 => 64,
352            Algorithm::ES384 => 96,
353            Algorithm::ES512 => 132,
354            Algorithm::RS256 => 1024,
355            Algorithm::RS384 => 1024,
356            Algorithm::RS512 => 1024,
357            Algorithm::PS256 => 1024,
358            Algorithm::PS384 => 1024,
359            Algorithm::PS512 => 1024,
360            Algorithm::MlDsa44 => 2420,
361            Algorithm::MlDsa65 => 3309,
362            Algorithm::MlDsa87 => 4627,
363        }
364    }
365}
366
367impl core::str::FromStr for Algorithm {
368    type Err = Error;
369
370    fn from_str(s: &str) -> Result<Self, Self::Err> {
371        match s {
372            "BLAKE3" => Ok(Algorithm::BLAKE3),
373            "HS256" => Ok(Algorithm::HS256),
374            "HS384" => Ok(Algorithm::HS384),
375            "HS512" => Ok(Algorithm::HS512),
376            "ES256" => Ok(Algorithm::ES256),
377            "ES384" => Ok(Algorithm::ES384),
378            "ES512" => Ok(Algorithm::ES512),
379            "EdDSA" => Ok(Algorithm::EdDSA),
380            "ML-DSA-44" => Ok(Algorithm::MlDsa44),
381            "ML-DSA-65" => Ok(Algorithm::MlDsa65),
382            "ML-DSA-87" => Ok(Algorithm::MlDsa87),
383            "RS256" => Ok(Algorithm::RS256),
384            "RS384" => Ok(Algorithm::RS384),
385            "RS512" => Ok(Algorithm::RS512),
386            "PS256" => Ok(Algorithm::PS256),
387            "PS384" => Ok(Algorithm::PS384),
388            "PS512" => Ok(Algorithm::PS512),
389            _ => Err(Error::UnknownAlgorithm(s.to_string())),
390        }
391    }
392}
393
394impl core::fmt::Display for Algorithm {
395    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
396        let name = match self {
397            Algorithm::BLAKE3 => "BLAKE3",
398            Algorithm::HS256 => "HS256",
399            Algorithm::HS384 => "HS384",
400            Algorithm::HS512 => "HS512",
401            Algorithm::EdDSA => "EdDSA",
402            Algorithm::ES256 => "ES256",
403            Algorithm::ES384 => "ES384",
404            Algorithm::ES512 => "ES512",
405            Algorithm::MlDsa44 => "ML-DSA-44",
406            Algorithm::MlDsa65 => "ML-DSA-65",
407            Algorithm::MlDsa87 => "ML-DSA-87",
408            Algorithm::RS256 => "RS256",
409            Algorithm::RS384 => "RS384",
410            Algorithm::RS512 => "RS512",
411            Algorithm::PS256 => "PS256",
412            Algorithm::PS384 => "PS384",
413            Algorithm::PS512 => "PS512",
414        };
415
416        f.write_str(name)
417    }
418}
419
420#[derive(Debug)]
421pub enum Error {
422    UnknownAlgorithm(String),
423    InvalidCurve,
424    InvalidTokenType(String),
425    Json(serde_json::Error),
426    InvalidToken,
427    InvalidSignature,
428    InvalidKey,
429    InvalidEllipticCurve(String),
430    InvalidJwk { kid: String, err: String },
431    Unspecified(String),
432    ClockIsMissing,
433}
434
435impl core::fmt::Display for Error {
436    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
437        match self {
438            Error::UnknownAlgorithm(algorithm) => write!(f, "unknown algorithm: {algorithm}"),
439            Error::InvalidCurve => f.write_str("invalid curve"),
440            Error::InvalidTokenType(token_type) => write!(f, "invalid token type: {token_type}"),
441            Error::Json(err) => write!(f, "error serializing JWT to JSON: {err}"),
442            Error::InvalidToken => f.write_str("JWT is not valid"),
443            Error::InvalidSignature => f.write_str("signature is not valid"),
444            Error::InvalidKey => f.write_str("key is not valid"),
445            Error::InvalidEllipticCurve(curve) => write!(f, "invalid elliptic curve: {curve}"),
446            Error::InvalidJwk {
447                kid,
448                err,
449            } => write!(f, "{kid} is not a valid JWK: {err}"),
450            Error::Unspecified(err) => f.write_str(&err),
451            Error::ClockIsMissing => f.write_str("a clock is needed for exp or nbf verification"),
452        }
453    }
454}
455
456impl From<serde_json::Error> for Error {
457    fn from(err: serde_json::Error) -> Self {
458        Self::Json(err)
459    }
460}
461
462#[cfg(feature = "std")]
463impl std::error::Error for Error {}
464
465/// A wall clock used to check tokens expiration.
466///
467/// Returns the current Unix timestamp (seconds since epoch). This trait
468/// exists so that no_std environments can inject their own time source
469/// (hardware RTC, NTP, etc.) instead of relying on `std::time::SystemTime`.
470pub trait Clock: Send + Sync {
471    fn now(&self) -> u64;
472}
473
474/// A [`Clock`] backed by `std::time::SystemTime`.
475///
476/// Available only when the `std` feature is enabled.
477#[cfg(feature = "std")]
478pub struct SystemClock;
479
480#[cfg(feature = "std")]
481impl Clock for SystemClock {
482    #[inline]
483    fn now(&self) -> u64 {
484        std::time::SystemTime::now()
485            .duration_since(std::time::UNIX_EPOCH)
486            .unwrap_or_default()
487            .as_secs()
488    }
489}
490
491pub struct VerifyOptions<'a> {
492    /// Allowed time drift for `nbf` and `exp` verification in order to account for devices with
493    /// inacurate clocks.
494    /// default: 30 seconds
495    pub allowed_time_drift: Duration,
496    /// default: true
497    pub nbf: bool,
498    /// default: true
499    pub exp: bool,
500    /// default: None
501    pub aud: Option<&'a [&'a str]>,
502    /// default: None
503    pub iss: Option<&'a [&'a str]>,
504    /// default: Some(&SYSTEM_CLOCK)
505    pub clock: Option<&'a dyn Clock>,
506}
507
508#[cfg(feature = "std")]
509impl Default for VerifyOptions<'_> {
510    fn default() -> Self {
511        Self {
512            allowed_time_drift: core::time::Duration::from_secs(30),
513            nbf: true,
514            exp: true,
515            aud: None,
516            iss: None,
517            clock: Some(&SYSTEM_CLOCK),
518        }
519    }
520}
521
522pub fn sign<C: Serialize>(key: &dyn Signer, header: &Header, claims: &C) -> Result<String, Error> {
523    let signing_algorithm = key.algorithm();
524    if signing_algorithm != header.alg {
525        return Err(Error::InvalidKey);
526    }
527
528    let header_base64 = base64::encode(serde_json::to_string(header)?.as_bytes(), base64::Alphabet::UrlNoPadding);
529    let claims_base64 = base64::encode(serde_json::to_string(claims)?.as_bytes(), base64::Alphabet::UrlNoPadding);
530
531    let mut jwt = String::with_capacity(
532        header_base64.len()
533            + claims_base64.len()
534            + base64::encoded_length(signing_algorithm.signature_max_size(), false)
535                .expect("error getting base64 encoding length")
536            + 2,
537    );
538    jwt.push_str(&header_base64);
539    jwt.push('.');
540    jwt.push_str(&claims_base64);
541
542    let signature = key.sign(jwt.as_bytes())?;
543    jwt.push('.');
544    jwt.push_str(&base64::encode(signature.as_ref(), base64::Alphabet::UrlNoPadding));
545
546    return Ok(jwt);
547}
548
549pub fn parse_header(token: &str) -> Result<Header, Error> {
550    let mut parts = token.split('.');
551    let header_base64 = parts.next().ok_or(Error::InvalidToken)?;
552    if parts.count() != 2 {
553        return Err(Error::InvalidToken);
554    }
555
556    let header_json = base64::decode(header_base64, base64::Alphabet::UrlNoPadding).map_err(|_| Error::InvalidToken)?;
557    let header: Header = serde_json::from_slice(&header_json).map_err(|_| Error::InvalidToken)?;
558
559    return Ok(header);
560}
561
562pub fn parse_and_verify<C: DeserializeOwned>(
563    key: &dyn Verifier,
564    header: &Header,
565    token: &str,
566    verify_options: &VerifyOptions,
567) -> Result<C, Error> {
568    if (verify_options.exp || verify_options.nbf) && verify_options.clock.is_none() {
569        return Err(Error::ClockIsMissing);
570    }
571
572    if header.alg != key.algorithm() {
573        return Err(Error::InvalidToken);
574    }
575
576    let mut parts = token.split('.');
577    let header_base64 = parts.next().ok_or(Error::InvalidToken)?;
578    let claims_base64 = parts.next().ok_or(Error::InvalidToken)?;
579    let signature_base64 = parts.next().ok_or(Error::InvalidToken)?;
580    if parts.next().is_some() {
581        return Err(Error::InvalidToken);
582    }
583
584    let mut signature_buffer = [0u8; SIGNATURE_MAX_SIZE];
585    let signature_size = base64::decode_into(
586        &mut signature_buffer,
587        signature_base64.as_bytes(),
588        base64::Alphabet::UrlNoPadding,
589    )
590    .map_err(|_| Error::InvalidSignature)?;
591
592    let signed_message = &token[..header_base64.len() + 1 + claims_base64.len()].as_bytes();
593    key.verify(signed_message, &signature_buffer[..signature_size])
594        .map_err(|_| Error::InvalidSignature)?;
595
596    let claims_json =
597        base64::decode(&claims_base64, base64::Alphabet::UrlNoPadding).map_err(|_| Error::InvalidToken)?;
598
599    let claims =
600        if verify_options.exp || verify_options.nbf || verify_options.aud.is_some() || verify_options.iss.is_some() {
601            let claims_json_value: serde_json::Value =
602                serde_json::from_slice(&claims_json).map_err(|_| Error::InvalidToken)?;
603
604            match &claims_json_value {
605                serde_json::Value::Object(claims_object) => {
606                    if verify_options.exp {
607                        match claims_object.get("exp") {
608                            None => return Err(Error::InvalidToken),
609                            Some(exp_value) => {
610                                if let Some(exp) = exp_value.as_u64() {
611                                    let now = verify_options.clock.unwrap().now();
612                                    if exp < (now - verify_options.allowed_time_drift.as_secs()) {
613                                        return Err(Error::InvalidToken);
614                                    }
615                                } else {
616                                    return Err(Error::InvalidToken);
617                                }
618                            }
619                        }
620                    }
621
622                    if verify_options.nbf {
623                        match claims_object.get("nbf") {
624                            None => return Err(Error::InvalidToken),
625                            Some(nbf_value) => {
626                                if let Some(nbf) = nbf_value.as_u64() {
627                                    let now = verify_options.clock.unwrap().now();
628                                    if nbf > (now + verify_options.allowed_time_drift.as_secs()) {
629                                        return Err(Error::InvalidToken);
630                                    }
631                                } else {
632                                    return Err(Error::InvalidToken);
633                                }
634                            }
635                        }
636                    }
637
638                    if let Some(expected_aud) = verify_options.aud {
639                        match claims_object.get("aud") {
640                            None => return Err(Error::InvalidToken),
641                            Some(aud_value) => {
642                                if let Some(aud) = aud_value.as_str() {
643                                    if !expected_aud.contains(&aud) {
644                                        return Err(Error::InvalidToken);
645                                    }
646                                } else {
647                                    return Err(Error::InvalidToken);
648                                }
649                            }
650                        }
651                    }
652
653                    if let Some(expected_iss) = verify_options.iss {
654                        match claims_object.get("iss") {
655                            None => return Err(Error::InvalidToken),
656                            Some(iss_value) => {
657                                if let Some(iss) = iss_value.as_str() {
658                                    if !expected_iss.contains(&iss) {
659                                        return Err(Error::InvalidToken);
660                                    }
661                                } else {
662                                    return Err(Error::InvalidToken);
663                                }
664                            }
665                        }
666                    }
667                }
668                _ => return Err(Error::InvalidToken),
669            };
670
671            serde_json::from_value(claims_json_value).map_err(|_| Error::InvalidToken)?
672        } else {
673            serde_json::from_slice(&claims_json).map_err(|_| Error::InvalidToken)?
674        };
675
676    return Ok(claims);
677}