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;