diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 74f7a1b0..8a8a77d8 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -1860,7 +1860,7 @@ pub(crate) async fn create_invite_route( events: vec![pdu.to_room_event()], txn_id: base64::engine::general_purpose::URL_SAFE_NO_PAD - .encode(utils::calculate_hash(&[pdu + .encode(utils::calculate_hash([pdu .event_id() .as_bytes()])) .into(), diff --git a/src/service/rooms/state.rs b/src/service/rooms/state.rs index 7c6a25e4..485d2b8c 100644 --- a/src/service/rooms/state.rs +++ b/src/service/rooms/state.rs @@ -133,9 +133,8 @@ impl Service { let previous_shortstatehash = self.db.get_room_shortstatehash(room_id)?; - let state_hash = calculate_hash( - &state_ids_compressed.iter().map(|s| &s[..]).collect::>(), - ); + let state_hash = + calculate_hash(state_ids_compressed.iter().map(|s| &s[..])); let (shortstatehash, already_existed) = services().rooms.short.get_or_create_shortstatehash(&state_hash)?; diff --git a/src/service/rooms/state_compressor.rs b/src/service/rooms/state_compressor.rs index f6a7d407..a545cf5e 100644 --- a/src/service/rooms/state_compressor.rs +++ b/src/service/rooms/state_compressor.rs @@ -283,10 +283,7 @@ impl Service { services().rooms.state.get_room_shortstatehash(room_id)?; let state_hash = utils::calculate_hash( - &new_state_ids_compressed - .iter() - .map(|bytes| &bytes[..]) - .collect::>(), + new_state_ids_compressed.iter().map(|bytes| &bytes[..]), ); let (new_shortstatehash, already_existed) = diff --git a/src/service/sending.rs b/src/service/sending.rs index bc4c33d6..c486701e 100644 --- a/src/service/sending.rs +++ b/src/service/sending.rs @@ -755,17 +755,10 @@ async fn handle_appservice_event( appservice::event::push_events::v1::Request { events: pdu_jsons, txn_id: general_purpose::URL_SAFE_NO_PAD - .encode(calculate_hash( - &events - .iter() - .map(|e| match e { - SendingEventType::Edu(b) => { - b.json().get().as_bytes() - } - SendingEventType::Pdu(b) => b.as_bytes(), - }) - .collect::>(), - )) + .encode(calculate_hash(events.iter().map(|e| match e { + SendingEventType::Edu(b) => b.json().get().as_bytes(), + SendingEventType::Pdu(b) => b.as_bytes(), + }))) .into(), }, ) @@ -902,17 +895,10 @@ async fn handle_federation_event( edus: edu_jsons, origin_server_ts: MilliSecondsSinceUnixEpoch::now(), transaction_id: general_purpose::URL_SAFE_NO_PAD - .encode(calculate_hash( - &events - .iter() - .map(|e| match e { - SendingEventType::Edu(b) => { - b.json().get().as_bytes() - } - SendingEventType::Pdu(b) => b.as_bytes(), - }) - .collect::>(), - )) + .encode(calculate_hash(events.iter().map(|e| match e { + SendingEventType::Edu(b) => b.json().get().as_bytes(), + SendingEventType::Pdu(b) => b.as_bytes(), + }))) .into(), }, false, diff --git a/src/utils.rs b/src/utils.rs index 42c15f88..30be1bad 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -106,9 +106,18 @@ where } #[tracing::instrument(skip(keys))] -pub(crate) fn calculate_hash(keys: &[&[u8]]) -> Vec { - // We only hash the pdu's event ids, not the whole pdu - let bytes = keys.join(&0xFF); +pub(crate) fn calculate_hash<'a, I, T>(keys: I) -> Vec +where + I: IntoIterator, + T: AsRef<[u8]>, +{ + let mut bytes = Vec::new(); + for (i, key) in keys.into_iter().enumerate() { + if i != 0 { + bytes.push(0xFF); + } + bytes.extend_from_slice(key.as_ref()); + } let hash = digest::digest(&digest::SHA256, &bytes); hash.as_ref().to_owned() }