Skip to main content

compact_jwt/
lib.rs

1#![deny(warnings)]
2#![warn(missing_docs)]
3#![warn(unused_extern_crates)]
4#![forbid(unsafe_code)]
5// Enable some groups of clippy lints.
6#![deny(clippy::suspicious)]
7#![deny(clippy::perf)]
8// Specific lints to enforce.
9#![deny(clippy::todo)]
10#![deny(clippy::unimplemented)]
11#![deny(clippy::unwrap_used)]
12#![deny(clippy::expect_used)]
13#![deny(clippy::panic)]
14#![deny(clippy::await_holding_lock)]
15#![deny(clippy::needless_pass_by_value)]
16#![deny(clippy::trivially_copy_pass_by_ref)]
17#![deny(clippy::disallowed_types)]
18#![deny(clippy::manual_let_else)]
19#![allow(clippy::unreachable)]
20
21//! Json Web Tokens (JWT) are a popular method for creating signed transparent tokens that can be verified
22//! by clients and servers. They are enshrined in standards like OpenID Connect which causes them to
23//! be a widespread and required component of many modern web authentication system.
24//!
25//! This is a minimal implementation of JWTs and Oidc Tokens that aims for auditability and correctness.
26//!
27//! # Examples
28//! ```
29//! # {
30//! use std::str::FromStr;
31//! use std::convert::TryFrom;
32//! use std::time::SystemTime;
33//! use url::Url;
34//! use compact_jwt::{
35//!     OidcToken,
36//!     OidcSubject,
37//!     OidcUnverified,
38//!     JwsEs256Signer,
39//!     // Traits
40//!     JwsSigner,
41//!     JwsSignerToVerifier,
42//!     JwsVerifier,
43//! };
44//!
45//! let oidc = OidcToken {
46//!         iss: Url::parse("https://oidc.example.com").expect("Failed to parse URL"),
47//!         sub: OidcSubject::S("UniqueId".to_string()),
48//! #       aud: "test".to_string(),
49//! #       exp: 0,
50//! #       nbf: Some(0),
51//! #       iat: 0,
52//! #       auth_time: Some(0),
53//! #       nonce: None,
54//! #       at_hash: None,
55//! #       acr: None,
56//! #       amr: None,
57//! #       azp: None,
58//! #       jti: None,
59//! #       s_claims: Default::default(),
60//! #       claims: Default::default(),
61//!     };
62//!
63//! let mut jws_es256_signer =
64//!     JwsEs256Signer::generate_es256().expect("Unable to generate ES256 signer");
65//!
66//! let oidc_signed = jws_es256_signer.sign(&oidc)
67//!     .expect("Unable to sign OIDC token");
68//!
69//! // Get the signed formatted token string
70//! let token_str = oidc_signed.to_string();
71//!
72//! // Build a validator from the public key of the signer. In a client scenario
73//! // you would get this public jwk from the oidc authorisation server.
74//! let mut jwk_es256_verifier = jws_es256_signer
75//!     .get_verifier()
76//!     .expect("failed to get verifier from signer");
77//!
78//! // Assuming we have the token_str, we parse it to an unverified state.
79//! let oidc_unverified = OidcUnverified::from_str(&token_str)
80//!     .expect("Unable to parse OIDC token");
81//!
82//! let curtime = SystemTime::now()
83//!     .duration_since(SystemTime::UNIX_EPOCH)
84//!     .expect("Failed to retrieve current time")
85//!     .as_secs() as i64;
86//!
87//! let oidc_validated = jwk_es256_verifier
88//!     .verify(&oidc_unverified)
89//!     .and_then(|oidc_exp| oidc_exp.verify_exp(curtime))
90//!     .expect("Unable to validate OIDC token");
91//!
92//! // Prove we got back the same content.
93//! assert!(oidc_validated == oidc);
94//! # }
95//! ```
96
97#[allow(unused_imports)]
98#[macro_use]
99extern crate tracing;
100
101pub mod crypto;
102
103#[cfg(feature = "unsafe_release_without_verify")]
104pub mod dangernoverify;
105
106pub mod compact;
107
108pub mod traits;
109
110pub mod error;
111pub mod jwe;
112pub mod jws;
113pub mod jwt;
114pub mod oidc;
115
116pub use crate::compact::{JwaAlg, JweCompact, Jwk, JwkKeySet, JwkUse, JwsCompact};
117pub use crate::crypto::{JwsEs256Signer, JwsEs256Verifier, JwsHs256Signer};
118pub use crate::error::JwtError;
119pub use crate::jws::{Jws, JwsSigned};
120pub use crate::jwt::{Jwt, JwtSigned, JwtUnverified};
121pub use crate::oidc::{OidcClaims, OidcSigned, OidcSubject, OidcToken, OidcUnverified};
122pub use crate::traits::{JwsSigner, JwsSignerToVerifier, JwsVerifier};
123
124// 96 bits is more than enough to uniquely ID a key
125const KID_LEN: usize = 12;
126
127pub(crate) fn btreemap_empty(
128    m: &std::collections::BTreeMap<String, serde_json::value::Value>,
129) -> bool {
130    m.is_empty()
131}
132
133pub(crate) fn vec_empty(m: &[String]) -> bool {
134    m.is_empty()
135}