mirror of
https://github.com/signalapp/libsignal.git
synced 2026-04-26 09:45:16 +02:00
cross-version: Add a test for sealed sender messages
This commit is contained in:
146
rust/protocol/cross-version-testing/tests/sealed_sender.rs
Normal file
146
rust/protocol/cross-version-testing/tests/sealed_sender.rs
Normal file
@@ -0,0 +1,146 @@
|
||||
//
|
||||
// Copyright 2025 Signal Messenger, LLC.
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
use libsignal_protocol_cross_version_testing::*;
|
||||
use libsignal_protocol_current::{
|
||||
ContentHint, DeviceId, KeyPair, SealedSenderV2SentMessage, SenderCertificate,
|
||||
ServerCertificate, Timestamp,
|
||||
};
|
||||
use rand::rng;
|
||||
|
||||
const BOB_UUID: uuid::Uuid = uuid::uuid!("b000000b-6199-486a-ba89-2ba2bb4f2154");
|
||||
|
||||
fn make_alice_sender_cert(alice_store: &mut dyn LibSignalProtocolStore) -> SenderCertificate {
|
||||
let fake_trust_root = KeyPair::generate(&mut rng());
|
||||
let signer_key = KeyPair::generate(&mut rng());
|
||||
let server_cert = ServerCertificate::new(
|
||||
0xfa75e,
|
||||
signer_key.public_key,
|
||||
&fake_trust_root.private_key,
|
||||
&mut rng(),
|
||||
)
|
||||
.expect("valid");
|
||||
let identity_key = *alice_store
|
||||
.create_pre_key_bundle()
|
||||
.identity_key()
|
||||
.expect("has identity key");
|
||||
SenderCertificate::new(
|
||||
"alice".to_owned(),
|
||||
Some("+16505550101".to_owned()),
|
||||
*identity_key.public_key(),
|
||||
DeviceId::new(1).expect("valid"),
|
||||
Timestamp::from_epoch_millis(0),
|
||||
server_cert,
|
||||
&signer_key.private_key,
|
||||
&mut rng(),
|
||||
)
|
||||
.expect("valid")
|
||||
}
|
||||
|
||||
fn assert_eq_usmc(
|
||||
original: &UnidentifiedSenderMessageContent,
|
||||
decrypted: &UnidentifiedSenderMessageContent,
|
||||
) {
|
||||
// Check the fields rather than just re-serializing to make sure the protobuf definition hasn't
|
||||
// changed either. But we also re-serialize in case a field is added that's not checked here.
|
||||
assert_eq!(
|
||||
original.msg_type().expect("has field"),
|
||||
decrypted.msg_type().expect("has field")
|
||||
);
|
||||
assert_eq!(
|
||||
original.contents().expect("has field"),
|
||||
decrypted.contents().expect("has field")
|
||||
);
|
||||
assert_eq!(
|
||||
original.group_id().expect("has field"),
|
||||
decrypted.group_id().expect("has field")
|
||||
);
|
||||
assert_eq!(
|
||||
original.content_hint().expect("has field"),
|
||||
decrypted.content_hint().expect("has field")
|
||||
);
|
||||
assert_eq!(
|
||||
original
|
||||
.sender()
|
||||
.expect("has field")
|
||||
.serialized()
|
||||
.expect("can serialize"),
|
||||
decrypted
|
||||
.sender()
|
||||
.expect("has field")
|
||||
.serialized()
|
||||
.expect("can serialize"),
|
||||
);
|
||||
assert_eq!(
|
||||
original.serialized().expect("can serialize the whole USMC"),
|
||||
decrypted
|
||||
.serialized()
|
||||
.expect("can serialize the whole USMC"),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssv1() {
|
||||
try_all_combinations(run, &[|| Box::new(LibSignalProtocolV70::new())]);
|
||||
|
||||
fn run(
|
||||
alice_store: &mut dyn LibSignalProtocolStore,
|
||||
bob_store: &mut dyn LibSignalProtocolStore,
|
||||
) {
|
||||
alice_store
|
||||
.process_pre_key_bundle(&BOB_UUID.to_string(), bob_store.create_pre_key_bundle());
|
||||
|
||||
let message = UnidentifiedSenderMessageContent::new(
|
||||
CiphertextMessageType::SenderKey,
|
||||
make_alice_sender_cert(alice_store),
|
||||
b"payload".to_vec(),
|
||||
ContentHint::Resendable,
|
||||
Some(b"group".to_vec()),
|
||||
)
|
||||
.expect("valid");
|
||||
|
||||
let encrypted = alice_store.encrypt_sealed_sender_v1(&BOB_UUID.to_string(), &message);
|
||||
let decrypted = bob_store.decrypt_sealed_sender(&encrypted);
|
||||
|
||||
assert_eq_usmc(&message, &decrypted);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssv2() {
|
||||
try_all_combinations(run, &[|| Box::new(LibSignalProtocolV70::new())]);
|
||||
|
||||
fn run(
|
||||
alice_store: &mut dyn LibSignalProtocolStore,
|
||||
bob_store: &mut dyn LibSignalProtocolStore,
|
||||
) {
|
||||
alice_store
|
||||
.process_pre_key_bundle(&BOB_UUID.to_string(), bob_store.create_pre_key_bundle());
|
||||
|
||||
let message = UnidentifiedSenderMessageContent::new(
|
||||
CiphertextMessageType::SenderKey,
|
||||
make_alice_sender_cert(alice_store),
|
||||
b"payload".to_vec(),
|
||||
ContentHint::Resendable,
|
||||
Some(b"group".to_vec()),
|
||||
)
|
||||
.expect("valid");
|
||||
|
||||
let encrypted_to_send =
|
||||
alice_store.encrypt_sealed_sender_v2(&BOB_UUID.to_string(), &message);
|
||||
|
||||
let parsed_encrypted_to_send =
|
||||
SealedSenderV2SentMessage::parse(&encrypted_to_send).expect("valid");
|
||||
assert_eq!(1, parsed_encrypted_to_send.recipients.len());
|
||||
let encrypted_to_receive = parsed_encrypted_to_send
|
||||
.received_message_parts_for_recipient(&parsed_encrypted_to_send.recipients[0])
|
||||
.as_ref()
|
||||
.concat();
|
||||
|
||||
let decrypted = bob_store.decrypt_sealed_sender(&encrypted_to_receive);
|
||||
|
||||
assert_eq_usmc(&message, &decrypted);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user