bh_jws_utils/
lib.rs

1// Copyright (C) 2020-2025  The Blockhouse Technology Limited (TBTL).
2//
3// This program is free software: you can redistribute it and/or modify it
4// under the terms of the GNU Affero General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or (at your
6// option) any later version.
7//
8// This program is distributed in the hope that it will be useful, but
9// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
11// License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16#![deny(missing_docs)]
17#![deny(rustdoc::broken_intra_doc_links)]
18
19//! This crate provides functions and types for working with [JSON Web
20//! Signatures (JWS)][1].
21//!
22//! [1]: https://datatracker.ietf.org/doc/html/rfc7515
23//!
24//! # Details
25//!
26//! The primary way to use this library is via the [`JwtSigner`] and
27//! [`JwtVerifier`] traits, which provide functionality for signing JWTs and
28//! verifying signed JWTs. A default [`openssl`] backed implementation of these
29//! traits is available by using the [`openssl_impl::Es256Signer`] and
30//! [`openssl_impl::Es256Verifier`] structs which implement [`JwtSigner`] and
31//! [`JwtVerifier`] respectively. These implementations are available under the
32//! default feature `openssl` which can be disabled and replaced by a custom
33//! implementation.
34//!
35//! A custom implementation must implement the [`Signer`] trait for signing
36//! JWKs, [`SignatureVerifier`] trait for verifying signatures and optionally
37//! the [`HasJwkKid`] trait if you need to access the JWK key id. The
38//! [`JwtSigner`] and [`JwtVerifier`] traits are implemented automatically for
39//! the custom implementation if the custom implementation implements the
40//! [`Signer`] and [`SignatureVerifier`] traits respectively.
41//!
42//! # Examples
43//!
44//! ## Sign and verify a JWT
45//!
46//! ```
47//! use bh_jws_utils::{json_object, Es256Signer, Es256Verifier, JwtSigner, JwtVerifier};
48//!
49//! // Construct a new signer
50//! let signer = Es256Signer::generate("dummy-kid".to_string()).unwrap();
51//!
52//! // Construct a JWT
53//! let dummy_jwt = json_object!({
54//!    "sub": "1234567890",
55//!    "name": "John Doe",
56//!    "iat": 1516239022
57//! });
58//!
59//! // Sign the JWT
60//! let signed_jwt = signer.sign_jwt(dummy_jwt).unwrap();
61//!
62//! // Get the public JWK for verification
63//! let public_jwk = signer.public_jwk().unwrap();
64//!
65//! // Verify the JWT
66//! let token: serde_json::Value = Es256Verifier
67//!     .verify_jwt_signature(signed_jwt.as_str(), &public_jwk)
68//!     .unwrap();
69//! ```
70
71mod openssl_impl;
72
73mod error;
74mod jwk;
75mod traits;
76mod utils;
77mod x509_chain;
78
79pub use error::*;
80pub use jwk::*;
81// Re-export the `jwt` crate
82pub use jwt;
83pub use openssl_impl::*;
84pub use traits::*;
85pub use utils::*;
86pub use x509_chain::*;
87
88/// Helper macro with the same syntax as [`serde_json::json`] specialized for
89/// constructing JSON objects.
90///
91/// It will construct a more specific type ([`serde_json::Map<String,Value>`])
92/// than just [`serde_json::Value`] when constructing an object, and panic if
93/// the syntax is valid JSON but not an object.
94#[macro_export]
95macro_rules! json_object {
96    ($stuff:tt) => {
97        match ::serde_json::json!($stuff) {
98            ::serde_json::Value::Object(o) => o,
99            _ => unreachable!("JSON literal wasn't an object"),
100        }
101    };
102}