Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow panics, unreachables, and expects using clippy lints #205

Merged
merged 2 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ unused_qualifications = "deny"
rust_2018_idioms = "deny"

[lints.clippy]
panic = "deny"
unreachable = "deny"
expect_used = "deny"
unwrap_used = "deny"
mem_forget = "deny"

Expand Down
2 changes: 2 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
allow-unwrap-in-tests = true
allow-expect-in-tests = true
allow-panic-in-tests = true
4 changes: 3 additions & 1 deletion src/cipher/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ impl ExpandedKeys {

let hkdf: Hkdf<Sha256> = Hkdf::new(Some(&[0]), message_key);

hkdf.expand(info, &mut expanded_keys).expect("Can't expand message key");
#[allow(clippy::expect_used)]
hkdf.expand(info, &mut expanded_keys)
.expect("HKDF should be able to expand a 32 byte key into 80 bytes");

Self(Box::new(expanded_keys))
}
Expand Down
4 changes: 3 additions & 1 deletion src/cipher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ impl Cipher {
// large HMAC key while the Olm spec defines a 32-byte one instead.
//
// https://gitlab.matrix.org/matrix-org/olm/-/blob/master/docs/olm.md#version-1
HmacSha256::new_from_slice(self.keys.mac_key()).expect("Invalid HMAC key size")
#[allow(clippy::expect_used)]
HmacSha256::new_from_slice(self.keys.mac_key())
.expect("We should be able to create a HmacSha256 from a 32 byte key")
}

