mirror of
https://github.com/chatmail/core.git
synced 2026-04-24 17:06:28 +03:00
fix: Domain separation between securejoin auth tokens and broadcast channel secrets (#7981)
Can be reviewed commit-by-commit.
This fixes another silly thing you can do with securejoinv3: show Bob a
QR code with auth token that is a broadcast channel secret of a known
channel, then never respond. Bob will decrypt messages from the channel
and drop them because they are sent by the "wrong" sender.
This can be avoided with domain separation, instead of
encrypting/decrypting securejoinv3 messages directly with auth token,
encrypt/decrypt them with `securejoin/<auth token>` as the secret or
even `securejoinv3/<alice's fingerprint>/<auth token>`. For existing
broadcast channels we cannot do this, but for securejoinv3 that is not
released yet this looks like an improvement that avoids at least this
problem.
Credits to link2xt for noticing the problem.
This also adds Alice's fingerprint to the auth tokens, which
was pretty easy to do. I find it hard to develop an intuition for
whether this is important, or whether we will be annoyed by it in the
future.
**Note:** This means that QR code scans will not work if one of the chat
partners uses a self-compiled core between c724e2981 and merging this PR
here. This is fine; we will just have to tell the other developers to
update their self-compiled cores.
This commit is contained in:
39
src/pgp.rs
39
src/pgp.rs
@@ -590,7 +590,7 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
decrypt,
|
||||
key::{load_self_public_key, load_self_secret_key, store_self_keypair},
|
||||
key::{load_self_public_key, self_fingerprint, store_self_keypair},
|
||||
mimefactory::{render_outer_message, wrap_encrypted_part},
|
||||
test_utils::{TestContext, TestContextManager, alice_keypair, bob_keypair},
|
||||
token,
|
||||
@@ -601,11 +601,11 @@ mod tests {
|
||||
async fn decrypt_bytes(
|
||||
bytes: Vec<u8>,
|
||||
private_keys_for_decryption: &[SignedSecretKey],
|
||||
shared_secrets: &[String],
|
||||
auth_tokens_for_decryption: &[String],
|
||||
) -> Result<pgp::composed::Message<'static>> {
|
||||
let t = &TestContext::new().await;
|
||||
|
||||
for secret in shared_secrets {
|
||||
for secret in auth_tokens_for_decryption {
|
||||
token::save(t, token::Namespace::Auth, None, secret, 0).await?;
|
||||
}
|
||||
let [secret_key] = private_keys_for_decryption else {
|
||||
@@ -807,36 +807,6 @@ mod tests {
|
||||
assert_eq!(valid_signatures.len(), 0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_encrypt_decrypt_broadcast() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
|
||||
let plain = Vec::from(b"this is the secret message");
|
||||
let shared_secret = "shared secret";
|
||||
let ctext = symm_encrypt_message(
|
||||
plain.clone(),
|
||||
Some(load_self_secret_key(alice).await?),
|
||||
shared_secret,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let bob_private_keyring = crate::key::load_self_secret_keyring(bob).await?;
|
||||
let mut decrypted = decrypt_bytes(
|
||||
ctext.into(),
|
||||
&bob_private_keyring,
|
||||
&[shared_secret.to_string()],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(decrypted.as_data_vec()?, plain);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_dont_decrypt_expensive_message_happy_path() -> Result<()> {
|
||||
let s2k = StringToKey::Salted {
|
||||
@@ -883,8 +853,9 @@ mod tests {
|
||||
|
||||
let plain = Vec::from(b"this is the secret message");
|
||||
let shared_secret = "shared secret";
|
||||
let bob_fp = self_fingerprint(bob).await?;
|
||||
|
||||
let shared_secret_pw = Password::from(shared_secret.to_string());
|
||||
let shared_secret_pw = Password::from(format!("securejoin/{bob_fp}/{shared_secret}"));
|
||||
let msg = MessageBuilder::from_bytes("", plain);
|
||||
let mut rng = thread_rng();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user