Skip to main content

shadow_integration_tests/
e2e_flow.rs

1//! Full end-to-end message flow tests
2
3use shadow_core::PeerId;
4
5/// Full E2E: create message → encrypt → stego embed → stego extract → decrypt → verify
6pub fn test_full_e2e_flow() -> Result<(), String> {
7    let alice_sk = crypto::SigningKey::generate();
8    let alice_id = PeerId::random();
9    let bob_sk = crypto::SigningKey::generate();
10    let bob_id = PeerId::random();
11    let alice_vk = alice_sk.verify_key();
12    let bob_vk = bob_sk.verify_key();
13
14    // 1. Key exchange
15    let (a_state, a_pub) = messaging::SecureChannel::initiate(alice_sk, alice_id);
16    let (b_state, b_pub) = messaging::SecureChannel::initiate(bob_sk, bob_id);
17    let a_chan = messaging::SecureChannel::complete(a_state, &b_pub, bob_vk)
18        .map_err(|e| format!("Channel setup failed: {}", e))?;
19    let b_chan = messaging::SecureChannel::complete(b_state, &a_pub, alice_vk)
20        .map_err(|e| format!("Channel setup failed: {}", e))?;
21
22    // 2. Create message
23    let msg = messaging::Message::text(
24        alice_id,
25        messaging::MessageTarget::Direct(bob_id),
26        "E2E integration test: full pipeline",
27    );
28
29    // 3. Encrypt message
30    let envelope = a_chan
31        .encrypt_message(&msg)
32        .map_err(|e| format!("Encrypt: {}", e))?;
33    let env_bytes = envelope
34        .to_bytes()
35        .map_err(|e| format!("Env serialize: {}", e))?;
36
37    // 4. Stego embed
38    let stego_config = stego_transport::StegoChannelConfig::default();
39    let stego_chan = stego_transport::StegoChannel::new(stego_config);
40    let stego_image = stego_chan
41        .encode(&env_bytes)
42        .map_err(|e| format!("Stego encode: {}", e))?;
43
44    // 5. Stego extract
45    let extracted = stego_chan
46        .decode(&stego_image)
47        .map_err(|e| format!("Stego decode: {}", e))?;
48    let extracted_env_bytes = &extracted[..env_bytes.len()];
49
50    // 6. Decrypt
51    let received_env = messaging::EncryptedEnvelope::from_bytes(extracted_env_bytes)
52        .map_err(|e| format!("Env deserialize: {}", e))?;
53    let received_msg = b_chan
54        .decrypt_message(&received_env)
55        .map_err(|e| format!("Decrypt: {}", e))?;
56
57    // 7. Verify
58    if received_msg.sender != alice_id {
59        return Err("Sender mismatch".into());
60    }
61
62    Ok(())
63}
64
65/// Group messaging E2E test
66pub fn test_group_messaging_e2e() -> Result<(), String> {
67    let mut group_mgr = messaging::GroupManager::new();
68    let owner = PeerId::random();
69    let member1 = PeerId::random();
70    let member2 = PeerId::random();
71
72    // Create group
73    let gid = group_mgr.create_group("test-e2e-group", owner);
74    group_mgr.join_group(&gid, member1);
75    group_mgr.join_group(&gid, member2);
76
77    // Get group
78    let group = group_mgr.get_group(&gid).ok_or("Group not found")?;
79    if group.member_count() != 3 {
80        return Err(format!("Expected 3 members, got {}", group.member_count()));
81    }
82
83    // Create group message
84    let msg = messaging::Message::text(
85        owner,
86        messaging::MessageTarget::Group(gid),
87        "Hello group!",
88    );
89
90    let serialized = msg.to_bytes().map_err(|e| format!("Serialize: {}", e))?;
91    if serialized.is_empty() {
92        return Err("Empty serialized message".into());
93    }
94
95    Ok(())
96}
97
98/// Offline queue delivery test
99pub fn test_offline_queue_delivery() -> Result<(), String> {
100    let alice_sk = crypto::SigningKey::generate();
101    let alice_id = PeerId::random();
102    let bob_sk = crypto::SigningKey::generate();
103    let bob_id = PeerId::random();
104    let alice_vk = alice_sk.verify_key();
105    let bob_vk = bob_sk.verify_key();
106
107    let (a_state, a_pub) = messaging::SecureChannel::initiate(alice_sk, alice_id);
108    let (b_state, b_pub) = messaging::SecureChannel::initiate(bob_sk, bob_id);
109    let a_chan = messaging::SecureChannel::complete(a_state, &b_pub, bob_vk)
110        .map_err(|e| format!("Channel: {}", e))?;
111    let b_chan = messaging::SecureChannel::complete(b_state, &a_pub, alice_vk)
112        .map_err(|e| format!("Channel: {}", e))?;
113
114    // Bob is offline — queue messages
115    let mut queue = messaging::OfflineQueue::new();
116
117    for i in 0..10 {
118        let msg = messaging::Message::text(
119            alice_id,
120            messaging::MessageTarget::Direct(bob_id),
121            format!("Queued message #{}", i),
122        );
123        let env = a_chan
124            .encrypt_message(&msg)
125            .map_err(|e| format!("Encrypt: {}", e))?;
126        queue.enqueue(bob_id, env, messaging::QueuePriority::Normal);
127    }
128
129    if queue.count_for(&bob_id) != 10 {
130        return Err(format!(
131            "Expected 10 queued, got {}",
132            queue.count_for(&bob_id)
133        ));
134    }
135
136    // Bob comes online — dequeue all
137    let messages = queue.dequeue_for(&bob_id);
138    if messages.len() != 10 {
139        return Err(format!("Expected 10 dequeued, got {}", messages.len()));
140    }
141
142    // Decrypt each
143    for (i, qm) in messages.iter().enumerate() {
144        let decrypted = b_chan
145            .decrypt_message(&qm.envelope)
146            .map_err(|e| format!("Decrypt msg {}: {}", i, e))?;
147        // Verify it's from Alice
148        if decrypted.sender != alice_id {
149            return Err(format!("Message {} sender mismatch", i));
150        }
151    }
152
153    Ok(())
154}
155
156#[cfg(test)]
157mod tests {
158    use super::*;
159
160    #[test]
161    fn test_e2e() {
162        test_full_e2e_flow().unwrap();
163    }
164
165    #[test]
166    fn test_group_e2e() {
167        test_group_messaging_e2e().unwrap();
168    }
169
170    #[test]
171    fn test_offline() {
172        test_offline_queue_delivery().unwrap();
173    }
174
175    #[test]
176    fn test_bidirectional_e2e() {
177        let a_sk = crypto::SigningKey::generate();
178        let a_id = PeerId::random();
179        let b_sk = crypto::SigningKey::generate();
180        let b_id = PeerId::random();
181        let a_vk = a_sk.verify_key();
182        let b_vk = b_sk.verify_key();
183
184        let (a_state, a_pub) = messaging::SecureChannel::initiate(a_sk, a_id);
185        let (b_state, b_pub) = messaging::SecureChannel::initiate(b_sk, b_id);
186        let a_chan = messaging::SecureChannel::complete(a_state, &b_pub, b_vk).unwrap();
187        let b_chan = messaging::SecureChannel::complete(b_state, &a_pub, a_vk).unwrap();
188
189        // Alice → Bob
190        let msg1 = messaging::Message::text(a_id, messaging::MessageTarget::Direct(b_id), "Hello Bob");
191        let env1 = a_chan.encrypt_message(&msg1).unwrap();
192        let dec1 = b_chan.decrypt_message(&env1).unwrap();
193        assert_eq!(dec1.sender, a_id);
194
195        // Bob → Alice
196        let msg2 = messaging::Message::text(b_id, messaging::MessageTarget::Direct(a_id), "Hello Alice");
197        let env2 = b_chan.encrypt_message(&msg2).unwrap();
198        let dec2 = a_chan.decrypt_message(&env2).unwrap();
199        assert_eq!(dec2.sender, b_id);
200    }
201}