Struct VerificationOptions

Source
pub struct VerificationOptions {
Show 13 fields pub verify_exp: bool, pub require_exp: bool, pub verify_nbf: bool, pub expected_issuer: Option<String>, pub require_iss: bool, pub expected_audience: Option<String>, pub require_aud: bool, pub verify_catu: bool, pub uri: Option<String>, pub verify_catm: bool, pub http_method: Option<String>, pub verify_catreplay: bool, pub token_seen_before: bool,
}
Expand description

Options for token verification

Fields§

§verify_exp: bool

Verify expiration claim

§require_exp: bool

Require expiration claim

§verify_nbf: bool

Verify not before claim

§expected_issuer: Option<String>

Expected issuer

§require_iss: bool

Require issuer claim

§expected_audience: Option<String>

Expected audience

§require_aud: bool

Require audience claim

§verify_catu: bool

Verify CAT-specific URI claim (CATU) against provided URI

§uri: Option<String>

URI to verify against CATU claim

§verify_catm: bool

Verify CAT-specific HTTP methods claim (CATM) against provided method

§http_method: Option<String>

HTTP method to verify against CATM claim

§verify_catreplay: bool

Verify CAT-specific replay protection (CATREPLAY)

§token_seen_before: bool

Whether the token has been seen before (for replay protection)

Implementations§

Source§

impl VerificationOptions

Source

pub fn new() -> Self

Create new default verification options

