enigma-protocol 0.1.0

High-level orchestrator that composes the Enigma crates into a production-ready messaging protocol
Documentation
use crate::error::Result;
use crate::session::Session;
use crate::types::{InitiatorOrResponder, SessionBootstrap};
use enigma_packet::{AttachmentChunkMeta, Message, MessageMeta, MessageType};
use uuid::Uuid;

fn sample_sessions() -> Result<(Session, Session)> {
    let secret = [5u8; 32];
    let sender = Session::new(
        "alice",
        "bob",
        &SessionBootstrap::PreSharedSecret {
            secret32: secret,
            role: InitiatorOrResponder::Initiator,
            remote_dh_pub: None,
        },
    )?;
    let receiver = Session::new(
        "bob",
        "alice",
        &SessionBootstrap::PreSharedSecret {
            secret32: secret,
            role: InitiatorOrResponder::Responder,
            remote_dh_pub: None,
        },
    )?;
    Ok((sender, receiver))
}

#[test]
fn ciphertext_tampering_detected() -> Result<()> {
    let (mut sender, mut receiver) = sample_sessions()?;
    let packet = sender.encrypt_message(&simple_message())?;
    let mut corrupted = packet.clone();
    if let Some(byte) = corrupted.get_mut(5) {
        *byte ^= 0xAA;
    }
    assert!(receiver.decrypt_packet(&corrupted).is_err());
    Ok(())
}

#[test]
fn chunk_without_init_fails() -> Result<()> {
    let (mut sender, mut receiver) = sample_sessions()?;
    let attachment_id = Uuid::new_v4();
    let message = Message {
        id: Uuid::new_v4(),
        sender: "alice".to_string(),
        receiver: "bob".to_string(),
        timestamp_ms: 1,
        msg_type: MessageType::AttachmentChunk,
        payload: vec![1, 2, 3],
        meta: MessageMeta::AttachmentChunk(AttachmentChunkMeta {
            attachment_id,
            index: 0,
            offset: 0,
            chunk_size: 3,
            total_size: Some(3),
        }),
    };
    let packet = sender.encrypt_message(&message)?;
    let decoded = receiver.decrypt_packet(&packet)?;
    assert!(receiver.handle_attachment_message(&decoded).is_err());
    Ok(())
}

fn simple_message() -> Message {
    Message {
        id: Uuid::new_v4(),
        sender: "alice".to_string(),
        receiver: "bob".to_string(),
        timestamp_ms: 1,
        msg_type: MessageType::Text,
        payload: b"attack".to_vec(),
        meta: MessageMeta::Basic {
            content_type: Some("text/plain".to_string()),
        },
    }
}