enigma-packet 0.1.0

Canonical message packet format + serialization for Enigma secure messaging
Documentation
use crate::tests::{inline_file_message, text_message, voice_message};
use crate::{decode_message, encode_message, EnigmaPacketError, HEADER_LEN};

#[test]
fn decode_rejects_bad_magic() {
    let message = text_message();
    let mut packet = encode_message(&message).unwrap();
    packet[0] = b'X';
    let err = decode_message(&packet).unwrap_err();
    assert!(matches!(err, EnigmaPacketError::InvalidPacket(_)));
}

#[test]
fn decode_rejects_bad_version() {
    let message = voice_message();
    let mut packet = encode_message(&message).unwrap();
    packet[4] = 2;
    let err = decode_message(&packet).unwrap_err();
    assert!(matches!(err, EnigmaPacketError::UnsupportedVersion(2)));
}

#[test]
fn decode_rejects_truncated_packet() {
    let message = inline_file_message();
    let mut packet = encode_message(&message).unwrap();
    packet.pop();
    assert!(decode_message(&packet).is_err());
}

#[test]
fn decode_rejects_mismatched_length() {
    let message = inline_file_message();
    let mut packet = encode_message(&message).unwrap();
    let body_len = (packet.len() - HEADER_LEN) as u32 + 1;
    packet[8..12].copy_from_slice(&body_len.to_be_bytes());
    assert!(decode_message(&packet).is_err());
}

#[test]
fn decode_rejects_corrupted_body() {
    let message = text_message();
    let mut packet = encode_message(&message).unwrap();
    let relative = packet[HEADER_LEN..]
        .windows(5)
        .position(|w| w == b"alice")
        .expect("sender bytes not found");
    let start = HEADER_LEN + relative;
    for byte in &mut packet[start..start + 5] {
        *byte = 0xFF;
    }
    let err = decode_message(&packet).unwrap_err();
    assert!(matches!(err, EnigmaPacketError::DecodeError(_)));
}