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//! `jwt` still requires `alloc`. ML-DSA signing additionally requires a random
15//! number generator: enable the `random` feature (implied by `std`), or provide
16//! a `getrandom` backend. Without `random`, the ML-DSA secret-key variants of
17//! [`Key`] and the ML-DSA [`Signer`] implementations are not compiled.
18//!
19//! # Example
20//!
21//! ```
22//! # #[cfg(feature = "std")] {
23//! use jwt::*;
24//! use crypto::curve25519::ed25519;
25//!
26//! // 1. Generate an Ed25519 secret key.
27//! let secret_key = ed25519::SecretKey::generate().map_err(|_| Error::InvalidKey)?;
28//!
29//! // 2. Build the header.
30//! let header = Header {
31//! typ: TokenType::JWT,
32//! alg: Algorithm::EdDSA,
33//! kid: Some("my-key-id".into()),
34//! cty: None,
35//! jku: None,
36//! x5u: None,
37//! x5c: None,
38//! x5t: None,
39//! x5t_s256: None,
40//! };
41//!
42//! // 3. Define the claims and sign.
43//! let claims = serde_json::json!({ "sub": "user123", "exp": 9999999999_u64 });
44//! let token = sign(&secret_key, &header, &claims)?;
45//!
46//! // 4. Extract the public key for verification.
47//! let public_key = secret_key.public_key();
48//!
49//! // 5. Parse only the header first (e.g., to read `kid` for key lookup).
50//! let parsed_header = parse_header(&token)?;
51//! assert_eq!(parsed_header.kid.as_deref(), Some("my-key-id"));
52//!
53//! // 6. Now verify and deserialize the claims.
54//! let opts = VerifyOptions {
55//! allowed_time_drift: core::time::Duration::from_secs(60),
56//! exp: true,
57//! nbf: false,
58//! aud: None,
59//! iss: None,
60//! clock: Some(&jwt::SYSTEM_CLOCK),
61//! };
62//! let claims: serde_json::Value =
63//! parse_and_verify(&public_key, &parsed_header, &token, &opts)?;
64//! assert_eq!(claims["sub"], "user123");
65//! # }
66//! # Ok::<(), jwt::Error>(())
67//! ```
68//!
69//! # JSON Web Key (JWK) import and export
70//!
71//! Keys can be exported to and imported from JSON Web Keys (JWK) for publishing or later re-use.
72//! Every supported key type implements `From<&KeyType> for Jwk`, and the reverse conversion is
73//! available through `TryFrom<&Jwk>`. Use it when the key is only known at runtime, for example
74//! after fetching a JWKS document. P-256, P-384 and P-521 public keys are all supported.
75//!
76//! ```
77//! # #[cfg(feature = "std")] {
78//! use jwt::*;
79//! use crypto::p256;
80//!
81//! // Generate a P-256 key pair.
82//! let secret_key = p256::SecretKey::generate().map_err(|_| Error::InvalidKey)?;
83//! let public_key = secret_key.public_key();
84//!
85//! // Convert to a JWK (e.g. for publishing in a JWKS endpoint).
86//! let jwk = Jwk::from(&public_key);
87//! assert_eq!(jwk.algorithm, Algorithm::ES256);
88//!
89//! // Parse the JWK back into a key (e.g. from a JWKS response).
90//! let key = p256::PublicKey::try_from(&jwk)?;
91//!
92//! let header = Header { typ: TokenType::JWT, alg: Algorithm::ES256, ..Default::default() };
93//! let token = sign(&secret_key, &header, &serde_json::json!({"exp": 9999999999_u64, "nbf": 0_u64 }))?;
94//! let parsed_header = parse_header(&token)?;
95//! let _claims: serde_json::Value = parse_and_verify(&key, &parsed_header, &token, &VerifyOptions::default())?;
96//! # }
97//! # Ok::<(), jwt::Error>(())
98//! ```
99//!
100//! When the key type is not known ahead of time (for example a JWKS document that may contain
101//! several kinds of keys), use the [`Key`] enum. It inspects the JWK's `kty` and `crv` and selects the
102//! matching concrete key, preferring the secret variant when both halves are present. [`Key`]
103//! implements both [`Signer`] and [`Verifier`], so it can be passed straight to [`sign`] or
104//! [`parse_and_verify`]:
105//!
106//! ```
107//! # #[cfg(feature = "std")] {
108//! use jwt::*;
109//! use crypto::curve25519::ed25519;
110//!
111//! let secret_key = ed25519::SecretKey::generate().map_err(|_| Error::InvalidKey)?;
112//!
113//! // A JWKS entry whose key type is only known at runtime.
114//! let jwk = Jwk::from(&secret_key.public_key());
115//! let key = Key::try_from(&jwk)?;
116//! assert!(matches!(key, Key::Ed25519Public(_)));
117//!
118//! let header = Header { typ: TokenType::JWT, alg: Algorithm::EdDSA, ..Default::default() };
119//! let token = sign(&secret_key, &header, &serde_json::json!({"exp": 9999999999_u64, "nbf": 0_u64 }))?;
120//! let parsed_header = parse_header(&token)?;
121//! let _claims: serde_json::Value = parse_and_verify(&key, &parsed_header, &token, &VerifyOptions::default())?;
122//! # }
123//! # Ok::<(), jwt::Error>(())
124//! ```
125//!
126//! When a JWK derived from a secret key is decoded, the secret variant is preferred, so the same
127//! [`Key`] can be used for signing:
128//!
129//! ```
130//! # #[cfg(feature = "std")] {
131//! use jwt::*;
132//! use crypto::curve25519::ed25519;
133//!
134//! let secret_key = ed25519::SecretKey::generate().map_err(|_| Error::InvalidKey)?;
135//! let jwk = Jwk::from(&secret_key);
136//! let key = Key::try_from(&jwk)?;
137//! assert!(matches!(key, Key::Ed25519Secret(_)));
138//!
139//! let header = Header { typ: TokenType::JWT, alg: Algorithm::EdDSA, ..Default::default() };
140//! let token = sign(&key, &header, &serde_json::json!({"exp": 9999999999_u64, "nbf": 0_u64 }))?;
141//! let parsed_header = parse_header(&token)?;
142//! let _claims: serde_json::Value = parse_and_verify(&key, &parsed_header, &token, &VerifyOptions::default())?;
143//! # }
144//! # Ok::<(), jwt::Error>(())
145//! ```
146
147#![cfg_attr(not(feature = "std"), no_std)]
148
149extern crate alloc;
150
151use alloc::{
152 string::{String, ToString},
153 vec::Vec,
154};
155use core::time::Duration;
156
157use serde::{Deserialize, Serialize, de::DeserializeOwned};
158use small_collections::SmallString;
159
160mod jwk;
161mod jwt_crypto;
162
163pub use jwk::*;
164pub use jwt_crypto::*;
165
166#[cfg(feature = "std")]
167pub static SYSTEM_CLOCK: SystemClock = SystemClock;
168
169#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
170pub struct Header {
171 /// The only valid value is "JWT"
172 /// https://tools.ietf.org/html/rfc7519#section-5.1
173 pub typ: TokenType,
174
175 /// ttps://tools.ietf.org/html/rfc7515#section-4.1.1
176 pub alg: Algorithm,
177
178 /// Content type
179 /// https://tools.ietf.org/html/rfc7519#section-5.2
180 #[serde(skip_serializing_if = "Option::is_none")]
181 pub cty: Option<SmallString<3>>,
182
183 /// JSON Key URL
184 /// https://tools.ietf.org/html/rfc7515#section-4.1.2
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub jku: Option<String>,
187
188 /// JSON Web Key
189 /// https://tools.ietf.org/html/rfc7515#section-4.1.3
190 // #[serde(skip_serializing_if = "Option::is_none")]
191 // pub jwk: Option<Jwk>,
192
193 /// Key ID
194 /// https://tools.ietf.org/html/rfc7515#section-4.1.4
195 #[serde(skip_serializing_if = "Option::is_none")]
196 pub kid: Option<SmallString<36>>, // 36 = UUID length
197
198 /// X.509 URL
199 /// https://tools.ietf.org/html/rfc7515#section-4.1.5
200 #[serde(skip_serializing_if = "Option::is_none")]
201 pub x5u: Option<String>,
202
203 /// X.509 certificate chain.
204 /// https://tools.ietf.org/html/rfc7515#section-4.1.6
205 #[serde(skip_serializing_if = "Option::is_none")]
206 pub x5c: Option<Vec<String>>,
207
208 /// X.509 SHA1 certificate Thumbprint
209 /// https://tools.ietf.org/html/rfc7515#section-4.1.7
210 #[serde(skip_serializing_if = "Option::is_none")]
211 pub x5t: Option<SmallString<27>>, // 27 = base64_encoded_length(20)
212
213 /// X.509 SHA256 certificate Thumbprint
214 /// https://tools.ietf.org/html/rfc7515#section-4.1.8
215 #[serde(skip_serializing_if = "Option::is_none")]
216 #[serde(rename = "x5t#S256")]
217 pub x5t_s256: Option<SmallString<43>>, // 43 = base64_encoded_length(32)
218}
219
220impl Default for Header {
221 fn default() -> Self {
222 Self {
223 typ: TokenType::JWT,
224 alg: Algorithm::EdDSA,
225 cty: None,
226 jku: None,
227 kid: None,
228 x5u: None,
229 x5c: None,
230 x5t: None,
231 x5t_s256: None,
232 }
233 }
234}
235
236/// Registered claim names from https://www.rfc-editor.org/rfc/rfc7519#section-4.1
237#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
238pub struct RegisteredClaims {
239 /// Issuer
240 /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.1
241 #[serde(skip_serializing_if = "Option::is_none")]
242 pub iss: Option<SmallString<20>>,
243
244 /// Subject
245 /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.2
246 #[serde(skip_serializing_if = "Option::is_none")]
247 pub sub: Option<SmallString<36>>, // 36 = UUID length
248
249 /// Audience
250 /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub aud: Option<SmallString<20>>,
253
254 /// Expiration Time
255 /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4
256 #[serde(skip_serializing_if = "Option::is_none")]
257 pub exp: Option<u64>,
258
259 /// Not Before
260 /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5
261 #[serde(skip_serializing_if = "Option::is_none")]
262 pub nbf: Option<u64>,
263
264 /// Issued At
265 /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6
266 #[serde(skip_serializing_if = "Option::is_none")]
267 pub iat: Option<u64>,
268
269 /// JWT ID
270 /// https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7
271 #[serde(skip_serializing_if = "Option::is_none")]
272 pub jti: Option<SmallString<36>>,
273}
274
275#[derive(Debug, Default, PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
276pub enum TokenType {
277 #[default]
278 JWT,
279}
280
281/// The algorithms supported for signing / verifying JWTs
282#[derive(Copy, Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
283pub enum Algorithm {
284 /// HMAC using SHA-256
285 HS256,
286
287 /// HMAC using SHA-384
288 HS384,
289
290 /// HMAC using SHA-512
291 HS512,
292
293 /// BLAKE3 in keyed mode
294 BLAKE3,
295
296 /// Edwards-curve Digital Signature Algorithm (EdDSA)
297 EdDSA,
298
299 /// ECDSA using P-256 and SHA-256
300 ES256,
301
302 /// ECDSA using P-384 and SHA-384
303 ES384,
304
305 /// ECDSA using P-521 and SHA-512
306 ES512,
307
308 /// ML-DSA-44
309 #[serde(rename = "ML-DSA-44")]
310 MlDsa44,
311
312 /// ML-DSA-65
313 #[serde(rename = "ML-DSA-65")]
314 MlDsa65,
315
316 /// ML-DSA-87
317 #[serde(rename = "ML-DSA-87")]
318 MlDsa87,
319
320 /// RSASSA-PKCS1-v1.5 with SHA-256
321 RS256,
322
323 /// RSASSA-PKCS1-v1.5 with SHA-384
324 RS384,
325
326 /// RSASSA-PKCS1-v1.5 with SHA-512
327 RS512,
328
329 /// RSASSA-PSS with SHA-256
330 PS256,
331
332 /// RSASSA-PSS with SHA-384
333 PS384,
334
335 /// RSASSA-PSS with SHA-512
336 PS512,
337}
338
339impl Algorithm {
340 /// Returns the size of the signature of the algorithm, or, if the size can vary in size,
341 /// the upper bound supported by this package (e.g. 8192 bits / 1024 bytes for RSA).
342 /// This is used, among other things, to pre-allocate the output buffer to the correct size
343 /// when encoding a JWT.
344 #[inline]
345 pub(crate) fn signature_max_size(&self) -> usize {
346 match self {
347 Algorithm::BLAKE3 => 32,
348 Algorithm::HS256 => 32,
349 Algorithm::HS384 => 48,
350 Algorithm::HS512 => 64,
351 Algorithm::EdDSA => 64,
352 Algorithm::ES256 => 64,
353 Algorithm::ES384 => 96,
354 Algorithm::ES512 => 132,
355 Algorithm::RS256 => 1024,
356 Algorithm::RS384 => 1024,
357 Algorithm::RS512 => 1024,
358 Algorithm::PS256 => 1024,
359 Algorithm::PS384 => 1024,
360 Algorithm::PS512 => 1024,
361 Algorithm::MlDsa44 => 2420,
362 Algorithm::MlDsa65 => 3309,
363 Algorithm::MlDsa87 => 4627,
364 }
365 }
366}
367
368impl core::str::FromStr for Algorithm {
369 type Err = Error;
370
371 fn from_str(s: &str) -> Result<Self, Self::Err> {
372 match s {
373 "BLAKE3" => Ok(Algorithm::BLAKE3),
374 "HS256" => Ok(Algorithm::HS256),
375 "HS384" => Ok(Algorithm::HS384),
376 "HS512" => Ok(Algorithm::HS512),
377 "ES256" => Ok(Algorithm::ES256),
378 "ES384" => Ok(Algorithm::ES384),
379 "ES512" => Ok(Algorithm::ES512),
380 "EdDSA" => Ok(Algorithm::EdDSA),
381 "ML-DSA-44" => Ok(Algorithm::MlDsa44),
382 "ML-DSA-65" => Ok(Algorithm::MlDsa65),
383 "ML-DSA-87" => Ok(Algorithm::MlDsa87),
384 "RS256" => Ok(Algorithm::RS256),
385 "RS384" => Ok(Algorithm::RS384),
386 "RS512" => Ok(Algorithm::RS512),
387 "PS256" => Ok(Algorithm::PS256),
388 "PS384" => Ok(Algorithm::PS384),
389 "PS512" => Ok(Algorithm::PS512),
390 _ => Err(Error::UnknownAlgorithm(s.to_string())),
391 }
392 }
393}
394
395impl core::fmt::Display for Algorithm {
396 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
397 let name = match self {
398 Algorithm::BLAKE3 => "BLAKE3",
399 Algorithm::HS256 => "HS256",
400 Algorithm::HS384 => "HS384",
401 Algorithm::HS512 => "HS512",
402 Algorithm::EdDSA => "EdDSA",
403 Algorithm::ES256 => "ES256",
404 Algorithm::ES384 => "ES384",
405 Algorithm::ES512 => "ES512",
406 Algorithm::MlDsa44 => "ML-DSA-44",
407 Algorithm::MlDsa65 => "ML-DSA-65",
408 Algorithm::MlDsa87 => "ML-DSA-87",
409 Algorithm::RS256 => "RS256",
410 Algorithm::RS384 => "RS384",
411 Algorithm::RS512 => "RS512",
412 Algorithm::PS256 => "PS256",
413 Algorithm::PS384 => "PS384",
414 Algorithm::PS512 => "PS512",
415 };
416
417 f.write_str(name)
418 }
419}
420
421#[derive(Debug)]
422pub enum Error {
423 UnknownAlgorithm(String),
424 InvalidCurve,
425 InvalidTokenType(String),
426 Json(serde_json::Error),
427 InvalidToken,
428 InvalidSignature,
429 InvalidKey,
430 InvalidEllipticCurve(String),
431 InvalidJwk { kid: String, err: String },
432 Unspecified(String),
433 ClockIsMissing,
434}
435
436impl core::fmt::Display for Error {
437 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
438 match self {
439 Error::UnknownAlgorithm(algorithm) => write!(f, "unknown algorithm: {algorithm}"),
440 Error::InvalidCurve => f.write_str("invalid curve"),
441 Error::InvalidTokenType(token_type) => write!(f, "invalid token type: {token_type}"),
442 Error::Json(err) => write!(f, "error serializing JWT to JSON: {err}"),
443 Error::InvalidToken => f.write_str("JWT is not valid"),
444 Error::InvalidSignature => f.write_str("signature is not valid"),
445 Error::InvalidKey => f.write_str("key is not valid"),
446 Error::InvalidEllipticCurve(curve) => write!(f, "invalid elliptic curve: {curve}"),
447 Error::InvalidJwk {
448 kid,
449 err,
450 } => write!(f, "{kid} is not a valid JWK: {err}"),
451 Error::Unspecified(err) => f.write_str(err),
452 Error::ClockIsMissing => f.write_str("a clock is needed for exp or nbf verification"),
453 }
454 }
455}
456
457impl From<serde_json::Error> for Error {
458 fn from(err: serde_json::Error) -> Self {
459 Self::Json(err)
460 }
461}
462
463impl core::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 = base64::decode(claims_base64, base64::Alphabet::UrlNoPadding).map_err(|_| Error::InvalidToken)?;
597
598 let claims =
599 if verify_options.exp || verify_options.nbf || verify_options.aud.is_some() || verify_options.iss.is_some() {
600 let claims_json_value: serde_json::Value =
601 serde_json::from_slice(&claims_json).map_err(|_| Error::InvalidToken)?;
602
603 match &claims_json_value {
604 serde_json::Value::Object(claims_object) => {
605 if verify_options.exp {
606 match claims_object.get("exp") {
607 None => return Err(Error::InvalidToken),
608 Some(exp_value) => {
609 if let Some(exp) = exp_value.as_u64() {
610 let now = verify_options.clock.unwrap().now();
611 if exp < (now - verify_options.allowed_time_drift.as_secs()) {
612 return Err(Error::InvalidToken);
613 }
614 } else {
615 return Err(Error::InvalidToken);
616 }
617 }
618 }
619 }
620
621 if verify_options.nbf {
622 match claims_object.get("nbf") {
623 None => return Err(Error::InvalidToken),
624 Some(nbf_value) => {
625 if let Some(nbf) = nbf_value.as_u64() {
626 let now = verify_options.clock.unwrap().now();
627 if nbf > (now + verify_options.allowed_time_drift.as_secs()) {
628 return Err(Error::InvalidToken);
629 }
630 } else {
631 return Err(Error::InvalidToken);
632 }
633 }
634 }
635 }
636
637 if let Some(expected_aud) = verify_options.aud {
638 match claims_object.get("aud") {
639 None => return Err(Error::InvalidToken),
640 Some(aud_value) => {
641 if let Some(aud) = aud_value.as_str() {
642 if !expected_aud.contains(&aud) {
643 return Err(Error::InvalidToken);
644 }
645 } else {
646 return Err(Error::InvalidToken);
647 }
648 }
649 }
650 }
651
652 if let Some(expected_iss) = verify_options.iss {
653 match claims_object.get("iss") {
654 None => return Err(Error::InvalidToken),
655 Some(iss_value) => {
656 if let Some(iss) = iss_value.as_str() {
657 if !expected_iss.contains(&iss) {
658 return Err(Error::InvalidToken);
659 }
660 } else {
661 return Err(Error::InvalidToken);
662 }
663 }
664 }
665 }
666 }
667 _ => return Err(Error::InvalidToken),
668 };
669
670 serde_json::from_value(claims_json_value).map_err(|_| Error::InvalidToken)?
671 } else {
672 serde_json::from_slice(&claims_json).map_err(|_| Error::InvalidToken)?
673 };
674
675 return Ok(claims);
676}