Examples found in repository?
examples/cat_specific_claims.rs (line 28)
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}
More examples
Hide additional examples
examples/basic_usage.rs (line 144)
124fn verify_token(token_bytes: &[u8], key: &[u8], expected_token_type: &str) {
125    // Decode the token
126    let token = match common_access_token::Token::from_bytes(token_bytes) {
127        Ok(token) => token,
128        Err(err) => {
129            println!("Failed to decode {} token: {}", expected_token_type, err);
130            return;
131        }
132    };
133
134    // Verify the signature
135    if let Err(err) = token.verify(key) {
136        println!(
137            "Failed to verify {} token signature: {}",
138            expected_token_type, err
139        );
140        return;
141    }
142
143    // Verify the claims
144    let options = VerificationOptions::new()
145        .verify_exp(true)
146        .verify_nbf(true)
147        .expected_issuer("example-issuer")
148        .expected_audience("example-audience");
149
150    if let Err(err) = token.verify_claims(&options) {
151        println!(
152            "Failed to verify {} token claims: {}",
153            expected_token_type, err
154        );
155        return;
156    }
157
158    // Get the key ID
159    let kid = token.header.key_id().expect("No key ID in token");
160    let kid_str = match &kid {
161        KeyId::Binary(data) => format!("Binary key ID: {:?}", data),
162        KeyId::String(data) => format!("String key ID: {}", data),
163    };
164
165    println!(
166        "Successfully verified {} token ({})",
167        expected_token_type, kid_str
168    );
169
170    // Print some claims
171    if let Some(iss) = &token.claims.registered.iss {
172        println!("  Issuer: {}", iss);
173    }
174    if let Some(sub) = &token.claims.registered.sub {
175        println!("  Subject: {}", sub);
176    }
177    if let Some(exp) = token.claims.registered.exp {
178        println!(
179            "  Expires at: {} (in {} seconds)",
180            exp,
181            exp - current_timestamp()
182        );
183    }
184}
185
186/// Verify a token with a nested map claim
187fn verify_nested_map_token(token_bytes: &[u8], key: &[u8]) {
188    // Decode the token
189    let token = match common_access_token::Token::from_bytes(token_bytes) {
190        Ok(token) => token,
191        Err(err) => {
192            println!("Failed to decode nested map token: {}", err);
193            return;
194        }
195    };
196
197    // Verify the signature
198    if let Err(err) = token.verify(key) {
199        println!("Failed to verify nested map token signature: {}", err);
200        return;
201    }
202
203    // Verify the claims
204    let options = VerificationOptions::new()
205        .verify_exp(true)
206        .verify_nbf(true)
207        .expected_issuer("example-issuer")
208        .expected_audience("example-audience");
209
210    if let Err(err) = token.verify_claims(&options) {
211        println!("Failed to verify nested map token claims: {}", err);
212        return;
213    }
214
215    println!("Successfully verified nested map token");
216
217    // Check for the nested map claim
218    if let Some(CborValue::Map(map)) = token.claims.custom.get(&200) {
219        println!("  Found nested map claim with {} entries", map.len());
220
221        // Print first level entries
222        if let Some(CborValue::Text(text)) = map.get(&1) {
223            println!("  Entry 1: Text = {}", text);
224        }
225
226        if let Some(CborValue::Integer(num)) = map.get(&2) {
227            println!("  Entry 2: Integer = {}", num);
228        }
229
230        if let Some(CborValue::Bytes(bytes)) = map.get(&3) {
231            println!("  Entry 3: Bytes = {:?}", bytes);
232        }
233
234        // Check for second level map
235        if let Some(CborValue::Map(second_map)) = map.get(&4) {
236            println!("  Entry 4: Nested map with {} entries", second_map.len());
237
238            if let Some(CborValue::Text(text)) = second_map.get(&1) {
239                println!("    Nested Entry 1: Text = {}", text);
240            }
241
242            if let Some(CborValue::Integer(num)) = second_map.get(&2) {
243                println!("    Nested Entry 2: Integer = {}", num);
244            }
245        }
246    } else {
247        println!("  Nested map claim not found!");
248    }
249}
examples/cat_validation.rs (line 104)
93fn validate_catu_claim(token: &common_access_token::Token) {
94    println!("\nValidating CATU (URI) claim:");
95
96    // Define URIs to test
97    let valid_uri = "https://api.example.com/api/users.json";
98    let invalid_scheme_uri = "http://api.example.com/api/users.json";
99    let invalid_host_uri = "https://api.other-site.com/api/users.json";
100    let invalid_path_uri = "https://api.example.com/users.json";
101    let invalid_extension_uri = "https://api.example.com/api/users.xml";
102
103    // Test valid URI
104    let options = VerificationOptions::new().verify_catu(true).uri(valid_uri);
105
106    match token.verify_claims(&options) {
107        Ok(_) => println!("  VALID URI: {}", valid_uri),
108        Err(e) => println!(
109            "  ERROR: {} should be valid, but got error: {}",
110            valid_uri, e
111        ),
112    }
113
114    // Test invalid scheme
115    let invalid_scheme_options = VerificationOptions::new()
116        .verify_catu(true)
117        .uri(invalid_scheme_uri);
118
119    match token.verify_claims(&invalid_scheme_options) {
120        Ok(_) => println!(
121            "  ERROR: {} should be invalid (wrong scheme)",
122            invalid_scheme_uri
123        ),
124        Err(e) => println!(
125            "  INVALID URI (as expected): {} - Error: {}",
126            invalid_scheme_uri, e
127        ),
128    }
129
130    // Test invalid host
131    let invalid_host_options = VerificationOptions::new()
132        .verify_catu(true)
133        .uri(invalid_host_uri);
134
135    match token.verify_claims(&invalid_host_options) {
136        Ok(_) => println!(
137            "  ERROR: {} should be invalid (wrong host)",
138            invalid_host_uri
139        ),
140        Err(e) => println!(
141            "  INVALID URI (as expected): {} - Error: {}",
142            invalid_host_uri, e
143        ),
144    }
145
146    // Test invalid path
147    let invalid_path_options = VerificationOptions::new()
148        .verify_catu(true)
149        .uri(invalid_path_uri);
150
151    match token.verify_claims(&invalid_path_options) {
152        Ok(_) => println!(
153            "  ERROR: {} should be invalid (wrong path)",
154            invalid_path_uri
155        ),
156        Err(e) => println!(
157            "  INVALID URI (as expected): {} - Error: {}",
158            invalid_path_uri, e
159        ),
160    }
161
162    // Test invalid extension
163    let invalid_extension_options = VerificationOptions::new()
164        .verify_catu(true)
165        .uri(invalid_extension_uri);
166
167    match token.verify_claims(&invalid_extension_options) {
168        Ok(_) => println!(
169            "  ERROR: {} should be invalid (wrong extension)",
170            invalid_extension_uri
171        ),
172        Err(e) => println!(
173            "  INVALID URI (as expected): {} - Error: {}",
174            invalid_extension_uri, e
175        ),
176    }
177}
178
179/// Validate the CATM claim against different HTTP methods
180fn validate_catm_claim(token: &common_access_token::Token) {
181    println!("\nValidating CATM (HTTP Methods) claim:");
182
183    // Test allowed methods
184    for method in &["GET", "HEAD", "OPTIONS"] {
185        let options = VerificationOptions::new()
186            .verify_catm(true)
187            .http_method(*method);
188
189        match token.verify_claims(&options) {
190            Ok(_) => println!("  VALID METHOD: {}", method),
191            Err(e) => println!("  ERROR: {} should be valid, but got error: {}", method, e),
192        }
193    }
194
195    // Test disallowed methods
196    for method in &["POST", "PUT", "DELETE", "PATCH"] {
197        let options = VerificationOptions::new()
198            .verify_catm(true)
199            .http_method(*method);
200
201        match token.verify_claims(&options) {
202            Ok(_) => println!("  ERROR: {} should be invalid method", method),
203            Err(e) => println!("  INVALID METHOD (as expected): {} - Error: {}", method, e),
204        }
205    }
206}
207
208/// Validate the CATREPLAY claim
209fn validate_catreplay_claim(token: &common_access_token::Token) {
210    println!("\nValidating CATREPLAY claim:");
211
212    // Test with token not seen before (should pass)
213    let options_not_seen = VerificationOptions::new()
214        .verify_catreplay(true)
215        .token_seen_before(false);
216
217    match token.verify_claims(&options_not_seen) {
218        Ok(_) => println!("  VALID: Token not seen before is accepted (as expected)"),
219        Err(e) => println!(
220            "  ERROR: Token not seen before should be valid, but got error: {}",
221            e
222        ),
223    }
224
225    // Test with token seen before (should fail with replay prohibited)
226    let options_seen = VerificationOptions::new()
227        .verify_catreplay(true)
228        .token_seen_before(true);
229
230    match token.verify_claims(&options_seen) {
231        Ok(_) => println!("  ERROR: Token seen before should be rejected"),
232        Err(e) => println!(
233            "  INVALID (as expected): Token seen before is rejected - Error: {}",
234            e
235        ),
236    }
237}
Source

