picky_krb/
gss_api.rs

1use std::fmt::Debug;
2use std::io::{self, Read, Write};
3
4use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
5use picky_asn1::tag::Tag;
6use picky_asn1::wrapper::{
7    Asn1SequenceOf, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, ExplicitContextTag3,
8    ObjectIdentifierAsn1, OctetStringAsn1, Optional,
9};
10use picky_asn1_der::{Asn1DerError, Asn1RawDer};
11use serde::de::{self, DeserializeOwned};
12use serde::{Deserialize, Serialize, ser};
13use thiserror::Error;
14
15use crate::constants::gss_api::{MIC_FILLER, MIC_TOKEN_ID, WRAP_FILLER, WRAP_TOKEN_ID};
16
17const MIC_TOKEN_INITIATOR_DEFAULT_FLAGS: u8 = 0x04;
18const MIC_TOKEN_ACCEPTOR_DEFAULT_FLAGS: u8 = 0x05;
19const WRAP_TOKEN_DEFAULT_FLAGS: u8 = 0x06;
20const WRAP_HEADER_LEN: usize = 16;
21
22#[derive(Debug, Error)]
23pub enum GssApiMessageError {
24    #[error("Invalid token id. Expected {0:?} but got {1:?}")]
25    InvalidId([u8; 2], [u8; 2]),
26    #[error("IO error: {0:?}")]
27    IoError(#[from] io::Error),
28    #[error("Invalid MIC token filler {0:?}")]
29    InvalidMicFiller([u8; 5]),
30    #[error("Invalid Wrap token filler {0:?}")]
31    InvalidWrapFiller(u8),
32    #[error("Asn1 error: {0:?}")]
33    Asn1Error(#[from] Asn1DerError),
34}
35
36/// [3.1 GSS-API](https://datatracker.ietf.org/doc/html/rfc2478#section-3.1)
37///
38/// ```not_rust
39/// MechType::= OBJECT IDENTIFIER
40/// ```
41pub type MechType = ObjectIdentifierAsn1;
42
43/// [3.2.1.  GSS-API](https://datatracker.ietf.org/doc/html/rfc2478#section-3.2.1)
44///
45/// ```not_rust
46/// MechTypeList ::= SEQUENCE OF MechType
47/// ```
48pub type MechTypeList = Asn1SequenceOf<MechType>;
49
50/// [3.2.1.  GSS-API](https://datatracker.ietf.org/doc/html/rfc2478#section-3.2.1)
51///
52/// ```not_rust
53/// NegTokenInit ::= SEQUENCE {
54///     mechTypes       [0] MechTypeList,
55///     reqFlags        [1] ContextFlags  OPTIONAL,
56///     mechToken       [2] OCTET STRING  OPTIONAL,
57///     mechListMIC     [3] OCTET STRING  OPTIONAL,
58/// }
59/// ```
60#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
61pub struct NegTokenInit {
62    #[serde(default)]
63    pub mech_types: Optional<Option<ExplicitContextTag0<MechTypeList>>>,
64    #[serde(default)]
65    pub req_flags: Optional<Option<ExplicitContextTag1<BitStringAsn1>>>,
66    #[serde(default)]
67    pub mech_token: Optional<Option<ExplicitContextTag2<OctetStringAsn1>>>,
68    #[serde(default)]
69    pub mech_list_mic: Optional<Option<ExplicitContextTag3<OctetStringAsn1>>>,
70}
71
72/// [3.2.1. GSS-API](https://datatracker.ietf.org/doc/html/rfc2478#section-3.2.1)
73///
74/// ```not_rust
75/// NegTokenTarg ::= SEQUENCE {
76///     negResult      [0] ENUMERATED                              OPTIONAL,
77///     supportedMech  [1] MechType                                OPTIONAL,
78///     responseToken  [2] OCTET STRING                            OPTIONAL,
79///     mechListMIC    [3] OCTET STRING                            OPTIONAL
80/// }
81/// ```
82#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
83pub struct NegTokenTarg {
84    #[serde(default)]
85    pub neg_result: Optional<Option<ExplicitContextTag0<Asn1RawDer>>>,
86    #[serde(default)]
87    pub supported_mech: Optional<Option<ExplicitContextTag1<MechType>>>,
88    #[serde(default)]
89    pub response_token: Optional<Option<ExplicitContextTag2<OctetStringAsn1>>>,
90    #[serde(default)]
91    pub mech_list_mic: Optional<Option<ExplicitContextTag3<OctetStringAsn1>>>,
92}
93
94pub type NegTokenTarg1 = ExplicitContextTag1<NegTokenTarg>;
95
96#[derive(Debug, PartialEq, Eq, Clone)]
97pub struct KrbMessage<T> {
98    pub krb5_oid: ObjectIdentifierAsn1,
99    pub krb5_token_id: [u8; 2],
100    pub krb_msg: T,
101}
102
103impl<T: Serialize> KrbMessage<T> {
104    pub fn encode(&self, mut data: impl Write) -> Result<(), GssApiMessageError> {
105        let mut oid = Vec::new();
106
107        {
108            let mut s = picky_asn1_der::Serializer::new_to_byte_buf(&mut oid);
109            self.krb5_oid.serialize(&mut s)?;
110        }
111
112        data.write_all(&oid)?;
113        data.write_all(&self.krb5_token_id)?;
114        data.write_all(&picky_asn1_der::to_vec(&self.krb_msg)?)?;
115
116        Ok(())
117    }
118}
119
120impl<T: DeserializeOwned> KrbMessage<T> {
121    /// Deserializes `ApplicationTag0<KrbMessage<T>>`.
122    pub fn decode_application_krb_message(
123        mut data: &[u8],
124    ) -> Result<ApplicationTag0<KrbMessage<T>>, GssApiMessageError> {
125        if data.is_empty() || Tag::from(data[0]) != Tag::application_constructed(0) {
126            return Err(GssApiMessageError::Asn1Error(Asn1DerError::InvalidData));
127        }
128
129        // We cannot implement the deserialization using the `Deserialize` trait
130        // because the krb5 token id is not an ASN1 field, but plain two-byte value.
131        // We cannot read this id using our ASN1 deserializer.
132
133        // This is a workaround we use to read the `ApplicationTag0` tag and length bytes.
134        // At the same time it will also read the first field of the `KrbMessage`.
135        #[derive(Deserialize)]
136        struct Container {
137            krb5_oid: ObjectIdentifierAsn1,
138        }
139
140        let max_len = data.len();
141        let mut reader = &mut data;
142        let Container { krb5_oid } =
143            Container::deserialize(&mut picky_asn1_der::Deserializer::new_from_reader(&mut reader, max_len))?;
144
145        let mut krb5_token_id = [0, 0];
146        reader.read_exact(&mut krb5_token_id)?;
147
148        let max_len = data.len();
149        let mut reader = &mut data;
150        let krb_msg: T = T::deserialize(&mut picky_asn1_der::Deserializer::new_from_reader(&mut reader, max_len))?;
151
152        Ok(ApplicationTag0(KrbMessage {
153            krb5_oid,
154            krb5_token_id,
155            krb_msg,
156        }))
157    }
158}
159
160impl<T: ser::Serialize> ser::Serialize for KrbMessage<T> {
161    fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, S::Error>
162    where
163        S: ser::Serializer,
164    {
165        use serde::ser::Error;
166
167        // We encode `KrbMessage` fields using `KrbMessage::encode` method.
168        // We use the `Container` type to prepend the sequence tag and length to the encoded fields.
169        #[derive(Serialize)]
170        struct Container {
171            buff: Asn1RawDer,
172        }
173
174        let mut buff = Vec::new();
175        self.encode(&mut buff)
176            .map_err(|e| S::Error::custom(format!("cannot serialize KrbMessage inner value: {:?}", e)))?;
177
178        Container { buff: Asn1RawDer(buff) }.serialize(serializer)
179    }
180}
181
182#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
183pub struct GssApiNegInit {
184    pub oid: ObjectIdentifierAsn1,
185    pub neg_token_init: ExplicitContextTag0<NegTokenInit>,
186}
187
188/// This [ApplicationTag0] is different from the [ApplicationTag].
189/// [ApplicationTag] works as a wrapper over the inner value
190/// but [ApplicationTag0] decodes/encodes inner type fields as its own fields
191///
192/// **Note**: The corresponding ASN1 type of the inner type is expected to be a SEQUENCE.
193/// In other words, the deserialization of something like `ApplicationTag0<BitString>` will fail
194/// or produce invalid value.
195/// This is because of the deserialization workaround we wrote to support weird Microsoft GSS API message.
196#[derive(Debug, PartialEq, Eq)]
197pub struct ApplicationTag0<T>(pub T);
198
199impl<'de, T: de::DeserializeOwned> de::Deserialize<'de> for ApplicationTag0<T> {
200    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
201    where
202        D: de::Deserializer<'de>,
203    {
204        let mut raw = Asn1RawDer::deserialize(deserializer)?.0;
205
206        if let Some(first) = raw.first_mut() {
207            // ASN1 sequence tag.
208            *first = Tag::SEQUENCE.inner();
209        }
210
211        let mut deserializer = picky_asn1_der::Deserializer::new_from_bytes(&raw);
212
213        Ok(Self(T::deserialize(&mut deserializer).unwrap()))
214    }
215}
216
217impl<T: ser::Serialize + Debug + PartialEq> ser::Serialize for ApplicationTag0<T> {
218    fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, S::Error>
219    where
220        S: ser::Serializer,
221    {
222        use serde::ser::Error;
223
224        let mut buff = Vec::new();
225        {
226            let mut s = picky_asn1_der::Serializer::new_to_byte_buf(&mut buff);
227            self.0
228                .serialize(&mut s)
229                .map_err(|e| S::Error::custom(format!("cannot serialize GssApiMessage inner value: {:?}", e)))?;
230        }
231
232        buff[0] = Tag::application_constructed(0).inner();
233
234        Asn1RawDer(buff).serialize(serializer)
235    }
236}
237
238/// [MIC Tokens](https://datatracker.ietf.org/doc/html/rfc4121#section-4.2.6.1)
239///
240/// Octet no Name       Description
241/// --------------------------------------------------------------
242/// 0..1     TOK_ID     Identification field. Contains the hex value 04 04 expressed in big-endian order
243/// 2        Flags      Attributes field
244/// 3..7     Filler     Contains five octets of hex value FF.
245/// 8..15    SND_SEQ    Sequence number expressed in big-endian order.
246/// 16..last SGN_CKSUM  Checksum
247#[derive(Debug, PartialEq, Eq, Clone)]
248pub struct MicToken {
249    pub flags: u8,
250    pub seq_num: u64,
251    pub payload: Option<Vec<u8>>,
252    pub checksum: Vec<u8>,
253}
254
255impl MicToken {
256    pub fn with_initiator_flags() -> Self {
257        Self {
258            flags: MIC_TOKEN_INITIATOR_DEFAULT_FLAGS,
259            seq_num: 0,
260            payload: None,
261            checksum: Vec::new(),
262        }
263    }
264
265    pub fn with_acceptor_flags() -> Self {
266        Self {
267            flags: MIC_TOKEN_ACCEPTOR_DEFAULT_FLAGS,
268            seq_num: 0,
269            payload: None,
270            checksum: Vec::new(),
271        }
272    }
273
274    pub fn with_seq_number(self, seq_num: u64) -> Self {
275        let MicToken {
276            flags,
277            payload,
278            checksum,
279            ..
280        } = self;
281        Self {
282            flags,
283            seq_num,
284            payload,
285            checksum,
286        }
287    }
288
289    pub fn header(&self) -> [u8; 16] {
290        let mut header_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
291
292        header_data[0..2].copy_from_slice(&MIC_TOKEN_ID);
293        header_data[2] = self.flags;
294        header_data[3..8].copy_from_slice(&MIC_FILLER);
295        header_data[8..].copy_from_slice(&self.seq_num.to_be_bytes());
296
297        header_data
298    }
299
300    pub fn set_checksum(&mut self, checksum: Vec<u8>) {
301        self.checksum = checksum;
302    }
303
304    pub fn set_payload(&mut self, payload: Vec<u8>) {
305        self.payload = Some(payload);
306    }
307
308    pub fn encode(&self, mut data: impl Write) -> Result<(), GssApiMessageError> {
309        data.write_all(&MIC_TOKEN_ID)?;
310        data.write_u8(self.flags)?;
311        data.write_all(&MIC_FILLER)?;
312        data.write_u64::<BigEndian>(self.seq_num)?;
313        data.write_all(&self.checksum)?;
314
315        Ok(())
316    }
317
318    pub fn decode(mut data: impl Read) -> Result<Self, GssApiMessageError> {
319        let mut mic_token_id = [0, 0];
320
321        data.read_exact(&mut mic_token_id)?;
322        if mic_token_id != MIC_TOKEN_ID {
323            return Err(GssApiMessageError::InvalidId(MIC_TOKEN_ID, mic_token_id));
324        }
325
326        let flags = data.read_u8()?;
327
328        let mut mic_fillter = [0, 0, 0, 0, 0];
329
330        data.read_exact(&mut mic_fillter)?;
331        if mic_fillter != MIC_FILLER {
332            return Err(GssApiMessageError::InvalidMicFiller(mic_fillter));
333        }
334
335        let seq_num = data.read_u64::<BigEndian>()?;
336
337        let mut checksum = Vec::with_capacity(12);
338        data.read_to_end(&mut checksum)?;
339
340        Ok(Self {
341            flags,
342            seq_num,
343            checksum,
344            payload: None,
345        })
346    }
347}
348
349/// [Wrap Tokens](https://datatracker.ietf.org/doc/html/rfc4121#section-4.2.6.2)
350///
351/// Octet no   Name        Description
352/// --------------------------------------------------------------
353///  0..1     TOK_ID    Identification field. Contain the hex value 05 04 expressed in big-endian
354///  2        Flags     Attributes field
355///  3        Filler    Contains the hex value FF.
356///  4..5     EC        Contains the "extra count" field, in big-endian order
357///  6..7     RRC       Contains the "right rotation count" in big-endian order
358///  8..15    SND_SEQ   Sequence number field expressed in big-endian order.
359///  16..last Data      Encrypted data for Wrap tokens
360#[derive(Debug, PartialEq, Eq, Clone)]
361pub struct WrapToken {
362    pub flags: u8,
363    pub ec: u16,
364    pub rrc: u16,
365    pub seq_num: u64,
366    pub payload: Option<Vec<u8>>,
367    pub checksum: Vec<u8>,
368}
369
370impl WrapToken {
371    pub fn with_seq_number(seq_num: u64) -> Self {
372        Self {
373            flags: WRAP_TOKEN_DEFAULT_FLAGS,
374            ec: 0,
375            rrc: 0,
376            seq_num,
377            payload: None,
378            checksum: Vec::new(),
379        }
380    }
381
382    pub fn header_len() -> usize {
383        WRAP_HEADER_LEN
384    }
385
386    pub fn header(&self) -> [u8; 16] {
387        let mut header_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
388
389        header_data[0..2].copy_from_slice(&WRAP_TOKEN_ID);
390        header_data[2] = self.flags;
391        header_data[3] = WRAP_FILLER;
392        header_data[4..6].copy_from_slice(&self.ec.to_be_bytes());
393        header_data[6..8].copy_from_slice(&self.rrc.to_be_bytes());
394        header_data[8..].copy_from_slice(&self.seq_num.to_be_bytes());
395
396        header_data
397    }
398
399    pub fn set_rrc(&mut self, rrc: u16) {
400        self.rrc = rrc;
401    }
402
403    pub fn set_checksum(&mut self, checksum: Vec<u8>) {
404        self.checksum = checksum;
405    }
406
407    pub fn encode(&self, mut data: impl Write) -> Result<(), GssApiMessageError> {
408        data.write_all(&WRAP_TOKEN_ID)?;
409        data.write_u8(self.flags)?;
410        data.write_u8(WRAP_FILLER)?;
411        data.write_u16::<BigEndian>(self.ec)?;
412        data.write_u16::<BigEndian>(self.rrc)?;
413        data.write_u64::<BigEndian>(self.seq_num)?;
414        data.write_all(&self.checksum)?;
415
416        Ok(())
417    }
418
419    pub fn decode(mut data: impl Read) -> Result<Self, GssApiMessageError> {
420        let mut wrap_token_id = [0, 0];
421
422        data.read_exact(&mut wrap_token_id)?;
423        if wrap_token_id != WRAP_TOKEN_ID {
424            return Err(GssApiMessageError::InvalidId(WRAP_TOKEN_ID, wrap_token_id));
425        }
426
427        let flags = data.read_u8()?;
428
429        let filler = data.read_u8()?;
430        if filler != WRAP_FILLER {
431            return Err(GssApiMessageError::InvalidWrapFiller(filler));
432        }
433
434        let ec = data.read_u16::<BigEndian>()?;
435        let rrc = data.read_u16::<BigEndian>()?;
436        let seq_num = data.read_u64::<BigEndian>()?;
437
438        let mut checksum = Vec::with_capacity(12);
439        data.read_to_end(&mut checksum)?;
440
441        Ok(Self {
442            flags,
443            ec,
444            rrc,
445            seq_num,
446            checksum,
447            payload: None,
448        })
449    }
450}
451
452#[cfg(test)]
453mod tests {
454    use picky_asn1::restricted_string::IA5String;
455    use picky_asn1::wrapper::{
456        Asn1SequenceOf, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, ExplicitContextTag3,
457        GeneralStringAsn1, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1, Optional,
458    };
459    use picky_asn1_x509::oids;
460
461    use crate::constants::types::TGT_REP_MSG_TYPE;
462    use crate::data_types::{EncryptedData, KerberosStringAsn1, PrincipalName, Ticket, TicketInner};
463    use crate::gss_api::{ApplicationTag0, MicToken, WrapToken};
464    use crate::messages::TgtRep;
465
466    use super::KrbMessage;
467
468    #[test]
469    fn mic_token() {
470        let expected_raw = vec![
471            4, 4, 5, 255, 255, 255, 255, 255, 0, 0, 0, 0, 86, 90, 21, 229, 142, 95, 130, 211, 64, 247, 193, 232, 123,
472            169, 124, 190,
473        ];
474        let expected = MicToken {
475            flags: 5,
476            seq_num: 1448744421,
477            payload: None,
478            checksum: vec![142, 95, 130, 211, 64, 247, 193, 232, 123, 169, 124, 190],
479        };
480
481        let mic_token = MicToken::decode(expected_raw.as_slice()).unwrap();
482        let mut mic_token_raw = Vec::new();
483        mic_token.encode(&mut mic_token_raw).unwrap();
484
485        assert_eq!(expected, mic_token);
486        assert_eq!(expected_raw, mic_token_raw);
487    }
488
489    #[test]
490    fn wrap_token() {
491        let expected_raw = vec![
492            5, 4, 6, 255, 0, 0, 0, 28, 0, 0, 0, 0, 90, 181, 116, 98, 255, 212, 120, 29, 19, 35, 95, 91, 192, 216, 160,
493            95, 135, 227, 86, 195, 248, 21, 226, 203, 98, 231, 109, 149, 168, 198, 63, 143, 64, 138, 30, 8, 241, 82,
494            184, 48, 216, 142, 130, 64, 115, 237, 26, 204, 70, 175, 90, 166, 133, 159, 55, 132, 201, 214, 37, 21, 33,
495            64, 239, 83, 135, 18, 103, 64, 219, 219, 16, 166, 251, 120, 195, 31, 57, 126, 188, 123,
496        ];
497        let expected = WrapToken {
498            flags: 6,
499            ec: 0,
500            rrc: 28,
501            seq_num: 1521841250,
502            payload: None,
503            checksum: vec![
504                255, 212, 120, 29, 19, 35, 95, 91, 192, 216, 160, 95, 135, 227, 86, 195, 248, 21, 226, 203, 98, 231,
505                109, 149, 168, 198, 63, 143, 64, 138, 30, 8, 241, 82, 184, 48, 216, 142, 130, 64, 115, 237, 26, 204,
506                70, 175, 90, 166, 133, 159, 55, 132, 201, 214, 37, 21, 33, 64, 239, 83, 135, 18, 103, 64, 219, 219, 16,
507                166, 251, 120, 195, 31, 57, 126, 188, 123,
508            ],
509        };
510
511        let wrap_token = WrapToken::decode(expected_raw.as_slice()).unwrap();
512
513        let mut wrap_token_raw = Vec::new();
514        wrap_token.encode(&mut wrap_token_raw).unwrap();
515
516        assert_eq!(expected, wrap_token);
517        assert_eq!(expected_raw, wrap_token_raw);
518    }
519
520    #[test]
521    fn application_krb_message() {
522        let expected_raw = [
523            96, 130, 4, 112, 6, 10, 42, 134, 72, 134, 247, 18, 1, 2, 2, 3, 4, 1, 48, 130, 4, 94, 160, 3, 2, 1, 5, 161,
524            3, 2, 1, 17, 162, 130, 4, 80, 97, 130, 4, 76, 48, 130, 4, 72, 160, 3, 2, 1, 5, 161, 13, 27, 11, 69, 88, 65,
525            77, 80, 76, 69, 46, 67, 79, 77, 162, 32, 48, 30, 160, 3, 2, 1, 2, 161, 23, 48, 21, 27, 6, 107, 114, 98,
526            116, 103, 116, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 163, 130, 4, 14, 48, 130, 4, 10, 160, 3,
527            2, 1, 18, 161, 3, 2, 1, 2, 162, 130, 3, 252, 4, 130, 3, 248, 58, 176, 96, 104, 148, 116, 168, 177, 48, 197,
528            115, 31, 233, 217, 105, 81, 140, 38, 30, 245, 3, 239, 15, 203, 160, 156, 134, 234, 132, 191, 71, 202, 222,
529            150, 103, 171, 92, 19, 221, 17, 179, 129, 3, 255, 79, 117, 96, 161, 111, 255, 62, 72, 85, 50, 133, 190,
530            217, 238, 115, 108, 74, 181, 4, 183, 174, 6, 13, 39, 157, 21, 179, 161, 38, 53, 173, 32, 179, 38, 31, 111,
531            235, 99, 4, 84, 73, 19, 131, 66, 70, 86, 143, 92, 176, 35, 222, 236, 86, 11, 218, 45, 67, 13, 75, 15, 70,
532            146, 109, 32, 230, 18, 73, 31, 136, 51, 36, 247, 91, 216, 147, 63, 53, 232, 52, 147, 108, 77, 95, 95, 24,
533            54, 56, 188, 50, 8, 28, 34, 173, 252, 124, 28, 83, 9, 186, 41, 94, 150, 73, 86, 24, 16, 54, 251, 57, 142,
534            11, 121, 241, 69, 245, 149, 245, 214, 198, 37, 119, 142, 219, 194, 2, 206, 206, 180, 158, 68, 168, 249,
535            236, 216, 49, 90, 165, 237, 232, 9, 189, 248, 231, 254, 121, 205, 205, 149, 131, 30, 46, 63, 48, 145, 68,
536            63, 146, 137, 77, 32, 182, 218, 225, 188, 226, 238, 82, 141, 180, 86, 90, 239, 101, 222, 8, 77, 102, 96,
537            102, 226, 45, 199, 31, 76, 163, 81, 169, 147, 168, 188, 112, 196, 135, 215, 159, 30, 74, 2, 133, 200, 145,
538            150, 60, 245, 124, 79, 250, 118, 6, 38, 91, 229, 40, 13, 51, 193, 1, 179, 37, 238, 58, 50, 172, 54, 24, 60,
539            250, 234, 13, 91, 77, 96, 143, 253, 1, 122, 141, 197, 143, 158, 38, 85, 60, 23, 149, 87, 27, 196, 153, 10,
540            122, 157, 246, 83, 225, 198, 161, 171, 201, 103, 126, 19, 156, 75, 143, 207, 166, 28, 76, 14, 185, 85, 98,
541            35, 103, 220, 152, 100, 20, 97, 187, 66, 107, 94, 56, 187, 77, 120, 82, 180, 244, 20, 129, 154, 251, 5, 99,
542            161, 220, 10, 238, 61, 2, 110, 72, 195, 81, 11, 11, 111, 219, 134, 142, 50, 9, 46, 224, 15, 206, 87, 24,
543            142, 157, 248, 107, 93, 133, 164, 75, 147, 111, 54, 154, 158, 157, 68, 158, 222, 20, 134, 249, 211, 36, 7,
544            229, 92, 130, 220, 29, 19, 82, 247, 236, 224, 7, 157, 70, 97, 70, 109, 205, 46, 44, 229, 186, 69, 127, 117,
545            201, 183, 151, 77, 25, 67, 38, 211, 184, 58, 7, 179, 234, 19, 37, 181, 63, 85, 12, 4, 8, 243, 248, 136,
546            134, 197, 28, 106, 99, 155, 17, 66, 223, 116, 123, 19, 88, 230, 99, 235, 56, 55, 135, 89, 57, 58, 125, 70,
547            67, 141, 106, 212, 9, 78, 0, 127, 213, 142, 8, 248, 78, 211, 241, 128, 127, 194, 240, 45, 253, 228, 210,
548            176, 229, 156, 0, 102, 105, 43, 64, 206, 83, 78, 130, 210, 238, 174, 206, 231, 47, 68, 225, 72, 234, 240,
549            90, 253, 246, 29, 173, 119, 117, 154, 253, 51, 14, 142, 112, 20, 86, 157, 15, 103, 44, 24, 83, 40, 38, 188,
550            135, 202, 60, 246, 32, 50, 51, 43, 148, 161, 58, 3, 212, 105, 169, 247, 125, 48, 35, 227, 186, 71, 158,
551            243, 198, 101, 9, 233, 169, 147, 66, 107, 65, 243, 211, 135, 236, 129, 116, 182, 77, 40, 32, 212, 28, 155,
552            140, 239, 48, 222, 163, 87, 100, 10, 149, 54, 126, 112, 180, 208, 225, 42, 182, 254, 79, 97, 85, 231, 109,
553            231, 111, 82, 56, 57, 34, 66, 23, 204, 83, 30, 187, 191, 9, 154, 29, 231, 12, 28, 62, 132, 221, 235, 106,
554            80, 220, 171, 207, 75, 44, 148, 78, 209, 252, 49, 138, 163, 159, 191, 96, 168, 149, 186, 115, 105, 229, 98,
555            181, 65, 191, 225, 46, 101, 235, 203, 204, 79, 168, 140, 216, 246, 73, 69, 104, 240, 239, 121, 227, 16,
556            134, 69, 150, 254, 18, 254, 223, 26, 154, 82, 26, 83, 21, 91, 1, 151, 221, 205, 114, 70, 140, 229, 219,
557            189, 100, 214, 255, 207, 91, 254, 74, 103, 199, 102, 170, 173, 137, 19, 47, 129, 151, 127, 144, 182, 202,
558            116, 115, 58, 214, 123, 18, 185, 81, 132, 29, 229, 80, 131, 118, 45, 185, 22, 87, 173, 173, 207, 204, 135,
559            13, 254, 244, 239, 28, 250, 233, 182, 140, 163, 234, 91, 25, 49, 182, 113, 182, 47, 213, 7, 203, 133, 227,
560            243, 75, 14, 250, 154, 83, 60, 23, 241, 253, 33, 106, 233, 235, 119, 71, 175, 49, 226, 125, 226, 156, 227,
561            132, 189, 29, 64, 151, 168, 39, 120, 199, 110, 233, 45, 132, 197, 250, 35, 67, 68, 139, 58, 245, 247, 74,
562            241, 70, 170, 174, 15, 56, 13, 130, 18, 195, 137, 90, 153, 166, 17, 152, 62, 12, 55, 51, 140, 22, 45, 171,
563            25, 172, 77, 14, 201, 160, 61, 56, 132, 216, 131, 93, 162, 132, 216, 186, 179, 60, 198, 247, 229, 249, 201,
564            43, 212, 227, 116, 29, 129, 9, 75, 99, 63, 218, 213, 214, 179, 204, 14, 48, 192, 232, 54, 197, 5, 235, 18,
565            106, 129, 85, 100, 2, 78, 213, 83, 255, 114, 85, 78, 250, 11, 235, 182, 221, 242, 255, 252, 51, 93, 254,
566            168, 35, 161, 111, 198, 77, 141, 118, 197, 155, 129, 191, 215, 193, 81, 47, 99, 1, 124, 120, 46, 148, 51,
567            133, 160, 21, 187, 196, 236, 59, 175, 138, 166, 247, 162, 168, 48, 122, 100, 146, 154, 251, 27, 131, 8,
568            249, 171, 237, 122, 212, 52, 195, 226, 75, 60, 248, 52, 124, 143, 121, 206, 69, 7, 24, 22, 16, 232, 178,
569            254, 197, 31, 132, 98, 71, 22, 217, 145, 34, 214, 214, 189, 164, 171, 200, 232, 234, 237, 99, 76, 216, 35,
570            137, 123, 207, 77, 59, 180, 170, 209, 93, 137, 89, 62, 192, 201, 20, 61, 102, 10, 255, 160, 11, 27, 254,
571            213, 14, 2,
572        ];
573        let expected = ApplicationTag0(KrbMessage {
574            krb5_oid: ObjectIdentifierAsn1::from(oids::krb5_user_to_user()),
575            // TGT rep
576            krb5_token_id: [0x04, 0x01],
577            krb_msg: TgtRep {
578                pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![5])),
579                msg_type: ExplicitContextTag1::from(IntegerAsn1::from(vec![TGT_REP_MSG_TYPE])),
580                ticket: ExplicitContextTag2::from(Ticket::from(TicketInner {
581                    tkt_vno: ExplicitContextTag0::from(IntegerAsn1(vec![5])),
582                    realm: ExplicitContextTag1::from(GeneralStringAsn1::from(
583                        IA5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
584                    )),
585                    sname: ExplicitContextTag2::from(PrincipalName {
586                        name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
587                        name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
588                            KerberosStringAsn1::from(IA5String::from_string("krbtgt".to_owned()).unwrap()),
589                            KerberosStringAsn1::from(IA5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
590                        ])),
591                    }),
592                    enc_part: ExplicitContextTag3::from(EncryptedData {
593                        etype: ExplicitContextTag0::from(IntegerAsn1(vec![18])),
594                        kvno: Optional::from(Some(ExplicitContextTag1::from(IntegerAsn1(vec![2])))),
595                        cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
596                            58, 176, 96, 104, 148, 116, 168, 177, 48, 197, 115, 31, 233, 217, 105, 81, 140, 38, 30,
597                            245, 3, 239, 15, 203, 160, 156, 134, 234, 132, 191, 71, 202, 222, 150, 103, 171, 92, 19,
598                            221, 17, 179, 129, 3, 255, 79, 117, 96, 161, 111, 255, 62, 72, 85, 50, 133, 190, 217, 238,
599                            115, 108, 74, 181, 4, 183, 174, 6, 13, 39, 157, 21, 179, 161, 38, 53, 173, 32, 179, 38, 31,
600                            111, 235, 99, 4, 84, 73, 19, 131, 66, 70, 86, 143, 92, 176, 35, 222, 236, 86, 11, 218, 45,
601                            67, 13, 75, 15, 70, 146, 109, 32, 230, 18, 73, 31, 136, 51, 36, 247, 91, 216, 147, 63, 53,
602                            232, 52, 147, 108, 77, 95, 95, 24, 54, 56, 188, 50, 8, 28, 34, 173, 252, 124, 28, 83, 9,
603                            186, 41, 94, 150, 73, 86, 24, 16, 54, 251, 57, 142, 11, 121, 241, 69, 245, 149, 245, 214,
604                            198, 37, 119, 142, 219, 194, 2, 206, 206, 180, 158, 68, 168, 249, 236, 216, 49, 90, 165,
605                            237, 232, 9, 189, 248, 231, 254, 121, 205, 205, 149, 131, 30, 46, 63, 48, 145, 68, 63, 146,
606                            137, 77, 32, 182, 218, 225, 188, 226, 238, 82, 141, 180, 86, 90, 239, 101, 222, 8, 77, 102,
607                            96, 102, 226, 45, 199, 31, 76, 163, 81, 169, 147, 168, 188, 112, 196, 135, 215, 159, 30,
608                            74, 2, 133, 200, 145, 150, 60, 245, 124, 79, 250, 118, 6, 38, 91, 229, 40, 13, 51, 193, 1,
609                            179, 37, 238, 58, 50, 172, 54, 24, 60, 250, 234, 13, 91, 77, 96, 143, 253, 1, 122, 141,
610                            197, 143, 158, 38, 85, 60, 23, 149, 87, 27, 196, 153, 10, 122, 157, 246, 83, 225, 198, 161,
611                            171, 201, 103, 126, 19, 156, 75, 143, 207, 166, 28, 76, 14, 185, 85, 98, 35, 103, 220, 152,
612                            100, 20, 97, 187, 66, 107, 94, 56, 187, 77, 120, 82, 180, 244, 20, 129, 154, 251, 5, 99,
613                            161, 220, 10, 238, 61, 2, 110, 72, 195, 81, 11, 11, 111, 219, 134, 142, 50, 9, 46, 224, 15,
614                            206, 87, 24, 142, 157, 248, 107, 93, 133, 164, 75, 147, 111, 54, 154, 158, 157, 68, 158,
615                            222, 20, 134, 249, 211, 36, 7, 229, 92, 130, 220, 29, 19, 82, 247, 236, 224, 7, 157, 70,
616                            97, 70, 109, 205, 46, 44, 229, 186, 69, 127, 117, 201, 183, 151, 77, 25, 67, 38, 211, 184,
617                            58, 7, 179, 234, 19, 37, 181, 63, 85, 12, 4, 8, 243, 248, 136, 134, 197, 28, 106, 99, 155,
618                            17, 66, 223, 116, 123, 19, 88, 230, 99, 235, 56, 55, 135, 89, 57, 58, 125, 70, 67, 141,
619                            106, 212, 9, 78, 0, 127, 213, 142, 8, 248, 78, 211, 241, 128, 127, 194, 240, 45, 253, 228,
620                            210, 176, 229, 156, 0, 102, 105, 43, 64, 206, 83, 78, 130, 210, 238, 174, 206, 231, 47, 68,
621                            225, 72, 234, 240, 90, 253, 246, 29, 173, 119, 117, 154, 253, 51, 14, 142, 112, 20, 86,
622                            157, 15, 103, 44, 24, 83, 40, 38, 188, 135, 202, 60, 246, 32, 50, 51, 43, 148, 161, 58, 3,
623                            212, 105, 169, 247, 125, 48, 35, 227, 186, 71, 158, 243, 198, 101, 9, 233, 169, 147, 66,
624                            107, 65, 243, 211, 135, 236, 129, 116, 182, 77, 40, 32, 212, 28, 155, 140, 239, 48, 222,
625                            163, 87, 100, 10, 149, 54, 126, 112, 180, 208, 225, 42, 182, 254, 79, 97, 85, 231, 109,
626                            231, 111, 82, 56, 57, 34, 66, 23, 204, 83, 30, 187, 191, 9, 154, 29, 231, 12, 28, 62, 132,
627                            221, 235, 106, 80, 220, 171, 207, 75, 44, 148, 78, 209, 252, 49, 138, 163, 159, 191, 96,
628                            168, 149, 186, 115, 105, 229, 98, 181, 65, 191, 225, 46, 101, 235, 203, 204, 79, 168, 140,
629                            216, 246, 73, 69, 104, 240, 239, 121, 227, 16, 134, 69, 150, 254, 18, 254, 223, 26, 154,
630                            82, 26, 83, 21, 91, 1, 151, 221, 205, 114, 70, 140, 229, 219, 189, 100, 214, 255, 207, 91,
631                            254, 74, 103, 199, 102, 170, 173, 137, 19, 47, 129, 151, 127, 144, 182, 202, 116, 115, 58,
632                            214, 123, 18, 185, 81, 132, 29, 229, 80, 131, 118, 45, 185, 22, 87, 173, 173, 207, 204,
633                            135, 13, 254, 244, 239, 28, 250, 233, 182, 140, 163, 234, 91, 25, 49, 182, 113, 182, 47,
634                            213, 7, 203, 133, 227, 243, 75, 14, 250, 154, 83, 60, 23, 241, 253, 33, 106, 233, 235, 119,
635                            71, 175, 49, 226, 125, 226, 156, 227, 132, 189, 29, 64, 151, 168, 39, 120, 199, 110, 233,
636                            45, 132, 197, 250, 35, 67, 68, 139, 58, 245, 247, 74, 241, 70, 170, 174, 15, 56, 13, 130,
637                            18, 195, 137, 90, 153, 166, 17, 152, 62, 12, 55, 51, 140, 22, 45, 171, 25, 172, 77, 14,
638                            201, 160, 61, 56, 132, 216, 131, 93, 162, 132, 216, 186, 179, 60, 198, 247, 229, 249, 201,
639                            43, 212, 227, 116, 29, 129, 9, 75, 99, 63, 218, 213, 214, 179, 204, 14, 48, 192, 232, 54,
640                            197, 5, 235, 18, 106, 129, 85, 100, 2, 78, 213, 83, 255, 114, 85, 78, 250, 11, 235, 182,
641                            221, 242, 255, 252, 51, 93, 254, 168, 35, 161, 111, 198, 77, 141, 118, 197, 155, 129, 191,
642                            215, 193, 81, 47, 99, 1, 124, 120, 46, 148, 51, 133, 160, 21, 187, 196, 236, 59, 175, 138,
643                            166, 247, 162, 168, 48, 122, 100, 146, 154, 251, 27, 131, 8, 249, 171, 237, 122, 212, 52,
644                            195, 226, 75, 60, 248, 52, 124, 143, 121, 206, 69, 7, 24, 22, 16, 232, 178, 254, 197, 31,
645                            132, 98, 71, 22, 217, 145, 34, 214, 214, 189, 164, 171, 200, 232, 234, 237, 99, 76, 216,
646                            35, 137, 123, 207, 77, 59, 180, 170, 209, 93, 137, 89, 62, 192, 201, 20, 61, 102, 10, 255,
647                            160, 11, 27, 254, 213, 14, 2,
648                        ])),
649                    }),
650                })),
651            },
652        });
653
654        let krb_message = KrbMessage::<TgtRep>::decode_application_krb_message(expected_raw.as_slice()).unwrap();
655        let krb_message_raw = picky_asn1_der::to_vec(&expected).unwrap();
656
657        assert_eq!(krb_message, expected);
658        assert_eq!(krb_message_raw, expected_raw);
659    }
660}