From c3d4c438e6e39ec4a147004261e7b985d75afac3 Mon Sep 17 00:00:00 2001 From: Hocuri Date: Wed, 21 Jan 2026 16:19:16 +0100 Subject: [PATCH] fix: Don't leak cryptographic identity by signing vc-request-pubkey --- benches/decrypting.rs | 2 +- src/e2ee.rs | 7 ++++++- src/mimefactory.rs | 7 +++++-- src/pgp.rs | 10 ++++++---- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/benches/decrypting.rs b/benches/decrypting.rs index 435850782..6dd7e89fa 100644 --- a/benches/decrypting.rs +++ b/benches/decrypting.rs @@ -83,7 +83,7 @@ fn criterion_benchmark(c: &mut Criterion) { let secret = secrets[NUM_SECRETS / 2].clone(); symm_encrypt_message( plain.clone(), - create_dummy_keypair("alice@example.org").unwrap().secret, + Some(create_dummy_keypair("alice@example.org").unwrap().secret), black_box(&secret), true, ) diff --git a/src/e2ee.rs b/src/e2ee.rs index 5c3ce91dc..e98785bd2 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -70,8 +70,13 @@ impl EncryptHelper { shared_secret: &str, mail_to_encrypt: MimePart<'static>, compress: bool, + sign: bool, ) -> Result { - let sign_key = load_self_secret_key(context).await?; + let sign_key = if sign { + Some(load_self_secret_key(context).await?) + } else { + None + }; let mut raw_message = Vec::new(); let cursor = Cursor::new(&mut raw_message); diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 0034a1db5..22af1b2bf 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -1169,8 +1169,9 @@ impl MimeFactory { } let encrypted = if let Some(shared_secret) = shared_secret { + let sign = true; encrypt_helper - .encrypt_symmetrically(context, &shared_secret, message, compress) + .encrypt_symmetrically(context, &shared_secret, message, compress, sign) .await? } else { // Asymmetric encryption @@ -2366,8 +2367,10 @@ pub(crate) async fn render_symm_encrypted_securejoin_message( // there are no compression side channels // leaking information about the tokens. let compress = false; + // Only sign the message if we attach the pubkey. + let sign = attach_self_pubkey; let encrypted = encrypt_helper - .encrypt_symmetrically(context, auth, message, compress) // TODO this also signs the message. vc-request-pubkey shouldn't be signed. + .encrypt_symmetrically(context, auth, message, compress, sign) .await?; wrap_encrypted_part(encrypted) diff --git a/src/pgp.rs b/src/pgp.rs index bcf888873..28f7ba9c4 100644 --- a/src/pgp.rs +++ b/src/pgp.rs @@ -480,7 +480,7 @@ pub async fn symm_encrypt_autocrypt_setup(passphrase: &str, plain: Vec) -> R /// `shared secret` is the secret that will be used for symmetric encryption. pub async fn symm_encrypt_message( plain: Vec, - private_key_for_signing: SignedSecretKey, + private_key_for_signing: Option, shared_secret: &str, compress: bool, ) -> Result { @@ -503,8 +503,10 @@ pub async fn symm_encrypt_message( ); msg.encrypt_with_password(&mut rng, s2k, &shared_secret)?; - let hash_algorithm = private_key_for_signing.hash_alg(); - msg.sign(&*private_key_for_signing, Password::empty(), hash_algorithm); + if let Some(private_key_for_signing) = private_key_for_signing.as_deref() { + let hash_algorithm = private_key_for_signing.hash_alg(); + msg.sign(private_key_for_signing, Password::empty(), hash_algorithm); + } if compress { msg.compression(CompressionAlgorithm::ZLIB); } @@ -737,7 +739,7 @@ mod tests { let shared_secret = "shared secret"; let ctext = symm_encrypt_message( plain.clone(), - load_self_secret_key(alice).await?, + Some(load_self_secret_key(alice).await?), shared_secret, true, )