pub fn verify_exp(self, verify: bool) -> Self

Set whether to verify expiration

Examples found in repository?
examples/cat_specific_claims.rs (line 29)
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}
More examples
Hide additional examples
examples/basic_usage.rs (line 145)
124fn verify_token(token_bytes: &[u8], key: &[u8], expected_token_type: &str) {
125    // Decode the token
126    let token = match common_access_token::Token::from_bytes(token_bytes) {
127        Ok(token) => token,
128        Err(err) => {
129            println!("Failed to decode {} token: {}", expected_token_type, err);
130            return;
131        }
132    };
133
134    // Verify the signature
135    if let Err(err) = token.verify(key) {
136        println!(
137            "Failed to verify {} token signature: {}",
138            expected_token_type, err
139        );
140        return;
141    }
142
143    // Verify the claims
144    let options = VerificationOptions::new()
145        .verify_exp(true)
146        .verify_nbf(true)
147        .expected_issuer("example-issuer")
148        .expected_audience("example-audience");
149
150    if let Err(err) = token.verify_claims(&options) {
151        println!(
152            "Failed to verify {} token claims: {}",
153            expected_token_type, err
154        );
155        return;
156    }
157
158    // Get the key ID
159    let kid = token.header.key_id().expect("No key ID in token");
160    let kid_str = match &kid {
161        KeyId::Binary(data) => format!("Binary key ID: {:?}", data),
162        KeyId::String(data) => format!("String key ID: {}", data),
163    };
164
165    println!(
166        "Successfully verified {} token ({})",
167        expected_token_type, kid_str
168    );
169
170    // Print some claims
171    if let Some(iss) = &token.claims.registered.iss {
172        println!("  Issuer: {}", iss);
173    }
174    if let Some(sub) = &token.claims.registered.sub {
175        println!("  Subject: {}", sub);
176    }
177    if let Some(exp) = token.claims.registered.exp {
178        println!(
179            "  Expires at: {} (in {} seconds)",
180            exp,
181            exp - current_timestamp()
182        );
183    }
184}
185
186/// Verify a token with a nested map claim
187fn verify_nested_map_token(token_bytes: &[u8], key: &[u8]) {
188    // Decode the token
189    let token = match common_access_token::Token::from_bytes(token_bytes) {
190        Ok(token) => token,
191        Err(err) => {
192            println!("Failed to decode nested map token: {}", err);
193            return;
194        }
195    };
196
197    // Verify the signature
198    if let Err(err) = token.verify(key) {
199        println!("Failed to verify nested map token signature: {}", err);
200        return;
201    }
202
203    // Verify the claims
204    let options = VerificationOptions::new()
205        .verify_exp(true)
206        .verify_nbf(true)
207        .expected_issuer("example-issuer")
208        .expected_audience("example-audience");
209
210    if let Err(err) = token.verify_claims(&options) {
211        println!("Failed to verify nested map token claims: {}", err);
212        return;
213    }
214
215    println!("Successfully verified nested map token");
216
217    // Check for the nested map claim
218    if let Some(CborValue::Map(map)) = token.claims.custom.get(&200) {
219        println!("  Found nested map claim with {} entries", map.len());
220
221        // Print first level entries
222        if let Some(CborValue::Text(text)) = map.get(&1) {
223            println!("  Entry 1: Text = {}", text);
224        }
225
226        if let Some(CborValue::Integer(num)) = map.get(&2) {
227            println!("  Entry 2: Integer = {}", num);
228        }
229
230        if let Some(CborValue::Bytes(bytes)) = map.get(&3) {
231            println!("  Entry 3: Bytes = {:?}", bytes);
232        }
233
234        // Check for second level map
235        if let Some(CborValue::Map(second_map)) = map.get(&4) {
236            println!("  Entry 4: Nested map with {} entries", second_map.len());
237
238            if let Some(CborValue::Text(text)) = second_map.get(&1) {
239                println!("    Nested Entry 1: Text = {}", text);
240            }
241
242            if let Some(CborValue::Integer(num)) = second_map.get(&2) {
243                println!("    Nested Entry 2: Integer = {}", num);
244            }
245        }
246    } else {
247        println!("  Nested map claim not found!");
248    }
249}
Source

