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//! };
72//! use std::collections::BTreeMap;
73//!
74//! // Create a key for signing and verification
75//! let key = b"my-secret-key-for-hmac-sha256";
76//! let now = current_timestamp();
77//!
78//! // Create CATU claim (URI restrictions)
79//! let mut catu_components = BTreeMap::new();
80//! // Restrict to https scheme
81//! catu_components.insert(uri_components::SCHEME, catu::exact_match("https"));
82//! // Restrict to example.com host
83//! catu_components.insert(uri_components::HOST, catu::suffix_match(".example.com"));
84//! // Restrict to paths starting with /api
85//! catu_components.insert(uri_components::PATH, catu::prefix_match("/api"));
86//!
87//! // Create CATM claim (HTTP method restrictions)
88//! let allowed_methods = vec!["GET", "HEAD"];
89//!
90//! // Create a token with CAT-specific claims
91//! let token = TokenBuilder::new()
92//!     .algorithm(Algorithm::HmacSha256)
93//!     .protected_key_id(KeyId::string("example-key-id"))
94//!     .registered_claims(
95//!         RegisteredClaims::new()
96//!             .with_issuer("example-issuer")
97//!             .with_expiration(now + 3600)
98//!     )
99//!     // Add CAT-specific claims
100//!     .custom_cbor(cat_keys::CATU, catu::create(catu_components))
101//!     .custom_array(cat_keys::CATM, catm::create(allowed_methods))
102//!     .custom_cbor(cat_keys::CATREPLAY, catreplay::prohibited())
103//!     .sign(key)
104//!     .expect("Failed to sign token");
105//!
106//! // Encode token to bytes
107//! let token_bytes = token.to_bytes().expect("Failed to encode token");
108//!
109//! // Decode and verify the token
110//! let decoded_token = common_access_token::Token::from_bytes(&token_bytes)
111//!     .expect("Failed to decode token");
112//!
113//! // Verify signature
114//! decoded_token.verify(key).expect("Failed to verify signature");
115//!
116//! // Verify standard claims and CAT-specific claims
117//! let options = VerificationOptions::new()
118//!     .verify_exp(true)
119//!     .expected_issuer("example-issuer")
120//!     // Add CAT-specific claim verification
121//!     .verify_catu(true)
122//!     .uri("https://api.example.com/api/users")
123//!     .verify_catm(true)
124//!     .http_method("GET")
125//!     .verify_catreplay(true)
126//!     .token_seen_before(false);
127//!
128//! decoded_token.verify_claims(&options).expect("Failed to verify all claims");
129//! ```
130
131pub mod cat_claims;
132pub mod claims;
133pub mod constants;
134pub mod error;
135pub mod header;
136pub mod token;
137pub mod utils;
138
139pub use cat_claims::{catm, catr, catreplay, catu, catv};
140pub use claims::{Claims, RegisteredClaims};
141pub use constants::{
142    cat_keys, cose_algs, cose_labels, cwt_keys, match_types, renewal_params, renewal_types,
143    replay_values, uri_components,
144};
145pub use error::Error;
146pub use header::{Algorithm, CborValue, Header, HeaderMap, KeyId};
147pub use token::{Token, TokenBuilder, VerificationOptions};
148pub use utils::current_timestamp;
149
150/// Re-export minicbor for users of this crate
151pub use minicbor;
152
153#[cfg(test)]
154mod tests;