diff --git a/CHANGELOG.md b/CHANGELOG.md index 3198bc71e..106868563 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - don't watch Sent folder by default #3025 - use webxdc app name in chatlist/quotes/replies etc. #3027 - refactorings #3023 +- remove direct dependency on `byteorder` crate #3031 ## 1.72.0 diff --git a/Cargo.lock b/Cargo.lock index 791387c4f..a0016211f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1077,7 +1077,6 @@ dependencies = [ "backtrace", "base64 0.13.0", "bitflags", - "byteorder", "chrono", "criterion", "deltachat_derive", diff --git a/Cargo.toml b/Cargo.toml index adb060993..abfd18cb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,6 @@ async-trait = "0.1" backtrace = "0.3" base64 = "0.13" bitflags = "1.3" -byteorder = "1.3" chrono = "0.4" dirs = { version = "4", optional=true } email = { git = "https://github.com/deltachat/rust-email", branch = "master" } diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 4c3a1e48a..2824b6e11 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -195,44 +195,26 @@ async fn maybe_warn_on_outdated(context: &Context, now: i64, approx_compile_time } /* Message-ID tools */ + +/// Generate an ID. The generated ID should be as short and as unique as possible: +/// - short, because it may also used as part of Message-ID headers or in QR codes +/// - unique as two IDs generated on two devices should not be the same. However, collisions are not world-wide but only by the few contacts. +/// IDs generated by this function are 66 bit wide and are returned as 11 base64 characters. +/// +/// Additional information when used as a message-id or group-id: +/// - for OUTGOING messages this ID is written to the header as `Chat-Group-ID:` and is added to the message ID as Gr..@ +/// - for INCOMING messages, the ID is taken from the Chat-Group-ID-header or from the Message-ID in the In-Reply-To: or References:-Header +/// - the group-id should be a string with the characters [a-zA-Z0-9\-_] pub(crate) fn dc_create_id() -> String { - /* generate an id. the generated ID should be as short and as unique as possible: - - short, because it may also used as part of Message-ID headers or in QR codes - - unique as two IDs generated on two devices should not be the same. However, collisions are not world-wide but only by the few contacts. - IDs generated by this function are 66 bit wide and are returned as 11 base64 characters. - If possible, RNG of OpenSSL is used. - - Additional information when used as a message-id or group-id: - - for OUTGOING messages this ID is written to the header as `Chat-Group-ID:` and is added to the message ID as Gr..@ - - for INCOMING messages, the ID is taken from the Chat-Group-ID-header or from the Message-ID in the In-Reply-To: or References:-Header - - the group-id should be a string with the characters [a-zA-Z0-9\-_] */ - + // ThreadRng implements CryptoRng trait and is supposed to be cryptographically secure. let mut rng = thread_rng(); - let buf: [u32; 3] = [rng.gen(), rng.gen(), rng.gen()]; - encode_66bits_as_base64(buf[0usize], buf[1usize], buf[2usize]) -} + // Generate 72 random bits. + let mut arr = [0u8; 9]; + rng.fill(&mut arr[..]); -/// Encode 66 bits as a base64 string. -/// This is useful for ID generating with short strings as we save 5 character -/// in each id compared to 64 bit hex encoding. For a typical group ID, these -/// are 10 characters (grpid+msgid): -/// hex: 64 bit, 4 bits/character, length = 64/4 = 16 characters -/// base64: 64 bit, 6 bits/character, length = 64/6 = 11 characters (plus 2 additional bits) -/// Only the lower 2 bits of `fill` are used. -fn encode_66bits_as_base64(v1: u32, v2: u32, fill: u32) -> String { - use byteorder::{BigEndian, WriteBytesExt}; - - let mut wrapped_writer = Vec::new(); - { - let mut enc = base64::write::EncoderWriter::new(&mut wrapped_writer, base64::URL_SAFE); - enc.write_u32::(v1).unwrap(); - enc.write_u32::(v2).unwrap(); - enc.write_u8(((fill & 0x3) as u8) << 6).unwrap(); - enc.finish().unwrap(); - } - assert_eq!(wrapped_writer.pop(), Some(b'A')); // Remove last "A" - String::from_utf8(wrapped_writer).unwrap() + // Take 11 base64 characters containing 66 random bits. + base64::encode(&arr).chars().take(11).collect() } /// Function generates a Message-ID that can be used for a new outgoing message. @@ -780,26 +762,6 @@ Hop: From: hq5.example.org; By: hq5.example.org; Date: Mon, 27 Dec 2021 11:21:22 assert_eq!(buf.len(), 11); } - #[test] - fn test_encode_66bits_as_base64() { - assert_eq!( - encode_66bits_as_base64(0x01234567, 0x89abcdef, 0), - "ASNFZ4mrze8" - ); - assert_eq!( - encode_66bits_as_base64(0x01234567, 0x89abcdef, 1), - "ASNFZ4mrze9" - ); - assert_eq!( - encode_66bits_as_base64(0x01234567, 0x89abcdef, 2), - "ASNFZ4mrze-" - ); - assert_eq!( - encode_66bits_as_base64(0x01234567, 0x89abcdef, 3), - "ASNFZ4mrze_" - ); - } - #[test] fn test_dc_extract_grpid_from_rfc724_mid() { // Should return None if we pass invalid mid