pub fn require_exp(self, require: bool) -> Self

Set whether to require expiration

Source

pub fn verify_nbf(self, verify: bool) -> Self

Set whether to verify not before

Examples found in repository?
examples/basic_usage.rs (line 146)
124fn verify_token(token_bytes: &[u8], key: &[u8], expected_token_type: &str) {
125    // Decode the token
126    let token = match common_access_token::Token::from_bytes(token_bytes) {
127        Ok(token) => token,
128        Err(err) => {
129            println!("Failed to decode {} token: {}", expected_token_type, err);
130            return;
131        }
132    };
133
134    // Verify the signature
135    if let Err(err) = token.verify(key) {
136        println!(
137            "Failed to verify {} token signature: {}",
138            expected_token_type, err
139        );
140        return;
141    }
142
143    // Verify the claims
144    let options = VerificationOptions::new()
145        .verify_exp(true)
146        .verify_nbf(true)
147        .expected_issuer("example-issuer")
148        .expected_audience("example-audience");
149
150    if let Err(err) = token.verify_claims(&options) {
151        println!(
152            "Failed to verify {} token claims: {}",
153            expected_token_type, err
154        );
155        return;
156    }
157
158    // Get the key ID
159    let kid = token.header.key_id().expect("No key ID in token");
160    let kid_str = match &kid {
161        KeyId::Binary(data) => format!("Binary key ID: {:?}", data),
162        KeyId::String(data) => format!("String key ID: {}", data),
163    };
164
165    println!(
166        "Successfully verified {} token ({})",
167        expected_token_type, kid_str
168    );
169
170    // Print some claims
171    if let Some(iss) = &token.claims.registered.iss {
172        println!("  Issuer: {}", iss);
173    }
174    if let Some(sub) = &token.claims.registered.sub {
175        println!("  Subject: {}", sub);
176    }
177    if let Some(exp) = token.claims.registered.exp {
178        println!(
179            "  Expires at: {} (in {} seconds)",
180            exp,
181            exp - current_timestamp()
182        );
183    }
184}
185
186/// Verify a token with a nested map claim
187fn verify_nested_map_token(token_bytes: &[u8], key: &[u8]) {
188    // Decode the token
189    let token = match common_access_token::Token::from_bytes(token_bytes) {
190        Ok(token) => token,
191        Err(err) => {
192            println!("Failed to decode nested map token: {}", err);
193            return;
194        }
195    };
196
197    // Verify the signature
198    if let Err(err) = token.verify(key) {
199        println!("Failed to verify nested map token signature: {}", err);
200        return;
201    }
202
203    // Verify the claims
204    let options = VerificationOptions::new()
205        .verify_exp(true)
206        .verify_nbf(true)
207        .expected_issuer("example-issuer")
208        .expected_audience("example-audience");
209
210    if let Err(err) = token.verify_claims(&options) {
211        println!("Failed to verify nested map token claims: {}", err);
212        return;
213    }
214
215    println!("Successfully verified nested map token");
216
217    // Check for the nested map claim
218    if let Some(CborValue::Map(map)) = token.claims.custom.get(&200) {
219        println!("  Found nested map claim with {} entries", map.len());
220
221        // Print first level entries
222        if let Some(CborValue::Text(text)) = map.get(&1) {
223            println!("  Entry 1: Text = {}", text);
224        }
225
226        if let Some(CborValue::Integer(num)) = map.get(&2) {
227            println!("  Entry 2: Integer = {}", num);
228        }
229
230        if let Some(CborValue::Bytes(bytes)) = map.get(&3) {
231            println!("  Entry 3: Bytes = {:?}", bytes);
232        }
233
234        // Check for second level map
235        if let Some(CborValue::Map(second_map)) = map.get(&4) {
236            println!("  Entry 4: Nested map with {} entries", second_map.len());
237
238            if let Some(CborValue::Text(text)) = second_map.get(&1) {
239                println!("    Nested Entry 1: Text = {}", text);
240            }
241
242            if let Some(CborValue::Integer(num)) = second_map.get(&2) {
243                println!("    Nested Entry 2: Integer = {}", num);
244            }
245        }
246    } else {
247        println!("  Nested map claim not found!");
248    }
249}
Source

pub fn expected_issuer<S: Into<String>>(self, issuer: S) -> Self

Set expected issuer

