mirror of
https://github.com/chatmail/core.git
synced 2026-04-26 01:46:34 +03:00
feat: Increase secret size to 256 bits of entropy
This is for quantumn computers. When trying to break AES, quantumn computers give a square-root speedup, i.e. the 144 bits of entropy would take as many queries as breaking 72 bits of entropy on a normal computer. This neglects e.g. the costs of quantumn circuits and quantumn error correction [1], so, 144 bits entropy would actually have been fine, but in order to be on the very safe side and so that noone can complain, let's increase it to 256 bits. [1]: https://csrc.nist.gov/csrc/media/Events/2024/fifth-pqc-standardization-conference/documents/papers/on-practical-cost-of-grover.pdf
This commit is contained in:
@@ -43,9 +43,9 @@ use crate::smtp::send_msg_to_smtp;
|
||||
use crate::stock_str;
|
||||
use crate::sync::{self, Sync::*, SyncData};
|
||||
use crate::tools::{
|
||||
IsNoneOrEmpty, SystemTime, buf_compress, create_id, create_outgoing_rfc724_mid,
|
||||
create_smeared_timestamp, create_smeared_timestamps, get_abs_path, gm2local_offset,
|
||||
smeared_time, time, truncate_msg_text,
|
||||
IsNoneOrEmpty, SystemTime, buf_compress, create_broadcast_shared_secret, create_id,
|
||||
create_outgoing_rfc724_mid, create_smeared_timestamp, create_smeared_timestamps, get_abs_path,
|
||||
gm2local_offset, smeared_time, time, truncate_msg_text,
|
||||
};
|
||||
use crate::webxdc::StatusUpdateSerial;
|
||||
use crate::{chatlist_events, imap};
|
||||
@@ -3794,7 +3794,7 @@ pub async fn create_group_ex(
|
||||
/// Returns the created chat's id.
|
||||
pub async fn create_broadcast(context: &Context, chat_name: String) -> Result<ChatId> {
|
||||
let grpid = create_id();
|
||||
let secret = create_id();
|
||||
let secret = create_broadcast_shared_secret();
|
||||
create_broadcast_ex(context, Sync, grpid, chat_name, secret).await
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ use crate::message::Message;
|
||||
use crate::net::http::post_empty;
|
||||
use crate::net::proxy::{DEFAULT_SOCKS_PORT, ProxyConfig};
|
||||
use crate::token;
|
||||
use crate::tools::validate_id;
|
||||
use crate::tools::{validate_broadcast_shared_secret, validate_id};
|
||||
|
||||
const OPENPGP4FPR_SCHEME: &str = "OPENPGP4FPR:"; // yes: uppercase
|
||||
const IDELTACHAT_SCHEME: &str = "https://i.delta.chat/#";
|
||||
@@ -459,7 +459,7 @@ async fn decode_openpgp(context: &Context, qr: &str) -> Result<Qr> {
|
||||
.map(|s| s.to_string());
|
||||
let broadcast_shared_secret = param
|
||||
.get("b")
|
||||
.filter(|&s| validate_id(s))
|
||||
.filter(|&s| validate_broadcast_shared_secret(s))
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let grpname = if grpid.is_some() {
|
||||
|
||||
@@ -44,7 +44,7 @@ use crate::securejoin::{self, handle_securejoin_handshake, observe_securejoin_on
|
||||
use crate::simplify;
|
||||
use crate::stock_str;
|
||||
use crate::sync::Sync::*;
|
||||
use crate::tools::{self, buf_compress, create_id, remove_subject_prefix};
|
||||
use crate::tools::{self, buf_compress, create_broadcast_shared_secret, remove_subject_prefix};
|
||||
use crate::{chatlist_events, ensure_and_debug_assert, ensure_and_debug_assert_eq, location};
|
||||
use crate::{contact, imap};
|
||||
|
||||
@@ -1566,7 +1566,7 @@ async fn do_chat_assignment(
|
||||
} else {
|
||||
let name =
|
||||
compute_mailinglist_name(mailinglist_header, &listid, mime_parser);
|
||||
let secret = create_id();
|
||||
let secret = create_broadcast_shared_secret();
|
||||
chat::create_broadcast_ex(context, Nosync, listid, name, secret).await?
|
||||
},
|
||||
);
|
||||
|
||||
24
src/tools.rs
24
src/tools.rs
@@ -300,6 +300,25 @@ pub(crate) fn create_id() -> String {
|
||||
base64::engine::general_purpose::URL_SAFE.encode(arr)
|
||||
}
|
||||
|
||||
/// Generate a shared secret for a broadcast channel, consisting of 43 characters.
|
||||
///
|
||||
/// The string generated by this function has 258 bits of entropy
|
||||
/// and is returned as 43 Base64 characters, each containing 6 bits of entropy.
|
||||
/// 256 is chosen because we may switch to AES-256 keys in the future,
|
||||
/// and so that the shared secret definitely won't be the weak spot.
|
||||
pub(crate) fn create_broadcast_shared_secret() -> String {
|
||||
// ThreadRng implements CryptoRng trait and is supposed to be cryptographically secure.
|
||||
let mut rng = thread_rng();
|
||||
|
||||
// Generate 264 random bits.
|
||||
let mut arr = [0u8; 33];
|
||||
rng.fill(&mut arr[..]);
|
||||
|
||||
let mut res = base64::engine::general_purpose::URL_SAFE.encode(arr);
|
||||
res.truncate(43);
|
||||
res
|
||||
}
|
||||
|
||||
/// Returns true if given string is a valid ID.
|
||||
///
|
||||
/// All IDs generated with `create_id()` should be considered valid.
|
||||
@@ -308,6 +327,11 @@ pub(crate) fn validate_id(s: &str) -> bool {
|
||||
s.chars().all(|c| alphabet.contains(c)) && s.len() > 10 && s.len() <= 32
|
||||
}
|
||||
|
||||
pub(crate) fn validate_broadcast_shared_secret(s: &str) -> bool {
|
||||
let alphabet = base64::alphabet::URL_SAFE.as_str();
|
||||
s.chars().all(|c| alphabet.contains(c)) && s.len() == 43
|
||||
}
|
||||
|
||||
/// Function generates a Message-ID that can be used for a new outgoing message.
|
||||
/// - this function is called for all outgoing messages.
|
||||
/// - the message ID should be globally unique
|
||||
|
||||
Reference in New Issue
Block a user