1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use cipher::Cipher;
use std;
use std::io::{Read, Write};

use blobs::SrdBlob;
use messages::{srd_message::ReadMac, srd_msg_id, Message, SrdHeader, SrdMessage};
use srd_errors::SrdError;
use Result;

const DELEGATE_MESSAGE_SIZE_LIMIT: u32 = 16 * 1024; // Limit DELEGATE messages to 16 Kb.

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct SrdDelegate {
    pub size: u32,
    pub encrypted_blob: Vec<u8>,
    mac: [u8; 32],
}

impl SrdDelegate {
    pub fn get_data(&self, cipher: Cipher, key: &[u8], iv: &[u8]) -> Result<SrdBlob> {
        let buffer = cipher.decrypt_data(&self.encrypted_blob, key, iv)?;

        let mut cursor = std::io::Cursor::new(buffer.as_slice());
        let srd_blob = SrdBlob::read_from(&mut cursor)?;
        Ok(srd_blob)
    }

    pub fn mac(&self) -> &[u8] {
        &self.mac
    }

    pub fn set_mac(&mut self, mac: &[u8]) {
        self.mac.clone_from_slice(mac);
    }
}

impl Message for SrdDelegate {
    fn read_from<R: Read>(reader: &mut R) -> Result<Self>
        where
            Self: Sized,
    {
        let size = reader.read_u32::<LittleEndian>()?;

        if size > DELEGATE_MESSAGE_SIZE_LIMIT {
            return Err(SrdError::InvalidDataLength);
        }

        let mut blob = vec![0u8; size as usize];
        reader.read_exact(&mut blob)?;

        let mut mac = [0u8; 32];
        reader.read_mac(&mut mac)?;

        Ok(SrdDelegate {
            size,
            encrypted_blob: blob,
            mac,
        })
    }

    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
        writer.write_u32::<LittleEndian>(self.size)?;
        writer.write_all(&self.encrypted_blob)?;
        writer.write_all(&self.mac)?;
        Ok(())
    }
}

pub fn new_srd_delegate_msg(
    seq_num: u8,
    use_cbt: bool,
    srd_blob: &SrdBlob,
    cipher: Cipher,
    delegation_key: &[u8],
    iv: &[u8],
) -> Result<SrdMessage> {
    let mut v_blob = Vec::new();
    srd_blob.write_to(&mut v_blob)?;
    let encrypted_blob = cipher.encrypt_data(&v_blob, delegation_key, iv)?;

    let hdr = SrdHeader::new(srd_msg_id::SRD_DELEGATE_MSG_ID, seq_num, use_cbt, true);
    let delegate = SrdDelegate {
        size: (encrypted_blob.len() as u32),
        encrypted_blob,
        mac: [0u8; 32],
    };

    //        response.compute_mac(&previous_messages, &integrity_key)?;
    Ok(SrdMessage::Delegate(hdr, delegate))
}

//#[cfg(test)]
//mod test {
//    use std;
//    use message_types::{SRD_SIGNATURE, SrdDelegate, SrdMessage, srd_msg_id::SRD_DELEGATE_MSG_ID};
//
//    #[test]
//    fn delegate_encoding() {
//        let blob = SrdLogonBlob {
//            packet_type: 1,
//            flags: 0,
//            size: 256,
//            data: [0u8; 256],
//        };
//
//        let msg = SrdDelegate::new()
//        {
//            packet_type: 5,
//            flags: 0,
//            reserved: 0,
//            blob,
//            mac: [0u8; 32],
//        };
//
//        assert_eq!(msg.blob.get_id(), SRD_LOGON_BLOB_ID);
//        assert_eq!(msg.get_id(), SRD_DELEGATE_ID);
//
//        let mut buffer: Vec<u8> = Vec::new();
//        match msg.write_to(&mut buffer) {
//            Ok(_) => (),
//            Err(_) => assert!(false),
//        };
//
//        let mut expected = vec![5, 0, 0, 0, 0, 0, 0, 0];
//        expected.append(&mut vec![1, 0, 0, 1]);
//        expected.append(&mut vec![0u8; 256]);
//        expected.append(&mut vec![0u8; 32]);
//
//        assert_eq!(buffer, expected);
//        assert_eq!(buffer.len(), msg.get_size());
//
//        let mut cursor = std::io::Cursor::new(buffer);
//
//        match SrdDelegate::read_from(&mut cursor) {
//            Ok(x) => {
//                assert_eq!(x.packet_type, 5);
//                assert_eq!(x.flags, 0);
//                assert_eq!(x.reserved, 0);
//                assert_eq!(x.blob.packet_type, 1);
//                assert_eq!(x.blob.size, 256);
//                assert_eq!(x.blob.data.to_vec(), vec![0u8; 256]);
//                assert_eq!(x.mac, [0u8; 32]);
//            }
//            Err(_) => assert!(false),
//        };
//    }
//}