Examples found in repository?
examples/cat_specific_claims.rs (line 30)
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}
More examples
Hide additional examples
examples/basic_usage.rs (line 147)
124fn verify_token(token_bytes: &[u8], key: &[u8], expected_token_type: &str) {
125    // Decode the token
126    let token = match common_access_token::Token::from_bytes(token_bytes) {
127        Ok(token) => token,
128        Err(err) => {
129            println!("Failed to decode {} token: {}", expected_token_type, err);
130            return;
131        }
132    };
133
134    // Verify the signature
135    if let Err(err) = token.verify(key) {
136        println!(
137            "Failed to verify {} token signature: {}",
138            expected_token_type, err
139        );
140        return;
141    }
142
143    // Verify the claims
144    let options = VerificationOptions::new()
145        .verify_exp(true)
146        .verify_nbf(true)
147        .expected_issuer("example-issuer")
148        .expected_audience("example-audience");
149
150    if let Err(err) = token.verify_claims(&options) {
151        println!(
152            "Failed to verify {} token claims: {}",
153            expected_token_type, err
154        );
155        return;
156    }
157
158    // Get the key ID
159    let kid = token.header.key_id().expect("No key ID in token");
160    let kid_str = match &kid {
161        KeyId::Binary(data) => format!("Binary key ID: {:?}", data),
162        KeyId::String(data) => format!("String key ID: {}", data),
163    };
164
165    println!(
166        "Successfully verified {} token ({})",
167        expected_token_type, kid_str
168    );
169
170    // Print some claims
171    if let Some(iss) = &token.claims.registered.iss {
172        println!("  Issuer: {}", iss);
173    }
174    if let Some(sub) = &token.claims.registered.sub {
175        println!("  Subject: {}", sub);
176    }
177    if let Some(exp) = token.claims.registered.exp {
178        println!(
179            "  Expires at: {} (in {} seconds)",
180            exp,
181            exp - current_timestamp()
182        );
183    }
184}
185
186/// Verify a token with a nested map claim
187fn verify_nested_map_token(token_bytes: &[u8], key: &[u8]) {
188    // Decode the token
189    let token = match common_access_token::Token::from_bytes(token_bytes) {
190        Ok(token) => token,
191        Err(err) => {
192            println!("Failed to decode nested map token: {}", err);
193            return;
194        }
195    };
196
197    // Verify the signature
198    if let Err(err) = token.verify(key) {
199        println!("Failed to verify nested map token signature: {}", err);
200        return;
201    }
202
203    // Verify the claims
204    let options = VerificationOptions::new()
205        .verify_exp(true)
206        .verify_nbf(true)
207        .expected_issuer("example-issuer")
208        .expected_audience("example-audience");
209
210    if let Err(err) = token.verify_claims(&options) {
211        println!("Failed to verify nested map token claims: {}", err);
212        return;
213    }
214
215    println!("Successfully verified nested map token");
216
217    // Check for the nested map claim
218    if let Some(CborValue::Map(map)) = token.claims.custom.get(&200) {
219        println!("  Found nested map claim with {} entries", map.len());
220
221        // Print first level entries
222        if let Some(CborValue::Text(text)) = map.get(&1) {
223            println!("  Entry 1: Text = {}", text);
224        }
225
226        if let Some(CborValue::Integer(num)) = map.get(&2) {
227            println!("  Entry 2: Integer = {}", num);
228        }
229
230        if let Some(CborValue::Bytes(bytes)) = map.get(&3) {
231            println!("  Entry 3: Bytes = {:?}", bytes);
232        }
233
234        // Check for second level map
235        if let Some(CborValue::Map(second_map)) = map.get(&4) {
236            println!("  Entry 4: Nested map with {} entries", second_map.len());
237
238            if let Some(CborValue::Text(text)) = second_map.get(&1) {
239                println!("    Nested Entry 1: Text = {}", text);
240            }
241
242            if let Some(CborValue::Integer(num)) = second_map.get(&2) {
243                println!("    Nested Entry 2: Integer = {}", num);
244            }
245        }
246    } else {
247        println!("  Nested map claim not found!");
248    }
249}
Source

pub fn require_iss(self, require: bool) -> Self

Set whether to require issuer

Source

pub fn expected_audience<S: Into<String>>(self, audience: S) -> Self

Set expected audience

