picky_krb/
pac.rs

1use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
2use std::io::{Cursor, Read, Write};
3use thiserror::Error;
4
5#[derive(Error, Debug)]
6pub enum PacError {
7    #[error("Version must be 0 but got {0}")]
8    Version(u32),
9    #[error("Invalid pac buffer type: {0}")]
10    PacBufferType(u32),
11    #[error("Unable to read bytes: {0:?}")]
12    IoError(#[from] std::io::Error),
13    #[error("Invalid version: expected 0 but got {0}")]
14    InvalidVersion(u32),
15    #[error("Invalid buffer data range")]
16    InvalidRange,
17}
18
19/// [MS-PAC](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-PAC/%5bMS-PAC%5d.pdf)
20/// Section 2.4 PAC_INFO_BUFFER ulType
21#[derive(Debug, PartialEq, Eq, Clone)]
22pub enum PacBufferType {
23    KerbValidationInfo,
24    Credentials,
25    ServerChecksum,
26    KdcChecksum,
27    ClientInfo,
28    ConstrainedDelegationInformation,
29    UpnDnsInfo,
30    ClientClaimsInfo,
31    DeviceInfo,
32    DeviceClaimsInfo,
33    TicketChecksum,
34}
35
36impl TryFrom<u32> for PacBufferType {
37    type Error = PacError;
38
39    fn try_from(value: u32) -> Result<Self, Self::Error> {
40        match value {
41            1 => Ok(PacBufferType::KerbValidationInfo),
42            2 => Ok(PacBufferType::Credentials),
43            6 => Ok(PacBufferType::ServerChecksum),
44            7 => Ok(PacBufferType::KdcChecksum),
45            10 => Ok(PacBufferType::ClientInfo),
46            11 => Ok(PacBufferType::ConstrainedDelegationInformation),
47            12 => Ok(PacBufferType::UpnDnsInfo),
48            13 => Ok(PacBufferType::ClientClaimsInfo),
49            14 => Ok(PacBufferType::DeviceInfo),
50            15 => Ok(PacBufferType::DeviceClaimsInfo),
51            16 => Ok(PacBufferType::TicketChecksum),
52            n => Err(PacError::PacBufferType(n)),
53        }
54    }
55}
56
57impl From<PacBufferType> for u32 {
58    fn from(buffer_type: PacBufferType) -> Self {
59        match buffer_type {
60            PacBufferType::KerbValidationInfo => 1,
61            PacBufferType::Credentials => 2,
62            PacBufferType::ServerChecksum => 6,
63            PacBufferType::KdcChecksum => 7,
64            PacBufferType::ClientInfo => 10,
65            PacBufferType::ConstrainedDelegationInformation => 11,
66            PacBufferType::UpnDnsInfo => 12,
67            PacBufferType::ClientClaimsInfo => 13,
68            PacBufferType::DeviceInfo => 14,
69            PacBufferType::DeviceClaimsInfo => 15,
70            PacBufferType::TicketChecksum => 16,
71        }
72    }
73}
74
75/// [MS-PAC](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-PAC/%5bMS-PAC%5d.pdf)
76/// Section 2.4 PAC_INFO_BUFFER
77#[derive(Debug, PartialEq, Eq, Clone)]
78pub struct PacInfoBuffer {
79    ul_type: PacBufferType,
80    cb_buffer_size: u32,
81    offset: u64,
82}
83
84impl PacInfoBuffer {
85    pub fn deserialize(data: &mut impl Read) -> Result<Self, PacError> {
86        Ok(Self {
87            ul_type: data.read_u32::<LittleEndian>()?.try_into()?,
88            cb_buffer_size: data.read_u32::<LittleEndian>()?,
89            offset: data.read_u64::<LittleEndian>()?,
90        })
91    }
92
93    pub fn serialize(&self, data: &mut impl Write) -> Result<(), PacError> {
94        data.write_u32::<LittleEndian>(self.ul_type.clone().into())?;
95        data.write_u32::<LittleEndian>(self.cb_buffer_size)?;
96        data.write_u64::<LittleEndian>(self.offset)?;
97
98        Ok(())
99    }
100}
101
102#[derive(Debug, PartialEq, Eq, Clone)]
103pub struct PacBuffer {
104    info_buffer: PacInfoBuffer,
105    data: Vec<u8>,
106}
107
108impl PacBuffer {
109    pub fn deserialize(data: &mut Cursor<&[u8]>) -> Result<Self, PacError> {
110        let info_buffer = PacInfoBuffer::deserialize(data)?;
111
112        let from = info_buffer.offset as usize;
113        let to = from + info_buffer.cb_buffer_size as usize;
114
115        if to >= data.get_ref().len() {
116            return Err(PacError::InvalidRange);
117        }
118        let data = data.get_ref()[from..to].to_vec();
119
120        Ok(Self { info_buffer, data })
121    }
122
123    pub fn serialize(&self, data: &mut Cursor<Vec<u8>>) -> Result<(), PacError> {
124        self.info_buffer.serialize(data)?;
125
126        let from = self.info_buffer.offset as usize;
127        let to = from + self.info_buffer.cb_buffer_size as usize;
128
129        if to - from != self.data.len() || to >= data.get_ref().len() {
130            return Err(PacError::InvalidRange);
131        }
132
133        data.get_mut()[from..to].copy_from_slice(&self.data);
134
135        Ok(())
136    }
137}
138
139/// [MS-PAC](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-PAC/%5bMS-PAC%5d.pdf)
140/// Section 2.3 PACTYPE
141#[derive(Debug, PartialEq, Eq, Clone)]
142pub struct Pac {
143    c_buffers: u32,
144    buffers: Vec<PacBuffer>,
145}
146
147impl Pac {
148    pub fn deserialize(mut reader: impl Read) -> Result<Self, PacError> {
149        let mut data = Vec::new();
150        reader.read_to_end(&mut data)?;
151        let mut data = Cursor::new(data.as_ref());
152
153        let c_buffers = data.read_u32::<LittleEndian>()?;
154
155        let version = data.read_u32::<LittleEndian>()?;
156        if version != 0 {
157            return Err(PacError::InvalidVersion(version));
158        }
159
160        let mut buffers = Vec::with_capacity(c_buffers as usize);
161        for _ in 0..c_buffers {
162            buffers.push(PacBuffer::deserialize(&mut data)?);
163        }
164
165        Ok(Self { c_buffers, buffers })
166    }
167
168    pub fn serialize(&self, mut data: impl Write) -> Result<(), PacError> {
169        let data_size = 4 /* c_buffers: buffers amount */
170            + 4 /* version */
171            + self.c_buffers as usize * 16 /* ul_type (4) + cb_buffer_size (4) + offset (8) = 16 */
172            + self.buffers.iter().fold(0, |s, b| {
173                let size = b.info_buffer.cb_buffer_size;
174                // [MS-PAC](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-PAC/%5bMS-PAC%5d.pdf)
175                // Section 2.3 PACTYPE: All PAC elements MUST be placed on an 8-byte boundary
176                s + b.info_buffer.cb_buffer_size as usize + if size % 8 == 0 {
177                    0
178                } else {
179                    (8 - size % 8) as usize
180                }
181            });
182        let mut c = Cursor::new(vec![0; data_size]);
183
184        c.write_u32::<LittleEndian>(self.c_buffers)?;
185        // [MS-PAC](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-PAC/%5bMS-PAC%5d.pdf)
186        // Section 2.3 PACTYPE: MUST be 0x00000000
187        c.write_u32::<LittleEndian>(0)?;
188
189        for buffer in self.buffers.iter() {
190            buffer.serialize(&mut c)?;
191        }
192
193        data.write_all(c.get_ref())?;
194
195        Ok(())
196    }
197}
198
199#[cfg(test)]
200mod tests {
201    use super::{Pac, PacBuffer, PacBufferType, PacInfoBuffer};
202
203    #[test]
204    fn pac() {
205        let expected_pac = Pac {
206            c_buffers: 4,
207            buffers: vec![
208                PacBuffer {
209                    info_buffer: PacInfoBuffer {
210                        ul_type: PacBufferType::KerbValidationInfo,
211                        cb_buffer_size: 1200,
212                        offset: 72,
213                    },
214                    data: vec![
215                        1, 16, 8, 0, 204, 204, 204, 204, 160, 4, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 209, 134, 102, 15, 101,
216                        106, 198, 1, 255, 255, 255, 255, 255, 255, 255, 127, 255, 255, 255, 255, 255, 255, 255, 127,
217                        23, 212, 57, 254, 120, 74, 198, 1, 23, 148, 163, 40, 66, 75, 198, 1, 23, 84, 36, 151, 122, 129,
218                        198, 1, 8, 0, 8, 0, 4, 0, 2, 0, 36, 0, 36, 0, 8, 0, 2, 0, 18, 0, 18, 0, 12, 0, 2, 0, 0, 0, 0,
219                        0, 16, 0, 2, 0, 0, 0, 0, 0, 20, 0, 2, 0, 0, 0, 0, 0, 24, 0, 2, 0, 84, 16, 0, 0, 151, 121, 44,
220                        0, 1, 2, 0, 0, 26, 0, 0, 0, 28, 0, 2, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221                        0, 0, 22, 0, 24, 0, 32, 0, 2, 0, 10, 0, 12, 0, 36, 0, 2, 0, 40, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
222                        0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223                        0, 0, 13, 0, 0, 0, 44, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4,
224                        0, 0, 0, 108, 0, 122, 0, 104, 0, 117, 0, 18, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 76, 0, 105, 0,
225                        113, 0, 105, 0, 97, 0, 110, 0, 103, 0, 40, 0, 76, 0, 97, 0, 114, 0, 114, 0, 121, 0, 41, 0, 32,
226                        0, 90, 0, 104, 0, 117, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 110, 0, 116, 0, 100, 0, 115, 0,
227                        50, 0, 46, 0, 98, 0, 97, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
228                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 97, 196, 51, 0, 7, 0, 0, 0,
229                        9, 195, 45, 0, 7, 0, 0, 0, 94, 180, 50, 0, 7, 0, 0, 0, 1, 2, 0, 0, 7, 0, 0, 0, 151, 185, 44, 0,
230                        7, 0, 0, 0, 43, 241, 50, 0, 7, 0, 0, 0, 206, 48, 51, 0, 7, 0, 0, 0, 167, 46, 46, 0, 7, 0, 0, 0,
231                        42, 241, 50, 0, 7, 0, 0, 0, 152, 185, 44, 0, 7, 0, 0, 0, 98, 196, 51, 0, 7, 0, 0, 0, 148, 1,
232                        51, 0, 7, 0, 0, 0, 118, 196, 51, 0, 7, 0, 0, 0, 174, 254, 45, 0, 7, 0, 0, 0, 50, 210, 44, 0, 7,
233                        0, 0, 0, 22, 8, 50, 0, 7, 0, 0, 0, 66, 91, 46, 0, 7, 0, 0, 0, 95, 180, 50, 0, 7, 0, 0, 0, 202,
234                        156, 53, 0, 7, 0, 0, 0, 133, 68, 45, 0, 7, 0, 0, 0, 194, 240, 50, 0, 7, 0, 0, 0, 233, 234, 49,
235                        0, 7, 0, 0, 0, 237, 142, 46, 0, 7, 0, 0, 0, 182, 235, 49, 0, 7, 0, 0, 0, 171, 46, 46, 0, 7, 0,
236                        0, 0, 114, 14, 46, 0, 7, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 78, 0, 84, 0, 68, 0,
237                        69, 0, 86, 0, 45, 0, 68, 0, 67, 0, 45, 0, 48, 0, 53, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,
238                        0, 78, 0, 84, 0, 68, 0, 69, 0, 86, 0, 0, 0, 4, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0,
239                        89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 13, 0, 0, 0, 48, 0, 2, 0, 7, 0, 0, 0, 52,
240                        0, 2, 0, 7, 0, 0, 32, 56, 0, 2, 0, 7, 0, 0, 32, 60, 0, 2, 0, 7, 0, 0, 32, 64, 0, 2, 0, 7, 0, 0,
241                        32, 68, 0, 2, 0, 7, 0, 0, 32, 72, 0, 2, 0, 7, 0, 0, 32, 76, 0, 2, 0, 7, 0, 0, 32, 80, 0, 2, 0,
242                        7, 0, 0, 32, 84, 0, 2, 0, 7, 0, 0, 32, 88, 0, 2, 0, 7, 0, 0, 32, 92, 0, 2, 0, 7, 0, 0, 32, 96,
243                        0, 2, 0, 7, 0, 0, 32, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 185, 48, 27, 46, 183,
244                        65, 76, 108, 140, 59, 53, 21, 1, 2, 0, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89,
245                        81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 116, 84, 47, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0,
246                        0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 232, 56, 50, 0, 5, 0, 0,
247                        0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11,
248                        205, 56, 50, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93,
249                        37, 100, 99, 59, 11, 93, 180, 50, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81,
250                        184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 65, 22, 53, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5,
251                        21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 232, 234, 49, 0, 5, 0, 0, 0,
252                        1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 193,
253                        25, 50, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37,
254                        100, 99, 59, 11, 41, 241, 50, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184,
255                        23, 102, 114, 93, 37, 100, 99, 59, 11, 15, 95, 46, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21,
256                        0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 47, 91, 46, 0, 5, 0, 0, 0, 1, 5,
257                        0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 239, 143,
258                        49, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100,
259                        99, 59, 11, 7, 95, 46, 0, 0, 0, 0, 0,
260                    ],
261                },
262                PacBuffer {
263                    info_buffer: PacInfoBuffer {
264                        ul_type: PacBufferType::ClientInfo,
265                        cb_buffer_size: 18,
266                        offset: 1272,
267                    },
268                    data: vec![0, 73, 217, 14, 101, 106, 198, 1, 8, 0, 108, 0, 122, 0, 104, 0, 117, 0],
269                },
270                PacBuffer {
271                    info_buffer: PacInfoBuffer {
272                        ul_type: PacBufferType::ServerChecksum,
273                        cb_buffer_size: 20,
274                        offset: 1296,
275                    },
276                    data: vec![
277                        118, 255, 255, 255, 65, 237, 206, 154, 52, 129, 93, 58, 239, 123, 201, 136, 116, 128, 93, 37,
278                    ],
279                },
280                PacBuffer {
281                    info_buffer: PacInfoBuffer {
282                        ul_type: PacBufferType::KdcChecksum,
283                        cb_buffer_size: 20,
284                        offset: 1320,
285                    },
286                    data: vec![
287                        118, 255, 255, 255, 247, 165, 52, 218, 178, 192, 41, 134, 239, 224, 251, 229, 17, 10, 79, 50,
288                    ],
289                },
290            ],
291        };
292        let expected_raw = vec![
293            4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 176, 4, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 18, 0, 0, 0, 248,
294            4, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 16, 5, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 40, 5, 0,
295            0, 0, 0, 0, 0, 1, 16, 8, 0, 204, 204, 204, 204, 160, 4, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 209, 134, 102, 15,
296            101, 106, 198, 1, 255, 255, 255, 255, 255, 255, 255, 127, 255, 255, 255, 255, 255, 255, 255, 127, 23, 212,
297            57, 254, 120, 74, 198, 1, 23, 148, 163, 40, 66, 75, 198, 1, 23, 84, 36, 151, 122, 129, 198, 1, 8, 0, 8, 0,
298            4, 0, 2, 0, 36, 0, 36, 0, 8, 0, 2, 0, 18, 0, 18, 0, 12, 0, 2, 0, 0, 0, 0, 0, 16, 0, 2, 0, 0, 0, 0, 0, 20,
299            0, 2, 0, 0, 0, 0, 0, 24, 0, 2, 0, 84, 16, 0, 0, 151, 121, 44, 0, 1, 2, 0, 0, 26, 0, 0, 0, 28, 0, 2, 0, 32,
300            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 24, 0, 32, 0, 2, 0, 10, 0, 12, 0, 36, 0, 2,
301            0, 40, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
302            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 44, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
303            0, 0, 0, 4, 0, 0, 0, 108, 0, 122, 0, 104, 0, 117, 0, 18, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 76, 0, 105, 0,
304            113, 0, 105, 0, 97, 0, 110, 0, 103, 0, 40, 0, 76, 0, 97, 0, 114, 0, 114, 0, 121, 0, 41, 0, 32, 0, 90, 0,
305            104, 0, 117, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 110, 0, 116, 0, 100, 0, 115, 0, 50, 0, 46, 0, 98, 0,
306            97, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
307            0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 97, 196, 51, 0, 7, 0, 0, 0, 9, 195, 45, 0, 7, 0, 0, 0, 94, 180, 50, 0, 7,
308            0, 0, 0, 1, 2, 0, 0, 7, 0, 0, 0, 151, 185, 44, 0, 7, 0, 0, 0, 43, 241, 50, 0, 7, 0, 0, 0, 206, 48, 51, 0,
309            7, 0, 0, 0, 167, 46, 46, 0, 7, 0, 0, 0, 42, 241, 50, 0, 7, 0, 0, 0, 152, 185, 44, 0, 7, 0, 0, 0, 98, 196,
310            51, 0, 7, 0, 0, 0, 148, 1, 51, 0, 7, 0, 0, 0, 118, 196, 51, 0, 7, 0, 0, 0, 174, 254, 45, 0, 7, 0, 0, 0, 50,
311            210, 44, 0, 7, 0, 0, 0, 22, 8, 50, 0, 7, 0, 0, 0, 66, 91, 46, 0, 7, 0, 0, 0, 95, 180, 50, 0, 7, 0, 0, 0,
312            202, 156, 53, 0, 7, 0, 0, 0, 133, 68, 45, 0, 7, 0, 0, 0, 194, 240, 50, 0, 7, 0, 0, 0, 233, 234, 49, 0, 7,
313            0, 0, 0, 237, 142, 46, 0, 7, 0, 0, 0, 182, 235, 49, 0, 7, 0, 0, 0, 171, 46, 46, 0, 7, 0, 0, 0, 114, 14, 46,
314            0, 7, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 78, 0, 84, 0, 68, 0, 69, 0, 86, 0, 45, 0, 68, 0, 67,
315            0, 45, 0, 48, 0, 53, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 78, 0, 84, 0, 68, 0, 69, 0, 86, 0, 0, 0,
316            4, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 13, 0,
317            0, 0, 48, 0, 2, 0, 7, 0, 0, 0, 52, 0, 2, 0, 7, 0, 0, 32, 56, 0, 2, 0, 7, 0, 0, 32, 60, 0, 2, 0, 7, 0, 0,
318            32, 64, 0, 2, 0, 7, 0, 0, 32, 68, 0, 2, 0, 7, 0, 0, 32, 72, 0, 2, 0, 7, 0, 0, 32, 76, 0, 2, 0, 7, 0, 0, 32,
319            80, 0, 2, 0, 7, 0, 0, 32, 84, 0, 2, 0, 7, 0, 0, 32, 88, 0, 2, 0, 7, 0, 0, 32, 92, 0, 2, 0, 7, 0, 0, 32, 96,
320            0, 2, 0, 7, 0, 0, 32, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 185, 48, 27, 46, 183, 65, 76, 108,
321            140, 59, 53, 21, 1, 2, 0, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114,
322            93, 37, 100, 99, 59, 11, 116, 84, 47, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23,
323            102, 114, 93, 37, 100, 99, 59, 11, 232, 56, 50, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81,
324            184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 205, 56, 50, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0,
325            0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 93, 180, 50, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5,
326            21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 65, 22, 53, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0,
327            0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 232, 234, 49, 0, 5, 0, 0, 0, 1,
328            5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 193, 25, 50, 0, 5, 0,
329            0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 41, 241, 50,
330            0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59, 11, 15,
331            95, 46, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100, 99, 59,
332            11, 47, 91, 46, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114, 93, 37, 100,
333            99, 59, 11, 239, 143, 49, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 89, 81, 184, 23, 102, 114,
334            93, 37, 100, 99, 59, 11, 7, 95, 46, 0, 0, 0, 0, 0, 0, 73, 217, 14, 101, 106, 198, 1, 8, 0, 108, 0, 122, 0,
335            104, 0, 117, 0, 0, 0, 0, 0, 0, 0, 118, 255, 255, 255, 65, 237, 206, 154, 52, 129, 93, 58, 239, 123, 201,
336            136, 116, 128, 93, 37, 0, 0, 0, 0, 118, 255, 255, 255, 247, 165, 52, 218, 178, 192, 41, 134, 239, 224, 251,
337            229, 17, 10, 79, 50, 0, 0, 0, 0,
338        ];
339
340        let pac = Pac::deserialize(expected_raw.as_slice()).unwrap();
341        let mut pac_raw = Vec::new();
342        pac.serialize(&mut pac_raw).unwrap();
343
344        assert_eq!(expected_pac, pac);
345        assert_eq!(expected_raw, pac_raw);
346    }
347}