metalssh 0.0.1

Experimental SSH implementation
//! `none` cipher.

use crate::crypto::cipher::Cipher;
use crate::types::Result;
use crate::wire::Packet;

/// See module level docs.
pub struct None {}

impl Cipher for None {
    const AEAD_LENGTH: Option<usize> = None;

    fn encrypt_packet<'buf, B>(
        &self,
        _packet: &'buf mut Packet<&'buf mut B>,
        _sequence_number: u32,
    ) -> Result<()>
    where
        B: AsRef<[u8]> + AsMut<[u8]> + ?Sized,
    {
        Ok(())
    }

    fn decrypt_packet_length<B>(&self, packet: &Packet<B>, _sequence_number: u32) -> Result<u32>
    where
        B: AsRef<[u8]>,
    {
        packet.packet_length()
    }

    fn decrypt_packet<'buf, B>(
        &self,
        _packet: &'buf mut Packet<&'buf mut B>,
        _sequence_number: u32,
    ) -> Result<()>
    where
        B: AsRef<[u8]> + AsMut<[u8]> + ?Sized,
    {
        Ok(())
    }
}

#[cfg(test)]
mod tests {

    use rstest::rstest;

    use super::*;

    #[rstest]
    #[case(0, "000000080615000102030405", "000000080615000102030405")]
    fn encrypt_works(
        #[case] sequence_number: u32,
        #[case] packet_clear: &str,
        #[case] packet_cipher_should: &str,
    ) {
        // Start with unencrypted binary packet data
        let mut data = hex::decode(packet_clear).unwrap();
        let data_len_should = data.len();

        // Take a mutable view over the packet and encrypt it in place
        {
            let mut packet = Packet::new(&mut data, 0);
            let cipher = None {};
            cipher.encrypt_packet(&mut packet, sequence_number).unwrap();
        }

        // Ensure that the buffer size did not change
        assert_eq!(data.len(), data_len_should);

        // Ensure that the packet bytes were updated in place
        let data = hex::encode(&data);
        assert_eq!(data, packet_cipher_should);
    }

    #[rstest]
    #[case(
        "000000080615000102030405",
        0,
        "000000080615000102030405",
        8,
        6,
        &[0x15],
        &[0x00, 0x01, 0x02 , 0x03 , 0x04 , 0x05]
    )]
    fn decrypt_works(
        #[case] input_data: &str,
        #[case] input_sequence_number: u32,
        #[case] should_data: &str,
        #[case] should_packet_length: u32,
        #[case] should_padding_length: u8,
        #[case] should_payload: &[u8],
        #[case] should_padding: &[u8],
    ) {
        // Start with "encrypted" binary packet data
        let mut data = hex::decode(input_data).unwrap();
        let should_data_len = data.len();

        // Take a mutable view over the packet and encrypt it in place
        {
            let mut packet = Packet::new(&mut data, 0);
            let cipher = None {};
            cipher
                .decrypt_packet(&mut packet, input_sequence_number)
                .unwrap();
        }

        // Ensure that the buffer size did not change
        assert_eq!(data.len(), should_data_len);

        // Ensure that the packet bytes were updated in place
        let got_dec_data = hex::encode(&data);
        assert_eq!(got_dec_data, should_data);

        // Ensure the packet structure is intact
        let packet = Packet::new(&data, 0);
        assert_eq!(packet.packet_length().unwrap(), should_packet_length);
        assert_eq!(packet.padding_length().unwrap(), should_padding_length);
        assert_eq!(packet.payload().unwrap(), should_payload);
        assert_eq!(packet.padding().unwrap(), should_padding);
    }
}