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

Function parse_envelope

nodedb-cluster/src/rpc_codec/auth_envelope.rs:99–144  ·  view source on GitHub ↗

Validate the envelope + MAC and return `(fields, inner_frame)`. `data` must be the entire envelope — nothing before the version byte, nothing after the MAC tag.

(data: &'a [u8], key: &MacKey)

Source from the content-addressed store, hash-verified

97/// `data` must be the entire envelope — nothing before the version byte,
98/// nothing after the MAC tag.
99pub fn parse_envelope<'a>(data: &'a [u8], key: &MacKey) -> Result<(EnvelopeFields, &'a [u8])> {
100 if data.len() < ENVELOPE_OVERHEAD {
101 return Err(ClusterError::Codec {
102 detail: format!(
103 "envelope too short: {} bytes, need at least {ENVELOPE_OVERHEAD}",
104 data.len()
105 ),
106 });
107 }
108
109 let version = data[OFF_VERSION];
110 if version != ENVELOPE_VERSION {
111 return Err(ClusterError::Codec {
112 detail: format!("unsupported envelope version {version}, expected {ENVELOPE_VERSION}"),
113 });
114 }
115
116 let from_node_id = u64::from_le_bytes(data[OFF_FROM_NODE..OFF_SEQ].try_into().expect("invariant: ENVELOPE_OVERHEAD/total-length checks above guarantee field bytes within bounds"));
117 let seq = u64::from_le_bytes(data[OFF_SEQ..OFF_INNER_LEN].try_into().expect("invariant: ENVELOPE_OVERHEAD/total-length checks above guarantee field bytes within bounds"));
118 let inner_len = u32::from_le_bytes(data[OFF_INNER_LEN..ENV_HEADER_LEN].try_into().expect("invariant: ENVELOPE_OVERHEAD/total-length checks above guarantee field bytes within bounds"));
119
120 if inner_len > MAX_RPC_PAYLOAD_SIZE {
121 return Err(ClusterError::Codec {
122 detail: format!(
123 "envelope inner length {inner_len} exceeds maximum {MAX_RPC_PAYLOAD_SIZE}"
124 ),
125 });
126 }
127
128 let inner_end = ENV_HEADER_LEN + inner_len as usize;
129 let expected_total = inner_end + MAC_LEN;
130 if data.len() != expected_total {
131 return Err(ClusterError::Codec {
132 detail: format!(
133 "envelope length mismatch: got {} bytes, expected {expected_total}",
134 data.len()
135 ),
136 });
137 }
138
139 let tag: &[u8; MAC_LEN] = data[inner_end..].try_into().expect("invariant: ENVELOPE_OVERHEAD/total-length checks above guarantee field bytes within bounds");
140 verify_hmac(key, &data[..inner_end], tag)?;
141
142 let inner_frame = &data[ENV_HEADER_LEN..inner_end];
143 Ok((EnvelopeFields { from_node_id, seq }, inner_frame))
144}
145
146#[cfg(test)]
147mod tests {

Calls 3

verify_hmacFunction · 0.85
lenMethod · 0.45
expectMethod · 0.45