diff --git a/rust/protocol/src/consts.rs b/rust/protocol/src/consts.rs index 6b0b4dbab5..f911122dad 100644 --- a/rust/protocol/src/consts.rs +++ b/rust/protocol/src/consts.rs @@ -1,10 +1,34 @@ // -// Copyright 2020 Signal Messenger, LLC. +// Copyright 2020-2022 Signal Messenger, LLC. // SPDX-License-Identifier: AGPL-3.0-only // -pub const MAX_FORWARD_JUMPS: usize = 25_000; -pub const MAX_MESSAGE_KEYS: usize = 2000; -pub const MAX_RECEIVER_CHAINS: usize = 5; -pub const ARCHIVED_STATES_MAX_LENGTH: usize = 40; -pub const MAX_SENDER_KEY_STATES: usize = 5; +#![warn(missing_docs)] + +//! Magic numbers. + +/// Various positive integers bounding the maximum size of other data structures. +pub mod limits { + /// The maximum number of encrypted messages that the client chain which decrypts Signal + /// messages in a [Double Ratchet] instance can retrieve at once (tracked in + /// [crate::proto::storage::session_structure::chain::ChainKey::index] as well as a separate + /// `counter`). + /// + /// [Double Ratchet]: https://signal.org/docs/specifications/doubleratchet/ + pub const MAX_FORWARD_JUMPS: usize = 25_000; + /// The maximum number of per-message keys that can be retained to decrypt messages within + /// a specific chain from `message_keys` in [crate::proto::storage::session_structure::Chain]. + pub const MAX_MESSAGE_KEYS: usize = 2000; + /// The maximum number of temporary backup chains to allow for `receiver_chains` in + /// [crate::proto::storage::SessionStructure]. These backup chains corresponds to the [Sesame] + /// protocol for syncing a Double Ratchet chain between two users. + /// + /// [Sesame]: https://signal.org/docs/specifications/sesame/#server + pub const MAX_RECEIVER_CHAINS: usize = 5; + /// The maximum number of sessions allowed for + /// [crate::proto::storage::RecordStructure::previous_sessions]. + pub const ARCHIVED_STATES_MAX_LENGTH: usize = 40; + /// The maximum number of sender key states allowed for + /// [crate::proto::storage::SenderKeyRecordStructure::sender_key_states]. + pub const MAX_SENDER_KEY_STATES: usize = 5; +} diff --git a/rust/protocol/src/group_cipher.rs b/rust/protocol/src/group_cipher.rs index a52d32db6a..f62ab4009b 100644 --- a/rust/protocol/src/group_cipher.rs +++ b/rust/protocol/src/group_cipher.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0-only // -use crate::consts; +use crate::consts::limits::MAX_FORWARD_JUMPS; use crate::crypto; use crate::{ @@ -101,11 +101,11 @@ fn get_sender_key( } let jump = (iteration - current_iteration) as usize; - if jump > consts::MAX_FORWARD_JUMPS { + if jump > MAX_FORWARD_JUMPS { log::error!( "SenderKey distribution {} Exceeded future message limit: {}, current iteration: {})", distribution_id, - consts::MAX_FORWARD_JUMPS, + MAX_FORWARD_JUMPS, current_iteration ); return Err(SignalProtocolError::InvalidMessage( diff --git a/rust/protocol/src/sender_keys.rs b/rust/protocol/src/sender_keys.rs index 359d7dc05d..51d8ebf4df 100644 --- a/rust/protocol/src/sender_keys.rs +++ b/rust/protocol/src/sender_keys.rs @@ -9,7 +9,7 @@ use std::convert::TryFrom; use itertools::Itertools; use prost::Message; -use crate::consts; +use crate::consts::limits::{MAX_MESSAGE_KEYS, MAX_SENDER_KEY_STATES}; use crate::crypto::hmac_sha256; use crate::proto::storage as storage_proto; use crate::{PrivateKey, PublicKey, SignalProtocolError}; @@ -211,7 +211,7 @@ impl SenderKeyState { self.state .sender_message_keys .push(sender_message_key.as_protobuf()); - while self.state.sender_message_keys.len() > consts::MAX_MESSAGE_KEYS { + while self.state.sender_message_keys.len() > MAX_MESSAGE_KEYS { self.state.sender_message_keys.remove(0); } } @@ -239,7 +239,7 @@ pub struct SenderKeyRecord { impl SenderKeyRecord { pub(crate) fn new_empty() -> Self { Self { - states: VecDeque::with_capacity(consts::MAX_SENDER_KEY_STATES), + states: VecDeque::with_capacity(MAX_SENDER_KEY_STATES), } } @@ -316,7 +316,7 @@ impl SenderKeyRecord { Some(state) => state, }; - while self.states.len() >= consts::MAX_SENDER_KEY_STATES { + while self.states.len() >= MAX_SENDER_KEY_STATES { self.states.pop_back(); } @@ -491,8 +491,7 @@ mod sender_key_record_add_sender_key_state_tests { #[test] fn when_exceed_maximum_states_then_oldest_is_ejected() { assert_eq!( - 5, - consts::MAX_SENDER_KEY_STATES, + 5, MAX_SENDER_KEY_STATES, "Test written to expect this limit" ); diff --git a/rust/protocol/src/session_cipher.rs b/rust/protocol/src/session_cipher.rs index b6733581a4..b430c0da6f 100644 --- a/rust/protocol/src/session_cipher.rs +++ b/rust/protocol/src/session_cipher.rs @@ -9,7 +9,7 @@ use crate::{ SessionStore, SignalMessage, SignalProtocolError, SignedPreKeyStore, }; -use crate::consts::MAX_FORWARD_JUMPS; +use crate::consts::limits::MAX_FORWARD_JUMPS; use crate::crypto; use crate::ratchet::{ChainKey, MessageKeys}; use crate::session; diff --git a/rust/protocol/src/state/session.rs b/rust/protocol/src/state/session.rs index 2cbfd4c902..99875b0f28 100644 --- a/rust/protocol/src/state/session.rs +++ b/rust/protocol/src/state/session.rs @@ -1,5 +1,5 @@ // -// Copyright 2020 Signal Messenger, LLC. +// Copyright 2020-2022 Signal Messenger, LLC. // SPDX-License-Identifier: AGPL-3.0-only // @@ -12,7 +12,7 @@ use subtle::ConstantTimeEq; use crate::ratchet::{ChainKey, MessageKeys, RootKey}; use crate::{IdentityKey, KeyPair, PrivateKey, PublicKey, SignalProtocolError}; -use crate::consts; +use crate::consts::limits::{ARCHIVED_STATES_MAX_LENGTH, MAX_MESSAGE_KEYS, MAX_RECEIVER_CHAINS}; use crate::proto::storage::session_structure; use crate::proto::storage::{RecordStructure, SessionStructure}; use crate::state::{PreKeyId, SignedPreKeyId}; @@ -236,7 +236,7 @@ impl SessionState { self.session.receiver_chains.push(chain); - if self.session.receiver_chains.len() > consts::MAX_RECEIVER_CHAINS { + if self.session.receiver_chains.len() > MAX_RECEIVER_CHAINS { log::info!( "Trimming excessive receiver_chain for session with base key {}, chain count: {}", self.sender_ratchet_key_for_logging() @@ -367,7 +367,7 @@ impl SessionState { let mut updated_chain = chain_and_index.0; updated_chain.message_keys.insert(0, new_keys); - if updated_chain.message_keys.len() > consts::MAX_MESSAGE_KEYS { + if updated_chain.message_keys.len() > MAX_MESSAGE_KEYS { updated_chain.message_keys.pop(); } @@ -578,7 +578,7 @@ impl SessionRecord { // A non-fallible version of archive_current_state. fn archive_current_state_inner(&mut self) { if let Some(current_session) = self.current_session.take() { - if self.previous_sessions.len() >= consts::ARCHIVED_STATES_MAX_LENGTH { + if self.previous_sessions.len() >= ARCHIVED_STATES_MAX_LENGTH { self.previous_sessions.pop(); } self.previous_sessions