krabka_verified/authz/
session.rs1use creusot_std::prelude::*;
2
3#[ensures((result.0 == None) == (credential_expiry_ms == None
6 && match reauth_ms { None => true, Some(cap) => cap@ <= 0 }))]
7#[ensures(match (credential_expiry_ms, result.0) {
8 (Some(credential), Some(at)) => at@ <= credential@,
9 _ => true,
10})]
11#[ensures(match (reauth_ms, result.0) {
12 (Some(cap), Some(at)) => cap@ > 0 ==> at@ <= now_ms@ + cap@,
13 _ => true,
14})]
15#[ensures(match result.0 {
16 None => true,
17 Some(at) => credential_expiry_ms == Some(at) || match reauth_ms {
18 None => false,
19 Some(cap) => cap@ > 0 && (at@ == now_ms@ + cap@ || at@ == i64::MAX@),
20 },
21})]
22#[ensures(match result.0 {
23 None => result.1@ == 0,
24 Some(at) => result.1@ == if at@ <= now_ms@ { 0 }
25 else if at@ - now_ms@ > i64::MAX@ { i64::MAX@ }
26 else { at@ - now_ms@ },
27})]
28#[must_use]
29pub fn sasl_session_expiry(
30 now_ms: i64,
31 credential_expiry_ms: Option<i64>,
32 reauth_ms: Option<i64>,
33) -> (Option<i64>, i64) {
34 let cap_expiry = match reauth_ms {
35 Some(cap) if cap > 0 => Some(now_ms.saturating_add(cap)),
36 _ => None,
37 };
38 let expiry = match (credential_expiry_ms, cap_expiry) {
39 (Some(credential), Some(cap)) => Some(credential.min(cap)),
40 (credential, cap) => credential.or(cap),
41 };
42 let Some(at) = expiry else {
43 return (expiry, 0);
44 };
45 (expiry, at.saturating_sub(now_ms).max(0))
46}
47
48pub const MIN_REAUTH_INTERVAL_MS: i64 = 1_000;
51
52#[ensures(result == (expiry_ms != None && match last_start_ms {
59 None => true,
60 Some(last) => now_ms@ - last@ >= 1000,
61}))]
62#[must_use]
63pub fn reauthentication_begins(
64 expiry_ms: Option<i64>,
65 now_ms: i64,
66 last_start_ms: Option<i64>,
67) -> bool {
68 match (expiry_ms, last_start_ms) {
69 (None, _) => false,
70 (Some(_), None) => true,
71 (Some(_), Some(last)) => now_ms.saturating_sub(last) >= MIN_REAUTH_INTERVAL_MS,
72 }
73}
74
75#[ensures(result == (match expiry_ms {
88 None => false,
89 Some(at) => now_ms@ > at@,
90} && !(api_key@ == 17 && match last_reauth_start_ms {
91 None => true,
92 Some(last) => now_ms@ - last@ >= 1000,
93})))]
94#[must_use]
95pub fn session_expired_for_request(
96 expiry_ms: Option<i64>,
97 api_key: i16,
98 now_ms: i64,
99 last_reauth_start_ms: Option<i64>,
100) -> bool {
101 match expiry_ms {
102 Some(at) if now_ms > at => {
103 !(api_key == 17 && reauthentication_begins(expiry_ms, now_ms, last_reauth_start_ms))
104 }
105 _ => false,
106 }
107}