/// Encrypts the given plaintext using this [`Cipher`] and returns the
Expand Down
14 changes: 10 additions & 4 deletions src/ecies/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ impl EciesNonce {
let mut nonce = [0u8; 12];
nonce.copy_from_slice(&current.to_le_bytes()[..12]);

#[allow(clippy::expect_used)]
Nonce::from_exact_iter(nonce)
.expect("We should be able to construct the correct nonce from a 12 byte slice")
}
Expand Down Expand Up @@ -382,8 +383,10 @@ impl EstablishedEcies {

let info = Self::get_check_code_info(info, role, our_public_key, their_public_key);

kdf.expand(info.as_bytes(), bytes.as_mut_slice())
.expect("We should be able to expand the shared secret into a 32 byte key.");
#[allow(clippy::expect_used)]
kdf.expand(info.as_bytes(), bytes.as_mut_slice()).expect(
"We should be able to expand the 32-byte long shared secret into a 32 byte key.",
);

CheckCode { bytes }
}
Expand All @@ -392,8 +395,10 @@ impl EstablishedEcies {
let mut key = Box::new([0u8; 32]);
let kdf: Hkdf<Sha512> = Hkdf::new(None, shared_secret.as_bytes());

kdf.expand(info.as_bytes(), key.as_mut_slice())
.expect("We should be able to expand the shared secret into a 32 byte key.");
#[allow(clippy::expect_used)]
kdf.expand(info.as_bytes(), key.as_mut_slice()).expect(
"We should be able to expand the 32-byte long shared secret into a 32 byte key.",
);

key
}
Expand Down Expand Up @@ -498,6 +503,7 @@ impl EstablishedEcies {
let nonce = self.encryption_nonce.get();

let cipher = ChaCha20Poly1305::new(self.encryption_key());
#[allow(clippy::expect_used)]
let ciphertext = cipher.encrypt(&nonce, plaintext).expect(
"We should always be able to encrypt a message since we provide the correct nonce",
);
Expand Down
1 change: 1 addition & 0 deletions src/megolm/inbound_group_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ impl InboundGroupSession {
//
// After that we compare the raw ratchet bytes in constant time.

#[allow(clippy::unreachable)]
if self.config != other.config || self.signing_key != other.signing_key {
// Short circuit if session configs differ or the signing keys
// differ. This is comparing public key material.
Expand Down
6 changes: 4 additions & 2 deletions src/megolm/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,9 @@ impl MegolmMessage {
ciphertext,
message_index,
mac: Mac([0u8; Mac::LENGTH]).into(),
#[allow(clippy::expect_used)]
signature: Ed25519Signature::from_slice(&[0; Ed25519Signature::LENGTH])
.expect("Can't create an empty signature"),
.expect("We should be able to create a signature from an empty zero slice"),
};

Self::encrypt_helper(cipher, signing_key, message)
Expand All @@ -199,8 +200,9 @@ impl MegolmMessage {
ciphertext,
message_index,
mac: [0u8; Mac::TRUNCATED_LEN].into(),
#[allow(clippy::expect_used)]
signature: Ed25519Signature::from_slice(&[0; Ed25519Signature::LENGTH])
.expect("Can't create an empty signature"),
.expect("We should be able to create a signature from an empty zero slice"),
};

Self::encrypt_helper(cipher, signing_key, message)
Expand Down
12 changes: 8 additions & 4 deletions src/megolm/ratchet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ impl<'d> Deserialize<'d> for RatchetBytes {
struct RatchetPart<'a>(&'a mut [u8]);

impl RatchetPart<'_> {
fn hash(&self, seed: &[u8]) -> CtOutput<Hmac<Sha256>> {
let mut hmac = Hmac::<Sha256>::new_from_slice(self.0).expect("Can't create a HMAC object");
fn hash(&self, seed: &[u8; 1]) -> CtOutput<Hmac<Sha256>> {
#[allow(clippy::expect_used)]
let mut hmac = Hmac::<Sha256>::new_from_slice(self.0)
.expect("We should be able to create a HMAC object from a ratchet part");
hmac.update(seed);

hmac.finalize()
Expand All @@ -107,22 +109,24 @@ struct RatchetParts<'a> {

impl<'a> RatchetParts<'a> {
fn update(&'a mut self, from: usize, to: usize) {
#[allow(clippy::unreachable)]
let from = match from {
0 => &self.r_0,
1 => &self.r_1,
2 => &self.r_2,
3 => &self.r_3,
_ => unreachable!(),
_ => unreachable!("We only have 4 ratchet parts"),
};

let result = from.hash(ADVANCEMENT_SEEDS[to]);

#[allow(clippy::unreachable)]
let to = match to {
0 => &mut self.r_0,
1 => &mut self.r_1,
2 => &mut self.r_2,
3 => &mut self.r_3,
_ => unreachable!(),
_ => unreachable!("We only have 4 ratchet parts"),
};

to.update(&result.into_bytes());
Expand Down
3 changes: 2 additions & 1 deletion src/megolm/session_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,9 @@ impl SessionKey {

Self {
session_key,
#[allow(clippy::expect_used)]
signature: Ed25519Signature::from_slice(&[0; Ed25519Signature::LENGTH])
.expect("Can't create an empty signature"),
.expect("We should be able to create a signature from an empty zero slice"),
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/olm/messages/pre_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,10 @@ impl PreKeyMessage {
let mut output: Vec<u8> = vec![0u8; message.encoded_len() + 1];
output[0] = Self::VERSION;

#[allow(clippy::expect_used)]
message
.encode(&mut output[1..].as_mut())
.expect("Couldn't encode our message into a protobuf");
.expect("We should be able to encode a pre-key message into protobuf.");

output
}
Expand Down
11 changes: 7 additions & 4 deletions src/olm/session/chain_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ const MESSAGE_KEY_SEED: &[u8; 1] = b"\x01";
const ADVANCEMENT_SEED: &[u8; 1] = b"\x02";

fn expand_chain_key(key: &[u8; 32]) -> Box<[u8; 32]> {
let mut mac =
Hmac::<Sha256>::new_from_slice(key).expect("Can't create HmacSha256 from the key");
#[allow(clippy::expect_used)]
let mut mac = Hmac::<Sha256>::new_from_slice(key)
.expect("We should be able to create a HMAC object from a 32-byte key");
mac.update(MESSAGE_KEY_SEED);

let mut output = mac.finalize().into_bytes();
Expand All @@ -41,8 +42,10 @@ fn expand_chain_key(key: &[u8; 32]) -> Box<[u8; 32]> {
}

fn advance(key: &[u8; 32]) -> CtOutput<Hmac<Sha256>> {
let mut mac = Hmac::<Sha256>::new_from_slice(key)
.expect("Couldn't create a valid Hmac object to advance the ratchet");
#[allow(clippy::expect_used)]
let mut mac = Hmac::<Sha256>::new_from_slice(key).expect(
"We should be able to create a HMAC object from a 32-byte key to advance the ratchet",
);
mac.update(ADVANCEMENT_SEED);

mac.finalize()
Expand Down
4 changes: 3 additions & 1 deletion src/olm/session/root_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ fn kdf(
let hkdf: Hkdf<Sha256> = Hkdf::new(Some(root_key.as_ref()), shared_secret.as_bytes());
let mut output = Box::new([0u8; 64]);

hkdf.expand(ADVANCEMENT_SEED, output.as_mut_slice()).expect("Can't expand");
#[allow(clippy::expect_used)]
hkdf.expand(ADVANCEMENT_SEED, output.as_mut_slice())
.expect("We should be able to expand the shared secret.");

output
}
Expand Down
3 changes: 2 additions & 1 deletion src/olm/shared_secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ fn expand(shared_secret: &[u8; 96]) -> (Box<[u8; 32]>, Box<[u8; 32]>) {

let mut expanded_keys = [0u8; 64];

#[allow(clippy::expect_used)]
hkdf.expand(b"OLM_ROOT", &mut expanded_keys)
.expect("Can't expand the shared 3DH secret into the Olm root");
.expect("We should be able to expand the shared 3DH secret into the Olm root");

root_key.copy_from_slice(&expanded_keys[0..32]);
chain_key.copy_from_slice(&expanded_keys[32..64]);
Expand Down
2 changes: 2 additions & 0 deletions src/pk_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ impl PkDecryption {
let expanded_keys = ExpandedKeys::new_helper(shared_secret.as_bytes(), b"");
let cipher_keys = CipherKeys::from_expanded_keys(expanded_keys);

#[allow(clippy::expect_used)]
let hmac = HmacSha256::new_from_slice(cipher_keys.mac_key())
.expect("We should be able to create a Hmac object from a 32 byte key");

Expand Down Expand Up @@ -304,6 +305,7 @@ impl PkEncryption {
let cipher = Aes256CbcEnc::new(cipher_keys.aes_key(), cipher_keys.iv());
let ciphertext = cipher.encrypt_padded_vec_mut::<Pkcs7>(message);

#[allow(clippy::expect_used)]
let hmac = HmacSha256::new_from_slice(cipher_keys.mac_key())
.expect("We should be able to create a Hmac object from a 32 byte key");

Expand Down
10 changes: 8 additions & 2 deletions src/sas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ impl EstablishedSas {
/// use the same info string.
pub fn bytes(&self, info: &str) -> SasBytes {
let mut bytes = [0u8; 6];
#[allow(clippy::expect_used)]
let byte_vec =
self.bytes_raw(info, 6).expect("HKDF should always be able to generate 6 bytes");

Expand Down Expand Up @@ -407,14 +408,19 @@ impl EstablishedSas {
let mut mac_key = Box::new([0u8; 32]);
let hkdf = self.get_hkdf();

hkdf.expand(info.as_bytes(), mac_key.as_mut_slice()).expect("Can't expand the MAC key");
#[allow(clippy::expect_used)]
hkdf.expand(info.as_bytes(), mac_key.as_mut_slice())
.expect("We should be able to expand the shared SAS secret into a MAC key");

mac_key
}

fn get_mac(&self, info: &str) -> Hmac<Sha256> {
let mac_key = self.get_mac_key(info);
Hmac::<Sha256>::new_from_slice(mac_key.as_slice()).expect("Can't create a HMAC object")

#[allow(clippy::expect_used)]
Hmac::<Sha256>::new_from_slice(mac_key.as_slice())
.expect("We should be able to create a HMAC object from a 32-byte slice")
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/utilities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ pub(crate) fn unpickle<T: for<'b> serde::Deserialize<'b>>(
pub(crate) fn pickle<T: serde::Serialize>(thing: &T, pickle_key: &[u8; 32]) -> String {
use zeroize::Zeroize;

let mut json = serde_json::to_vec(&thing).expect("Can't serialize a pickled object");
#[allow(clippy::expect_used)]
let mut json = serde_json::to_vec(&thing)
.expect("A pickled object should always be serializable into JSON");
let cipher = crate::cipher::Cipher::new_pickle(pickle_key);

let ciphertext = cipher.encrypt_pickle(json.as_slice());
Expand Down