common_access_token/
lib.rs

1//! # Common Access Token (CAT)
2//!
3//! A Rust implementation of the Common Access Token specification, which is based on CBOR Object Signing and Encryption (COSE).
4//!
5//! ## Overview
6//!
7//! Common Access Tokens are compact, secure tokens designed for efficient transmission in resource-constrained environments.
8//! They use CBOR encoding for smaller token sizes compared to JSON-based tokens like JWT.
9//!
10//! ## Features
11//!
12//! - CBOR-encoded tokens for compact representation
13//! - Support for both COSE_Sign1 and COSE_Mac0 structures
14//! - HMAC-SHA256 authentication
15//! - Protected and unprotected headers
16//! - Standard registered claims (issuer, subject, audience, expiration, etc.)
17//! - Custom claims with string, binary, integer, and nested map values
18//! - CAT-specific claims for URI validation (CATU), HTTP method restrictions (CATM),
19//!   replay protection (CATREPLAY), and token renewal (CATR)
20//! - Comprehensive token verification including CAT-specific claim validation
21//!
22//! ## Basic Example
23//!
24//! ```rust
25//! use common_access_token::{Algorithm, KeyId, RegisteredClaims, TokenBuilder, VerificationOptions};
26//! use common_access_token::current_timestamp;
27//!
28//! // Create a key for signing and verification
29//! let key = b"my-secret-key-for-hmac-sha256";
30//! let now = current_timestamp();
31//!
32//! // Create a token
33//! let token = TokenBuilder::new()
34//!     .algorithm(Algorithm::HmacSha256)
35//!     .protected_key_id(KeyId::string("example-key-id"))
36//!     .registered_claims(
37//!         RegisteredClaims::new()
38//!             .with_issuer("example-issuer")
39//!             .with_subject("example-subject")
40//!             .with_audience("example-audience")
41//!             .with_expiration(now + 3600) // 1 hour from now
42//!     )
43//!     .custom_string(100, "custom-value")
44//!     .sign(key)
45//!     .expect("Failed to sign token");
46//!
47//! // Encode token to bytes
48//! let token_bytes = token.to_bytes().expect("Failed to encode token");
49//!
50//! // Decode and verify the token
51//! let decoded_token = common_access_token::Token::from_bytes(&token_bytes)
52//!     .expect("Failed to decode token");
53//!
54//! // Verify the signature
55//! decoded_token.verify(key).expect("Failed to verify signature");
56//!
57//! // Verify the claims
58//! let options = VerificationOptions::new()
59//!     .verify_exp(true)
60//!     .expected_issuer("example-issuer");
61//!
62//! decoded_token.verify_claims(&options).expect("Failed to verify claims");
63//! ```
64//!
65//! ## CAT-Specific Claims Example
66//!
67//! ```rust
68//! use common_access_token::{
69//!     Algorithm, KeyId, RegisteredClaims, TokenBuilder, VerificationOptions,
70//!     cat_keys, catm, catr, catreplay, catu, uri_components, current_timestamp,
71//!     cattprint, FingerprintType
72//! };
73//! use std::collections::BTreeMap;
74//!
75//! // Create a key for signing and verification
76//! let key = b"my-secret-key-for-hmac-sha256";
77//! let now = current_timestamp();
78//!
79//! // Create CATU claim (URI restrictions)
80//! let mut catu_components = BTreeMap::new();
81//! // Restrict to https scheme
82//! catu_components.insert(uri_components::SCHEME, catu::exact_match("https"));
83//! // Restrict to example.com host
84//! catu_components.insert(uri_components::HOST, catu::suffix_match(".example.com"));
85//! // Restrict to paths starting with /api
86//! catu_components.insert(uri_components::PATH, catu::prefix_match("/api"));
87//!
88//! // Create CATM claim (HTTP method restrictions)
89//! let allowed_methods = vec!["GET", "HEAD"];
90//!
91//! // Create a token with CAT-specific claims
92//! let token = TokenBuilder::new()
93//!     .algorithm(Algorithm::HmacSha256)
94//!     .protected_key_id(KeyId::string("example-key-id"))
95//!     .registered_claims(
96//!         RegisteredClaims::new()
97//!             .with_issuer("example-issuer")
98//!             .with_expiration(now + 3600)
99//!     )
100//!     // Add CAT-specific claims
101//!     .custom_cbor(cat_keys::CATU, catu::create(catu_components))
102//!     .custom_array(cat_keys::CATM, catm::create(allowed_methods))
103//!     .custom_cbor(cat_keys::CATREPLAY, catreplay::prohibited())
104//!     .custom_cbor(cat_keys::CATTPRINT, cattprint::create(FingerprintType::JA4, "t13d1516h2_8daaf6152771_b186095e22b6"))
105//!     .sign(key)
106//!     .expect("Failed to sign token");
107//!
108//! // Encode token to bytes
109//! let token_bytes = token.to_bytes().expect("Failed to encode token");
110//!
111//! // Decode and verify the token
112//! let decoded_token = common_access_token::Token::from_bytes(&token_bytes)
113//!     .expect("Failed to decode token");
114//!
115//! // Verify signature
116//! decoded_token.verify(key).expect("Failed to verify signature");
117//!
118//! // Verify standard claims and CAT-specific claims
119//! let options = VerificationOptions::new()
120//!     .verify_exp(true)
121//!     .expected_issuer("example-issuer")
122//!     // Add CAT-specific claim verification
123//!     .verify_catu(true)
124//!     .uri("https://api.example.com/api/users")
125//!     .verify_catm(true)
126//!     .http_method("GET")
127//!     .verify_catreplay(true)
128//!     .token_seen_before(false);
129//!
130//! decoded_token.verify_claims(&options).expect("Failed to verify all claims");
131//! ```
132
133pub mod cat_claims;
134pub mod claims;
135pub mod constants;
136pub mod error;
137pub mod header;
138pub mod token;
139pub mod utils;
140
141pub use cat_claims::{
142    catalpn, catdpop, catgeoalt, catgeocoord, catgeoiso3166, cath, catif, catifdata, catm, catnip,
143    catpor, catr, catreplay, cattpk, catu, catv, cattprint,
144};
145pub use claims::{Claims, RegisteredClaims};
146pub use constants::{
147    cat_keys, cose_algs, cose_labels, cwt_keys, match_types, renewal_params, renewal_types,
148    replay_values, uri_components, tprint_params, FingerprintType
149};
150pub use error::Error;
151pub use header::{Algorithm, CborValue, Header, HeaderMap, KeyId};
152pub use token::{Token, TokenBuilder, VerificationOptions};
153pub use utils::current_timestamp;
154
155/// Re-export minicbor for users of this crate
156pub use minicbor;
157
158#[cfg(test)]
159mod tests;