Examples found in repository?
examples/basic_usage.rs (line 148)
124fn verify_token(token_bytes: &[u8], key: &[u8], expected_token_type: &str) {
125    // Decode the token
126    let token = match common_access_token::Token::from_bytes(token_bytes) {
127        Ok(token) => token,
128        Err(err) => {
129            println!("Failed to decode {} token: {}", expected_token_type, err);
130            return;
131        }
132    };
133
134    // Verify the signature
135    if let Err(err) = token.verify(key) {
136        println!(
137            "Failed to verify {} token signature: {}",
138            expected_token_type, err
139        );
140        return;
141    }
142
143    // Verify the claims
144    let options = VerificationOptions::new()
145        .verify_exp(true)
146        .verify_nbf(true)
147        .expected_issuer("example-issuer")
148        .expected_audience("example-audience");
149
150    if let Err(err) = token.verify_claims(&options) {
151        println!(
152            "Failed to verify {} token claims: {}",
153            expected_token_type, err
154        );
155        return;
156    }
157
158    // Get the key ID
159    let kid = token.header.key_id().expect("No key ID in token");
160    let kid_str = match &kid {
161        KeyId::Binary(data) => format!("Binary key ID: {:?}", data),
162        KeyId::String(data) => format!("String key ID: {}", data),
163    };
164
165    println!(
166        "Successfully verified {} token ({})",
167        expected_token_type, kid_str
168    );
169
170    // Print some claims
171    if let Some(iss) = &token.claims.registered.iss {
172        println!("  Issuer: {}", iss);
173    }
174    if let Some(sub) = &token.claims.registered.sub {
175        println!("  Subject: {}", sub);
176    }
177    if let Some(exp) = token.claims.registered.exp {
178        println!(
179            "  Expires at: {} (in {} seconds)",
180            exp,
181            exp - current_timestamp()
182        );
183    }
184}
185
186/// Verify a token with a nested map claim
187fn verify_nested_map_token(token_bytes: &[u8], key: &[u8]) {
188    // Decode the token
189    let token = match common_access_token::Token::from_bytes(token_bytes) {
190        Ok(token) => token,
191        Err(err) => {
192            println!("Failed to decode nested map token: {}", err);
193            return;
194        }
195    };
196
197    // Verify the signature
198    if let Err(err) = token.verify(key) {
199        println!("Failed to verify nested map token signature: {}", err);
200        return;
201    }
202
203    // Verify the claims
204    let options = VerificationOptions::new()
205        .verify_exp(true)
206        .verify_nbf(true)
207        .expected_issuer("example-issuer")
208        .expected_audience("example-audience");
209
210    if let Err(err) = token.verify_claims(&options) {
211        println!("Failed to verify nested map token claims: {}", err);
212        return;
213    }
214
215    println!("Successfully verified nested map token");
216
217    // Check for the nested map claim
218    if let Some(CborValue::Map(map)) = token.claims.custom.get(&200) {
219        println!("  Found nested map claim with {} entries", map.len());
220
221        // Print first level entries
222        if let Some(CborValue::Text(text)) = map.get(&1) {
223            println!("  Entry 1: Text = {}", text);
224        }
225
226        if let Some(CborValue::Integer(num)) = map.get(&2) {
227            println!("  Entry 2: Integer = {}", num);
228        }
229
230        if let Some(CborValue::Bytes(bytes)) = map.get(&3) {
231            println!("  Entry 3: Bytes = {:?}", bytes);
232        }
233
234        // Check for second level map
235        if let Some(CborValue::Map(second_map)) = map.get(&4) {
236            println!("  Entry 4: Nested map with {} entries", second_map.len());
237
238            if let Some(CborValue::Text(text)) = second_map.get(&1) {
239                println!("    Nested Entry 1: Text = {}", text);
240            }
241
242            if let Some(CborValue::Integer(num)) = second_map.get(&2) {
243                println!("    Nested Entry 2: Integer = {}", num);
244            }
245        }
246    } else {
247        println!("  Nested map claim not found!");
248    }
249}
Source

pub fn require_aud(self, require: bool) -> Self

Set whether to require audience

Source

pub fn verify_catu(self, verify: bool) -> Self

Set whether to verify CAT-specific URI claim (CATU)

