fix: Don't leak cryptographic identity by signing vc-request-pubkey

This commit is contained in:
Hocuri
2026-01-21 16:19:16 +01:00
parent c9bd5d09c2
commit c3d4c438e6
4 changed files with 18 additions and 8 deletions

View File

@@ -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,
)

View File

@@ -70,8 +70,13 @@ impl EncryptHelper {
shared_secret: &str,
mail_to_encrypt: MimePart<'static>,
compress: bool,
sign: bool,
) -> Result<String> {
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);

View File

@@ -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)

View File

@@ -480,7 +480,7 @@ pub async fn symm_encrypt_autocrypt_setup(passphrase: &str, plain: Vec<u8>) -> R
/// `shared secret` is the secret that will be used for symmetric encryption.
pub async fn symm_encrypt_message(
plain: Vec<u8>,
private_key_for_signing: SignedSecretKey,
private_key_for_signing: Option<SignedSecretKey>,
shared_secret: &str,
compress: bool,
) -> Result<String> {
@@ -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,
)