cat_specific_claims/
cat_specific_claims.rs

1use common_access_token::{
2    cat_keys, catm, catr, catreplay, catu, current_timestamp, uri_components, Algorithm, KeyId,
3    RegisteredClaims, TokenBuilder, VerificationOptions,
4};
5use std::collections::BTreeMap;
6
7fn main() {
8    // Create a key for signing and verification
9    let key = b"my-secret-key-for-hmac-sha256";
10
11    // Create a token with CAT-specific claims
12    let token = create_token_with_cat_claims(key);
13
14    // Encode token to bytes
15    let token_bytes = token.to_bytes().expect("Failed to encode token");
16    println!("Token encoded to {} bytes", token_bytes.len());
17
18    // Decode and verify the token
19    let decoded_token =
20        common_access_token::Token::from_bytes(&token_bytes).expect("Failed to decode token");
21
22    // Verify the signature
23    decoded_token
24        .verify(key)
25        .expect("Failed to verify signature");
26
27    // Verify the claims
28    let options = VerificationOptions::new()
29        .verify_exp(true)
30        .expected_issuer("example-issuer");
31
32    decoded_token
33        .verify_claims(&options)
34        .expect("Failed to verify claims");
35
36    // Print token information
37    print_token_info(&decoded_token);
38}
39
40/// Create a token with CAT-specific claims
41fn create_token_with_cat_claims(key: &[u8]) -> common_access_token::Token {
42    let now = current_timestamp();
43
44    // Create a CATU claim (Common Access Token URI)
45    let mut catu_components = BTreeMap::new();
46
47    // Restrict to https scheme
48    catu_components.insert(uri_components::SCHEME, catu::exact_match("https"));
49
50    // Restrict to example.com host
51    catu_components.insert(uri_components::HOST, catu::suffix_match(".example.com"));
52
53    // Restrict to paths starting with /content
54    catu_components.insert(uri_components::PATH, catu::prefix_match("/content"));
55
56    // Restrict to .m3u8 files
57    catu_components.insert(uri_components::EXTENSION, catu::exact_match(".m3u8"));
58
59    // Create a CATM claim (Common Access Token Methods)
60    let allowed_methods = vec!["GET", "HEAD"];
61
62    // Create a CATR claim (Common Access Token Renewal)
63    let renewal_params = catr::automatic_renewal(3600, Some((now + 3000) as i64));
64
65    // Build the token with CAT-specific claims
66    TokenBuilder::new()
67        .algorithm(Algorithm::HmacSha256)
68        .protected_key_id(KeyId::string("example-key-id"))
69        .registered_claims(
70            RegisteredClaims::new()
71                .with_issuer("example-issuer")
72                .with_subject("example-subject")
73                .with_audience("example-audience")
74                .with_expiration(now + 3600) // 1 hour from now
75                .with_not_before(now)
76                .with_issued_at(now)
77                .with_cti(b"token-id-1234".to_vec()),
78        )
79        // Add CAT-specific claims
80        .custom_cbor(cat_keys::CATU, catu::create(catu_components))
81        .custom_cbor(cat_keys::CATR, catr::create(renewal_params))
82        .custom_cbor(cat_keys::CATREPLAY, catreplay::prohibited())
83        .custom_int(cat_keys::CATV, 1) // Version 1
84        .custom_array(cat_keys::CATM, catm::create(allowed_methods))
85        .sign(key)
86        .expect("Failed to sign token")
87}
88
89/// Print information about a token
90fn print_token_info(token: &common_access_token::Token) {
91    println!("\nToken Information:");
92    println!("------------------");
93
94    // Print registered claims
95    if let Some(iss) = &token.claims.registered.iss {
96        println!("Issuer: {}", iss);
97    }
98    if let Some(sub) = &token.claims.registered.sub {
99        println!("Subject: {}", sub);
100    }
101    if let Some(aud) = &token.claims.registered.aud {
102        println!("Audience: {}", aud);
103    }
104    if let Some(exp) = token.claims.registered.exp {
105        println!("Expires at: {} (unix timestamp)", exp);
106    }
107    if let Some(nbf) = token.claims.registered.nbf {
108        println!("Not valid before: {} (unix timestamp)", nbf);
109    }
110    if let Some(iat) = token.claims.registered.iat {
111        println!("Issued at: {} (unix timestamp)", iat);
112    }
113    if let Some(cti) = &token.claims.registered.cti {
114        println!("CWT ID: {:?}", cti);
115    }
116
117    // Print CAT-specific claims
118    println!("\nCAT-specific claims:");
119
120    // Check for CATU claim
121    if token.claims.custom.contains_key(&cat_keys::CATU) {
122        println!("CATU (URI restrictions): present");
123    }
124
125    // Check for CATM claim
126    if token.claims.custom.contains_key(&cat_keys::CATM) {
127        println!("CATM (HTTP methods): present");
128    }
129
130    // Check for CATR claim
131    if token.claims.custom.contains_key(&cat_keys::CATR) {
132        println!("CATR (Token renewal): present");
133    }
134
135    // Check for CATV claim
136    if token.claims.custom.contains_key(&cat_keys::CATV) {
137        println!("CATV (Version): present");
138    }
139
140    // Check for CATREPLAY claim
141    if token.claims.custom.contains_key(&cat_keys::CATREPLAY) {
142        println!("CATREPLAY (Replay protection): present");
143    }
144}