Examples found in repository?
examples/cat_validation.rs (line 104)
93fn validate_catu_claim(token: &common_access_token::Token) {
94    println!("\nValidating CATU (URI) claim:");
95
96    // Define URIs to test
97    let valid_uri = "https://api.example.com/api/users.json";
98    let invalid_scheme_uri = "http://api.example.com/api/users.json";
99    let invalid_host_uri = "https://api.other-site.com/api/users.json";
100    let invalid_path_uri = "https://api.example.com/users.json";
101    let invalid_extension_uri = "https://api.example.com/api/users.xml";
102
103    // Test valid URI
104    let options = VerificationOptions::new().verify_catu(true).uri(valid_uri);
105
106    match token.verify_claims(&options) {
107        Ok(_) => println!("  VALID URI: {}", valid_uri),
108        Err(e) => println!(
109            "  ERROR: {} should be valid, but got error: {}",
110            valid_uri, e
111        ),
112    }
113
114    // Test invalid scheme
115    let invalid_scheme_options = VerificationOptions::new()
116        .verify_catu(true)
117        .uri(invalid_scheme_uri);
118
119    match token.verify_claims(&invalid_scheme_options) {
120        Ok(_) => println!(
121            "  ERROR: {} should be invalid (wrong scheme)",
122            invalid_scheme_uri
123        ),
124        Err(e) => println!(
125            "  INVALID URI (as expected): {} - Error: {}",
126            invalid_scheme_uri, e
127        ),
128    }
129
130    // Test invalid host
131    let invalid_host_options = VerificationOptions::new()
132        .verify_catu(true)
133        .uri(invalid_host_uri);
134
135    match token.verify_claims(&invalid_host_options) {
136        Ok(_) => println!(
137            "  ERROR: {} should be invalid (wrong host)",
138            invalid_host_uri
139        ),
140        Err(e) => println!(
141            "  INVALID URI (as expected): {} - Error: {}",
142            invalid_host_uri, e
143        ),
144    }
145
146    // Test invalid path
147    let invalid_path_options = VerificationOptions::new()
148        .verify_catu(true)
149        .uri(invalid_path_uri);
150
151    match token.verify_claims(&invalid_path_options) {
152        Ok(_) => println!(
153            "  ERROR: {} should be invalid (wrong path)",
154            invalid_path_uri
155        ),
156        Err(e) => println!(
157            "  INVALID URI (as expected): {} - Error: {}",
158            invalid_path_uri, e
159        ),
160    }
161
162    // Test invalid extension
163    let invalid_extension_options = VerificationOptions::new()
164        .verify_catu(true)
165        .uri(invalid_extension_uri);
166
167    match token.verify_claims(&invalid_extension_options) {
168        Ok(_) => println!(
169            "  ERROR: {} should be invalid (wrong extension)",
170            invalid_extension_uri
171        ),
172        Err(e) => println!(
173            "  INVALID URI (as expected): {} - Error: {}",
174            invalid_extension_uri, e
175        ),
176    }
177}
Source

pub fn uri<S: Into<String>>(self, uri: S) -> Self

Set URI to verify against CATU claim

Examples found in repository?
examples/cat_validation.rs (line 104)
93fn validate_catu_claim(token: &common_access_token::Token) {
94    println!("\nValidating CATU (URI) claim:");
95
96    // Define URIs to test
97    let valid_uri = "https://api.example.com/api/users.json";
98    let invalid_scheme_uri = "http://api.example.com/api/users.json";
99    let invalid_host_uri = "https://api.other-site.com/api/users.json";
100    let invalid_path_uri = "https://api.example.com/users.json";
101    let invalid_extension_uri = "https://api.example.com/api/users.xml";
102
103    // Test valid URI
104    let options = VerificationOptions::new().verify_catu(true).uri(valid_uri);
105
106    match token.verify_claims(&options) {
107        Ok(_) => println!("  VALID URI: {}", valid_uri),
108        Err(e) => println!(
109            "  ERROR: {} should be valid, but got error: {}",
110            valid_uri, e
111        ),
112    }
113
114    // Test invalid scheme
115    let invalid_scheme_options = VerificationOptions::new()
116        .verify_catu(true)
117        .uri(invalid_scheme_uri);
118
119    match token.verify_claims(&invalid_scheme_options) {
120        Ok(_) => println!(
121            "  ERROR: {} should be invalid (wrong scheme)",
122            invalid_scheme_uri
123        ),
124        Err(e) => println!(
125            "  INVALID URI (as expected): {} - Error: {}",
126            invalid_scheme_uri, e
127        ),
128    }
129
130    // Test invalid host
131    let invalid_host_options = VerificationOptions::new()
132        .verify_catu(true)
133        .uri(invalid_host_uri);
134
135    match token.verify_claims(&invalid_host_options) {
136        Ok(_) => println!(
137            "  ERROR: {} should be invalid (wrong host)",
138            invalid_host_uri
139        ),
140        Err(e) => println!(
141            "  INVALID URI (as expected): {} - Error: {}",
142            invalid_host_uri, e
143        ),
144    }
145
146    // Test invalid path
147    let invalid_path_options = VerificationOptions::new()
148        .verify_catu(true)
149        .uri(invalid_path_uri);
150
151    match token.verify_claims(&invalid_path_options) {
152        Ok(_) => println!(
153            "  ERROR: {} should be invalid (wrong path)",
154            invalid_path_uri
155        ),
156        Err(e) => println!(
157            "  INVALID URI (as expected): {} - Error: {}",
158            invalid_path_uri, e
159        ),
160    }
161
162    // Test invalid extension
163    let invalid_extension_options = VerificationOptions::new()
164        .verify_catu(true)
165        .uri(invalid_extension_uri);
166
167    match token.verify_claims(&invalid_extension_options) {
168        Ok(_) => println!(
169            "  ERROR: {} should be invalid (wrong extension)",
170            invalid_extension_uri
171        ),
172        Err(e) => println!(
173            "  INVALID URI (as expected): {} - Error: {}",
174            invalid_extension_uri, e
175        ),
176    }
177}
Source

pub fn verify_catm(self, verify: bool) -> Self

Set whether to verify CAT-specific HTTP methods claim (CATM)

