MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / validate_or_reject

Method validate_or_reject

nodedb-crdt/src/validator/validate.rs:51–162  ·  view source on GitHub ↗

Validate and apply declarative policy resolution. ## Replay protection When `auth.delta_signature` is non-zero, the following steps execute in this order to prevent replay attacks at minimum cost: 1. **Cheap seq_no check** — `seq_no > last_seen[(user_id, device_id)]`. Fails fast before any HMAC computation. 2. **HMAC verification** — constant-time comparison prevents timing attacks. 3. **Atomic

(
        &mut self,
        state: &CrdtState,
        peer_id: u64,
        auth: CrdtAuthContext,
        change: &ProposedChange,
        delta_bytes: Vec<u8>,
    )

Source from the content-addressed store, hash-verified

49 /// - If AutoResolved: returns Ok(())
50 /// - If Deferred/Webhook/Escalate: returns appropriate error
51 pub fn validate_or_reject(
52 &mut self,
53 state: &CrdtState,
54 peer_id: u64,
55 auth: CrdtAuthContext,
56 change: &ProposedChange,
57 delta_bytes: Vec<u8>,
58 ) -> Result<()> {
59 // Check auth expiry: agents that accumulated deltas offline must
60 // re-authenticate before syncing.
61 if auth.auth_expires_at > 0 {
62 let now_ms = std::time::SystemTime::now()
63 .duration_since(std::time::UNIX_EPOCH)
64 .unwrap_or_default()
65 .as_millis() as u64;
66 if now_ms > auth.auth_expires_at {
67 return Err(CrdtError::AuthExpired {
68 user_id: auth.user_id,
69 expired_at: auth.auth_expires_at,
70 });
71 }
72 }
73
74 // Replay protection + signature verification (signed path only).
75 //
76 // The unsigned path (all-zeros signature) bypasses replay protection.
77 // Old clients that send device_id=0 / seq_no=0 with a non-zero
78 // signature will be rejected by the seq_no check (0 is never > 0).
79 if auth.delta_signature != [0u8; 32]
80 && let Some(ref verifier) = self.delta_verifier
81 {
82 // Step 1: cheap seq_no check before any HMAC computation.
83 verifier
84 .registry()
85 .check_seq(auth.user_id, auth.device_id, auth.seq_no)?;
86
87 // Step 2: constant-time HMAC verification.
88 verifier.verify(
89 auth.user_id,
90 auth.device_id,
91 auth.seq_no,
92 &delta_bytes,
93 &auth.delta_signature,
94 )?;
95
96 // Step 3: advance last_seen atomically on success.
97 verifier
98 .registry()
99 .commit_seq(auth.user_id, auth.device_id, auth.seq_no)?;
100 }
101
102 let hlc_timestamp = std::time::SystemTime::now()
103 .duration_since(std::time::UNIX_EPOCH)
104 .unwrap_or_default()
105 .as_millis() as u64;
106
107 match self.validate_with_policy(state, peer_id, auth, change, delta_bytes, hlc_timestamp)? {
108 PolicyResolution::AutoResolved(_) => Ok(()),

Calls 11

nowFunction · 0.85
duration_sinceMethod · 0.80
check_seqMethod · 0.80
registryMethod · 0.80
commit_seqMethod · 0.80
validate_with_policyMethod · 0.80
as_millisMethod · 0.45
verifyMethod · 0.45
validateMethod · 0.45
is_emptyMethod · 0.45
cloneMethod · 0.45