Examples found in repository?
examples/cat_validation.rs (line 186)
180fn validate_catm_claim(token: &common_access_token::Token) {
181    println!("\nValidating CATM (HTTP Methods) claim:");
182
183    // Test allowed methods
184    for method in &["GET", "HEAD", "OPTIONS"] {
185        let options = VerificationOptions::new()
186            .verify_catm(true)
187            .http_method(*method);
188
189        match token.verify_claims(&options) {
190            Ok(_) => println!("  VALID METHOD: {}", method),
191            Err(e) => println!("  ERROR: {} should be valid, but got error: {}", method, e),
192        }
193    }
194
195    // Test disallowed methods
196    for method in &["POST", "PUT", "DELETE", "PATCH"] {
197        let options = VerificationOptions::new()
198            .verify_catm(true)
199            .http_method(*method);
200
201        match token.verify_claims(&options) {
202            Ok(_) => println!("  ERROR: {} should be invalid method", method),
203            Err(e) => println!("  INVALID METHOD (as expected): {} - Error: {}", method, e),
204        }
205    }
206}
Source

pub fn http_method<S: Into<String>>(self, method: S) -> Self

Set HTTP method to verify against CATM claim

Examples found in repository?
examples/cat_validation.rs (line 187)
180fn validate_catm_claim(token: &common_access_token::Token) {
181    println!("\nValidating CATM (HTTP Methods) claim:");
182
183    // Test allowed methods
184    for method in &["GET", "HEAD", "OPTIONS"] {
185        let options = VerificationOptions::new()
186            .verify_catm(true)
187            .http_method(*method);
188
189        match token.verify_claims(&options) {
190            Ok(_) => println!("  VALID METHOD: {}", method),
191            Err(e) => println!("  ERROR: {} should be valid, but got error: {}", method, e),
192        }
193    }
194
195    // Test disallowed methods
196    for method in &["POST", "PUT", "DELETE", "PATCH"] {
197        let options = VerificationOptions::new()
198            .verify_catm(true)
199            .http_method(*method);
200
201        match token.verify_claims(&options) {
202            Ok(_) => println!("  ERROR: {} should be invalid method", method),
203            Err(e) => println!("  INVALID METHOD (as expected): {} - Error: {}", method, e),
204        }
205    }
206}
Source

pub fn verify_catreplay(self, verify: bool) -> Self

Set whether to verify CAT-specific replay protection (CATREPLAY)

Examples found in repository?
examples/cat_validation.rs (line 214)
209fn validate_catreplay_claim(token: &common_access_token::Token) {
210    println!("\nValidating CATREPLAY claim:");
211
212    // Test with token not seen before (should pass)
213    let options_not_seen = VerificationOptions::new()
214        .verify_catreplay(true)
215        .token_seen_before(false);
216
217    match token.verify_claims(&options_not_seen) {
218        Ok(_) => println!("  VALID: Token not seen before is accepted (as expected)"),
219        Err(e) => println!(
220            "  ERROR: Token not seen before should be valid, but got error: {}",
221            e
222        ),
223    }
224
225    // Test with token seen before (should fail with replay prohibited)
226    let options_seen = VerificationOptions::new()
227        .verify_catreplay(true)
228        .token_seen_before(true);
229
230    match token.verify_claims(&options_seen) {
231        Ok(_) => println!("  ERROR: Token seen before should be rejected"),
232        Err(e) => println!(
233            "  INVALID (as expected): Token seen before is rejected - Error: {}",
234            e
235        ),
236    }
237}
Source

pub fn token_seen_before(self, seen: bool) -> Self

Set whether the token has been seen before (for replay protection)

Examples found in repository?
examples/cat_validation.rs (line 215)
209fn validate_catreplay_claim(token: &common_access_token::Token) {
210    println!("\nValidating CATREPLAY claim:");
211
212    // Test with token not seen before (should pass)
213    let options_not_seen = VerificationOptions::new()
214        .verify_catreplay(true)
215        .token_seen_before(false);
216
217    match token.verify_claims(&options_not_seen) {
218        Ok(_) => println!("  VALID: Token not seen before is accepted (as expected)"),
219        Err(e) => println!(
220            "  ERROR: Token not seen before should be valid, but got error: {}",
221            e
222        ),
223    }
224
225    // Test with token seen before (should fail with replay prohibited)
226    let options_seen = VerificationOptions::new()
227        .verify_catreplay(true)
228        .token_seen_before(true);
229
230    match token.verify_claims(&options_seen) {
231        Ok(_) => println!("  ERROR: Token seen before should be rejected"),
232        Err(e) => println!(
233            "  INVALID (as expected): Token seen before is rejected - Error: {}",
234            e
235        ),
236    }
237}

Trait Implementations§

Source§

impl Clone for VerificationOptions

Source§

fn clone(&self) -> VerificationOptions

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for VerificationOptions

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for VerificationOptions

Source§

fn default() -> VerificationOptions

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> ErasedDestructor for T
where T: 'static,