picky_krb/
messages.rs

1use std::fmt;
2use std::io::{self, Read};
3
4use picky_asn1::tag::{TagClass, TagPeeker};
5use picky_asn1::wrapper::{
6    Asn1SequenceOf, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, ExplicitContextTag3,
7    ExplicitContextTag4, ExplicitContextTag5, ExplicitContextTag6, ExplicitContextTag7, ExplicitContextTag8,
8    ExplicitContextTag9, ExplicitContextTag10, ExplicitContextTag11, ExplicitContextTag12, IntegerAsn1,
9    OctetStringAsn1, Optional,
10};
11use picky_asn1_der::application_tag::ApplicationTag;
12use picky_asn1_der::{Asn1DerError, Asn1RawDer};
13use serde::ser::Error;
14use serde::{Deserialize, Serialize, de, ser};
15
16use crate::constants::krb_priv::KRB_PRIV_VERSION;
17use crate::constants::types::{
18    AP_REP_MSG_TYPE, AP_REQ_MSG_TYPE, AS_REP_MSG_TYPE, AS_REQ_MSG_TYPE, ENC_AS_REP_PART_TYPE, ENC_TGS_REP_PART_TYPE,
19    KRB_ERROR_MSG_TYPE, KRB_PRIV, TGS_REP_MSG_TYPE, TGS_REQ_MSG_TYPE,
20};
21use crate::data_types::{
22    ApOptions, EncryptedData, EncryptionKey, HostAddresses, KerberosFlags, KerberosStringAsn1, KerberosTime, LastReq,
23    Microseconds, PaData, PrincipalName, Realm, Ticket,
24};
25
26/// [2.2.2 KDC_PROXY_MESSAGE](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-kkdcp/5778aff5-b182-4b97-a970-29c7f911eef2)
27///
28/// ```not_rust
29/// KDC-PROXY-MESSAGE::= SEQUENCE {
30///     kerb-message           [0] OCTET STRING,
31///     target-domain          [1] KERB-REALM OPTIONAL,
32///     dclocator-hint         [2] INTEGER OPTIONAL
33/// }
34/// ```
35#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
36pub struct KdcProxyMessage {
37    pub kerb_message: ExplicitContextTag0<OctetStringAsn1>,
38    #[serde(default)]
39    pub target_domain: Optional<Option<ExplicitContextTag1<KerberosStringAsn1>>>,
40    #[serde(default)]
41    pub dclocator_hint: Optional<Option<ExplicitContextTag2<IntegerAsn1>>>,
42}
43
44impl KdcProxyMessage {
45    pub fn from_raw<R: ?Sized + AsRef<[u8]>>(raw: &R) -> Result<KdcProxyMessage, Asn1DerError> {
46        let mut deserializer = picky_asn1_der::Deserializer::new_from_bytes(raw.as_ref());
47        KdcProxyMessage::deserialize(&mut deserializer)
48    }
49
50    pub fn from_raw_kerb_message<R: ?Sized + AsRef<[u8]>>(
51        raw_kerb_message: &R,
52    ) -> Result<KdcProxyMessage, Asn1DerError> {
53        Ok(KdcProxyMessage {
54            kerb_message: ExplicitContextTag0::from(OctetStringAsn1(raw_kerb_message.as_ref().to_vec())),
55            target_domain: Optional::from(None),
56            dclocator_hint: Optional::from(None),
57        })
58    }
59
60    pub fn to_vec(&self) -> Result<Vec<u8>, Asn1DerError> {
61        picky_asn1_der::to_vec(self)
62    }
63}
64
65/// [RFC 4120 5.4.1](https://www.rfc-editor.org/rfc/rfc4120.txt)
66///
67/// ```not_rust
68/// KDCOptions      ::= KerberosFlags
69/// KDC-REQ-BODY    ::= SEQUENCE {
70///         kdc-options             [0] KDCOptions,
71///         cname                   [1] PrincipalName OPTIONAL
72///                                     -- Used only in AS-REQ --,
73///         realm                   [2] Realm
74///                                     -- Server's realm
75///                                     -- Also client's in AS-REQ --,
76///         sname                   [3] PrincipalName OPTIONAL,
77///         from                    [4] KerberosTime OPTIONAL,
78///         till                    [5] KerberosTime,
79///         rtime                   [6] KerberosTime OPTIONAL,
80///         nonce                   [7] UInt32,
81///         etype                   [8] SEQUENCE OF Int32 -- EncryptionType
82///                                     -- in preference order --,
83///         addresses               [9] HostAddresses OPTIONAL,
84///         enc-authorization-data  [10] EncryptedData OPTIONAL
85///                                     -- AuthorizationData --,
86///         additional-tickets      [11] SEQUENCE OF Ticket OPTIONAL
87///                                        -- NOTE: not empty
88/// }
89/// ```
90#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
91pub struct KdcReqBody {
92    pub kdc_options: ExplicitContextTag0<KerberosFlags>,
93    pub cname: Optional<Option<ExplicitContextTag1<PrincipalName>>>,
94    pub realm: ExplicitContextTag2<Realm>,
95    pub sname: Optional<Option<ExplicitContextTag3<PrincipalName>>>,
96    pub from: Optional<Option<ExplicitContextTag4<KerberosTime>>>,
97    pub till: ExplicitContextTag5<KerberosTime>,
98    pub rtime: Optional<Option<ExplicitContextTag6<KerberosTime>>>,
99    pub nonce: ExplicitContextTag7<IntegerAsn1>,
100    pub etype: ExplicitContextTag8<Asn1SequenceOf<IntegerAsn1>>,
101    #[serde(default)]
102    pub addresses: Optional<Option<ExplicitContextTag9<HostAddresses>>>,
103    #[serde(default)]
104    pub enc_authorization_data: Optional<Option<ExplicitContextTag10<EncryptedData>>>,
105    #[serde(default)]
106    pub additional_tickets: Optional<Option<ExplicitContextTag11<Asn1SequenceOf<Ticket>>>>,
107}
108
109/// [RFC 4120 5.4.1](https://www.rfc-editor.org/rfc/rfc4120.txt)
110///
111/// ```not_rust
112/// KDC-REQ         ::= SEQUENCE {
113///         pvno            [1] INTEGER (5) ,
114///         msg-type        [2] INTEGER,
115///         padata          [3] SEQUENCE OF PA-DATA OPTIONAL,
116///                             -- NOTE: not empty --,
117///         req-body        [4] KDC-REQ-BODY,
118/// }
119/// ```
120#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
121pub struct KdcReq {
122    pub pvno: ExplicitContextTag1<IntegerAsn1>,
123    pub msg_type: ExplicitContextTag2<IntegerAsn1>,
124    pub padata: Optional<Option<ExplicitContextTag3<Asn1SequenceOf<PaData>>>>,
125    pub req_body: ExplicitContextTag4<KdcReqBody>,
126}
127
128/// [RFC 4120 5.4.2](https://www.rfc-editor.org/rfc/rfc4120.txt)
129///
130/// ```not_rust
131/// AS-REQ          ::= [APPLICATION 10] KDC-REQ
132/// ```
133pub type AsReq = ApplicationTag<KdcReq, AS_REQ_MSG_TYPE>;
134
135/// [RFC 4120 5.4.2](https://www.rfc-editor.org/rfc/rfc4120.txt)
136///
137/// ```not_rust
138/// TGS-REQ         ::= [APPLICATION 12] KDC-REQ
139/// ```
140pub type TgsReq = ApplicationTag<KdcReq, TGS_REQ_MSG_TYPE>;
141
142/// [RFC 4120 5.4.2](https://www.rfc-editor.org/rfc/rfc4120.txt)
143///
144/// ```not_rust
145/// KDC-REP         ::= SEQUENCE {
146///         pvno            [0] INTEGER (5),
147///         msg-type        [1] INTEGER (11 -- AS -- | 13 -- TGS --),
148///         padata          [2] SEQUENCE OF PA-DATA OPTIONAL
149///                                 -- NOTE: not empty --,
150///         crealm          [3] Realm,
151///         cname           [4] PrincipalName,
152///         ticket          [5] Ticket,
153///         enc-part        [6] EncryptedData
154/// }
155/// ```
156#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
157pub struct KdcRep {
158    pub pvno: ExplicitContextTag0<IntegerAsn1>,
159    pub msg_type: ExplicitContextTag1<IntegerAsn1>,
160    pub padata: Optional<Option<ExplicitContextTag2<Asn1SequenceOf<PaData>>>>,
161    pub crealm: ExplicitContextTag3<Realm>,
162    pub cname: ExplicitContextTag4<PrincipalName>,
163    pub ticket: ExplicitContextTag5<Ticket>,
164    pub enc_part: ExplicitContextTag6<EncryptedData>,
165}
166
167/// [RFC 4120 5.4.2](https://www.rfc-editor.org/rfc/rfc4120.txt)
168///
169/// ```not_rust
170/// AS-REP          ::= [APPLICATION 11] KDC-REP
171/// ```
172pub type AsRep = ApplicationTag<KdcRep, AS_REP_MSG_TYPE>;
173
174/// [RFC 4120 5.4.2](https://www.rfc-editor.org/rfc/rfc4120.txt)
175///
176/// ```not_rust
177/// TGS-REP         ::= [APPLICATION 13] KDC-REP
178/// ```
179pub type TgsRep = ApplicationTag<KdcRep, TGS_REP_MSG_TYPE>;
180
181/// [RFC 4120 5.9.1](https://www.rfc-editor.org/rfc/rfc4120.txt)
182///
183/// ```not_rust
184/// KRB-ERROR       ::= [APPLICATION 30] SEQUENCE {
185///         pvno            [0] INTEGER (5),
186///         msg-type        [1] INTEGER (30),
187///         ctime           [2] KerberosTime OPTIONAL,
188///         cusec           [3] Microseconds OPTIONAL,
189///         stime           [4] KerberosTime,
190///         susec           [5] Microseconds,
191///         error-code      [6] Int32,
192///         crealm          [7] Realm OPTIONAL,
193///         cname           [8] PrincipalName OPTIONAL,
194///         realm           [9] Realm -- service realm --,
195///         sname           [10] PrincipalName -- service name --,
196///         e-text          [11] KerberosString OPTIONAL,
197///         e-data          [12] OCTET STRING OPTIONAL
198/// }
199/// ```
200#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
201pub struct KrbErrorInner {
202    pub pvno: ExplicitContextTag0<IntegerAsn1>,
203    pub msg_type: ExplicitContextTag1<IntegerAsn1>,
204    pub ctime: Optional<Option<ExplicitContextTag2<KerberosTime>>>,
205    pub cusec: Optional<Option<ExplicitContextTag3<KerberosTime>>>,
206    pub stime: ExplicitContextTag4<KerberosTime>,
207    pub susec: ExplicitContextTag5<Microseconds>,
208    pub error_code: ExplicitContextTag6<u32>, /* use u32 until we can de/serialize signed integers. error_code should fit in u8. */
209    pub crealm: Optional<Option<ExplicitContextTag7<Realm>>>,
210    pub cname: Optional<Option<ExplicitContextTag8<PrincipalName>>>,
211    pub realm: ExplicitContextTag9<Realm>,
212    pub sname: ExplicitContextTag10<PrincipalName>,
213    #[serde(default)]
214    pub e_text: Optional<Option<ExplicitContextTag11<KerberosStringAsn1>>>,
215    #[serde(default)]
216    pub e_data: Optional<Option<ExplicitContextTag12<OctetStringAsn1>>>,
217}
218
219pub type KrbError = ApplicationTag<KrbErrorInner, KRB_ERROR_MSG_TYPE>;
220
221impl fmt::Display for KrbErrorInner {
222    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223        write!(f, "{:#04X?}", self.error_code)
224    }
225}
226
227/// [RFC 4120 5.4.2](https://www.rfc-editor.org/rfc/rfc4120.txt)
228///
229/// ```not_rust
230/// EncKDCRepPart   ::= SEQUENCE {
231///         key             [0] EncryptionKey,
232///         last-req        [1] LastReq,
233///         nonce           [2] UInt32,
234///         key-expiration  [3] KerberosTime OPTIONAL,
235///         flags           [4] TicketFlags,
236///         authtime        [5] KerberosTime,
237///         starttime       [6] KerberosTime OPTIONAL,
238///         endtime         [7] KerberosTime,
239///         renew-till      [8] KerberosTime OPTIONAL,
240///         srealm          [9] Realm,
241///         sname           [10] PrincipalName,
242///         caddr           [11] HostAddresses OPTIONAL
243/// }
244/// ```
245#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
246pub struct EncKdcRepPart {
247    pub key: ExplicitContextTag0<EncryptionKey>,
248    pub last_req: ExplicitContextTag1<LastReq>,
249    pub nonce: ExplicitContextTag2<IntegerAsn1>,
250    pub key_expiration: Optional<Option<ExplicitContextTag3<KerberosTime>>>,
251    pub flags: ExplicitContextTag4<KerberosFlags>,
252    pub auth_time: ExplicitContextTag5<KerberosTime>,
253    pub start_time: Optional<Option<ExplicitContextTag6<KerberosTime>>>,
254    pub end_time: ExplicitContextTag7<KerberosTime>,
255    pub renew_till: Optional<Option<ExplicitContextTag8<KerberosTime>>>,
256    pub srealm: ExplicitContextTag9<Realm>,
257    pub sname: ExplicitContextTag10<PrincipalName>,
258    #[serde(default)]
259    pub caddr: Optional<Option<ExplicitContextTag11<HostAddresses>>>,
260    // this field is not specified in RFC but present in real tickets
261    #[serde(default)]
262    pub encrypted_pa_data: Optional<Option<ExplicitContextTag12<Asn1SequenceOf<PaData>>>>,
263}
264
265/// [RFC 4120 5.4.2](https://www.rfc-editor.org/rfc/rfc4120.txt)
266///
267/// ```not_rust
268/// EncASRepPart    ::= [APPLICATION 25] EncKDCRepPart
269/// ```
270pub type EncAsRepPart = ApplicationTag<EncKdcRepPart, ENC_AS_REP_PART_TYPE>;
271
272/// [RFC 4120 5.4.2](https://www.rfc-editor.org/rfc/rfc4120.txt)
273///
274/// ```not_rust
275/// EncTGSRepPart   ::= [APPLICATION 26] EncKDCRepPart
276/// ```
277pub type EncTgsRepPart = ApplicationTag<EncKdcRepPart, ENC_TGS_REP_PART_TYPE>;
278
279#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
280pub struct ApReqInner {
281    pub pvno: ExplicitContextTag0<IntegerAsn1>,
282    pub msg_type: ExplicitContextTag1<IntegerAsn1>,
283    pub ap_options: ExplicitContextTag2<ApOptions>,
284    pub ticket: ExplicitContextTag3<Ticket>,
285    pub authenticator: ExplicitContextTag4<EncryptedData>,
286}
287
288pub type ApReq = ApplicationTag<ApReqInner, AP_REQ_MSG_TYPE>;
289
290#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
291pub struct ApRepInner {
292    pub pvno: ExplicitContextTag0<IntegerAsn1>,
293    pub msg_type: ExplicitContextTag1<IntegerAsn1>,
294    pub enc_part: ExplicitContextTag2<EncryptedData>,
295}
296pub type ApRep = ApplicationTag<ApRepInner, AP_REP_MSG_TYPE>;
297
298#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
299pub struct TgtReq {
300    pub pvno: ExplicitContextTag0<IntegerAsn1>,
301    pub msg_type: ExplicitContextTag1<IntegerAsn1>,
302    pub server_name: ExplicitContextTag2<PrincipalName>,
303}
304
305#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
306pub struct TgtRep {
307    pub pvno: ExplicitContextTag0<IntegerAsn1>,
308    pub msg_type: ExplicitContextTag1<IntegerAsn1>,
309    pub ticket: ExplicitContextTag2<Ticket>,
310}
311
312/// [RFC 4120](https://datatracker.ietf.org/doc/html/rfc4120#section-5.7.1)
313///
314/// ```not_rust
315/// KRB-PRIV        ::= [APPLICATION 21] SEQUENCE {
316///         pvno            [0] INTEGER (5),
317///         msg-type        [1] INTEGER (21),
318///                         -- NOTE: there is no [2] tag
319///         enc-part        [3] EncryptedData -- EncKrbPrivPart
320/// }
321/// ```
322#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
323pub struct KrbPrivInner {
324    pub pvno: ExplicitContextTag0<IntegerAsn1>,
325    pub msg_type: ExplicitContextTag1<IntegerAsn1>,
326    pub enc_part: ExplicitContextTag3<EncryptedData>,
327}
328
329pub type KrbPriv = ApplicationTag<KrbPrivInner, KRB_PRIV>;
330
331#[derive(Debug, Clone, PartialEq, Eq)]
332pub enum ApMessage {
333    ApReq(ApReq),
334    ApRep(ApRep),
335}
336
337impl<'de> de::Deserialize<'de> for ApMessage {
338    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
339    where
340        D: de::Deserializer<'de>,
341    {
342        use serde::de::Error;
343
344        struct Visitor;
345
346        impl<'de> de::Visitor<'de> for Visitor {
347            type Value = ApMessage;
348
349            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
350                formatter.write_str("a valid DER-encoded ApMessage")
351            }
352
353            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
354            where
355                A: de::SeqAccess<'de>,
356            {
357                let tag_peeker: TagPeeker = seq
358                    .next_element()
359                    .map_err(|e| A::Error::custom(format!("Cannot deserialize application tag: {:?}", e)))?
360                    .ok_or_else(|| A::Error::missing_field("ApplicationTag"))?;
361
362                match tag_peeker.next_tag.class_and_number() {
363                    (TagClass::Application, AP_REQ_MSG_TYPE) => seq
364                        .next_element()?
365                        .ok_or_else(|| A::Error::missing_field("Missing ApMessage::ApReq value"))
366                        .map(ApMessage::ApReq),
367                    (TagClass::Application, AP_REP_MSG_TYPE) => seq
368                        .next_element::<ApRep>()?
369                        .ok_or_else(|| A::Error::missing_field("Missing ApMessage::ApRep value"))
370                        .map(ApMessage::ApRep),
371                    _ => Err(A::Error::custom("Invalid tag for ApMessage. Expected ApReq or ApRep")),
372                }
373            }
374        }
375
376        deserializer.deserialize_enum("ApMessage", &["ApReq", "ApRep"], Visitor)
377    }
378}
379
380impl ser::Serialize for ApMessage {
381    fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, S::Error>
382    where
383        S: ser::Serializer,
384    {
385        match self {
386            ApMessage::ApReq(ap_req) => ap_req.serialize(serializer),
387            ApMessage::ApRep(ap_rep) => ap_rep.serialize(serializer),
388        }
389    }
390}
391
392#[derive(Debug, Clone, PartialEq, Eq)]
393pub struct KrbPrivMessage {
394    pub ap_message: ApMessage,
395    pub krb_priv: KrbPriv,
396}
397
398impl KrbPrivMessage {
399    pub fn deserialize(mut data: impl Read) -> io::Result<Self> {
400        let mut buf = [0, 0];
401
402        // read message len
403        data.read_exact(&mut buf)?;
404
405        // read version
406        data.read_exact(&mut buf)?;
407
408        if buf != KRB_PRIV_VERSION {
409            return Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid KRB_PRIV_VERSION"));
410        }
411
412        // read ap_message len
413        data.read_exact(&mut buf)?;
414
415        Ok(Self {
416            ap_message: picky_asn1_der::from_reader(&mut data)
417                .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, format!("{:?}", err)))?,
418            krb_priv: picky_asn1_der::from_reader(&mut data)
419                .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, format!("{:?}", err)))?,
420        })
421    }
422}
423
424impl ser::Serialize for KrbPrivMessage {
425    fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, S::Error>
426    where
427        S: ser::Serializer,
428    {
429        // 2 /* message len */ + 2 /* version */ + 2 /* ap_req len */
430        let mut message = vec![0, 0, 0, 0, 0, 0];
431
432        let ap_len = picky_asn1_der::to_writer(&self.ap_message, &mut message)
433            .map_err(|err| S::Error::custom(format!("Cannot serialize ap_req: {:?}", err)))?;
434        let _krb_priv_len = picky_asn1_der::to_writer(&self.krb_priv, &mut message)
435            .map_err(|err| S::Error::custom(format!("Cannot serialize krb_priv: {:?}", err)))?;
436
437        let message_len = message.len();
438        debug_assert_eq!(message_len, 6 + ap_len + _krb_priv_len);
439
440        message[0..2].copy_from_slice(&(message_len as u16).to_be_bytes());
441        message[2..4].copy_from_slice(&KRB_PRIV_VERSION);
442        message[4..6].copy_from_slice(&(ap_len as u16).to_be_bytes());
443
444        Asn1RawDer(message).serialize(serializer)
445    }
446}
447
448#[cfg(test)]
449mod tests {
450    use crate::constants::error_codes::{KDC_ERR_C_PRINCIPAL_UNKNOWN, KRB_AP_ERR_INAPP_CKSUM};
451    use crate::data_types::{
452        ApOptions, EncryptedData, KerberosFlags, KerberosStringAsn1, KerberosTime, PaData, PrincipalName, Realm,
453        Ticket, TicketInner,
454    };
455    use crate::messages::{
456        ApMessage, ApRep, ApRepInner, ApReq, ApReqInner, AsRep, AsReq, KdcProxyMessage, KdcRep, KdcReq, KdcReqBody,
457        KrbError, KrbErrorInner, KrbPriv, KrbPrivInner, KrbPrivMessage, TgsReq,
458    };
459
460    use picky_asn1::bit_string::BitString;
461    use picky_asn1::date::Date;
462    use picky_asn1::restricted_string::Ia5String;
463    use picky_asn1::wrapper::{
464        Asn1SequenceOf, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2,
465        ExplicitContextTag3, ExplicitContextTag4, ExplicitContextTag5, ExplicitContextTag6, ExplicitContextTag7,
466        ExplicitContextTag8, ExplicitContextTag9, ExplicitContextTag10, ExplicitContextTag11, GeneralStringAsn1,
467        GeneralizedTimeAsn1, IntegerAsn1, OctetStringAsn1, Optional,
468    };
469
470    #[test]
471    fn krb_priv_request_serialization() {
472        let expected_raw: [u8; 1307] = [
473            5, 27, 0, 1, 4, 177, 110, 130, 4, 173, 48, 130, 4, 169, 160, 3, 2, 1, 5, 161, 3, 2, 1, 14, 162, 7, 3, 5, 0,
474            0, 0, 0, 0, 163, 130, 3, 239, 97, 130, 3, 235, 48, 130, 3, 231, 160, 3, 2, 1, 5, 161, 13, 27, 11, 81, 75,
475            65, 84, 73, 79, 78, 46, 67, 79, 77, 162, 29, 48, 27, 160, 3, 2, 1, 2, 161, 20, 48, 18, 27, 6, 107, 97, 100,
476            109, 105, 110, 27, 8, 99, 104, 97, 110, 103, 101, 112, 119, 163, 130, 3, 176, 48, 130, 3, 172, 160, 3, 2,
477            1, 18, 161, 3, 2, 1, 2, 162, 130, 3, 158, 4, 130, 3, 154, 111, 86, 147, 251, 215, 29, 83, 198, 94, 151,
478            136, 27, 199, 220, 167, 21, 228, 231, 25, 42, 81, 220, 76, 168, 63, 248, 7, 70, 229, 251, 160, 184, 86, 31,
479            157, 224, 190, 19, 211, 201, 209, 24, 167, 98, 12, 241, 25, 182, 53, 11, 99, 196, 249, 53, 173, 176, 74,
480            172, 119, 219, 208, 49, 102, 187, 219, 120, 216, 79, 219, 180, 37, 148, 9, 49, 176, 79, 173, 231, 16, 10,
481            70, 91, 224, 15, 147, 41, 26, 219, 156, 26, 157, 205, 245, 187, 33, 230, 179, 158, 205, 24, 253, 79, 208,
482            202, 252, 12, 75, 87, 52, 215, 230, 3, 251, 162, 76, 108, 120, 154, 32, 56, 125, 168, 237, 218, 135, 37,
483            124, 255, 240, 248, 167, 19, 139, 155, 171, 119, 215, 146, 149, 91, 154, 92, 161, 55, 139, 240, 41, 45,
484            227, 174, 33, 178, 232, 230, 206, 50, 46, 129, 239, 109, 213, 239, 6, 90, 127, 222, 5, 182, 247, 168, 220,
485            223, 86, 45, 68, 203, 170, 207, 19, 96, 229, 83, 104, 23, 181, 138, 67, 233, 113, 157, 241, 36, 59, 138,
486            246, 251, 65, 211, 244, 165, 103, 42, 22, 90, 114, 181, 192, 151, 243, 27, 92, 158, 53, 36, 123, 127, 169,
487            180, 48, 248, 18, 212, 171, 213, 206, 94, 202, 11, 154, 23, 82, 130, 155, 130, 78, 26, 197, 35, 159, 150,
488            212, 239, 164, 0, 38, 70, 186, 110, 224, 64, 204, 185, 29, 203, 222, 74, 242, 252, 169, 128, 193, 18, 234,
489            135, 122, 150, 170, 34, 73, 110, 146, 113, 169, 218, 111, 44, 233, 214, 160, 174, 63, 181, 216, 75, 36, 79,
490            135, 173, 110, 247, 130, 174, 242, 234, 54, 107, 90, 166, 111, 219, 2, 6, 25, 48, 11, 163, 205, 148, 228,
491            40, 251, 91, 34, 132, 119, 63, 127, 73, 38, 20, 40, 245, 172, 219, 91, 241, 57, 177, 142, 229, 138, 45, 56,
492            237, 121, 14, 26, 196, 162, 25, 86, 3, 255, 45, 140, 209, 254, 49, 253, 24, 133, 222, 212, 18, 229, 142,
493            70, 174, 13, 30, 0, 201, 94, 205, 160, 20, 73, 220, 154, 82, 154, 155, 1, 230, 99, 201, 174, 233, 137, 250,
494            17, 126, 74, 101, 35, 141, 255, 9, 112, 169, 100, 181, 145, 76, 11, 4, 129, 146, 195, 171, 182, 38, 134,
495            113, 8, 113, 246, 87, 91, 199, 88, 128, 5, 133, 112, 221, 205, 85, 5, 58, 218, 140, 176, 219, 84, 76, 7,
496            56, 106, 64, 90, 230, 179, 220, 137, 76, 140, 98, 189, 28, 77, 197, 145, 247, 137, 76, 103, 173, 198, 22,
497            5, 124, 57, 192, 250, 30, 51, 66, 164, 213, 142, 4, 46, 102, 21, 95, 200, 105, 200, 95, 1, 33, 186, 246,
498            202, 93, 252, 98, 85, 145, 128, 251, 90, 171, 185, 201, 96, 253, 245, 44, 166, 89, 68, 216, 204, 200, 198,
499            179, 61, 172, 154, 49, 195, 199, 11, 108, 13, 212, 45, 73, 76, 89, 76, 164, 24, 170, 90, 227, 50, 3, 187,
500            255, 44, 98, 180, 192, 80, 119, 197, 208, 130, 192, 64, 103, 186, 162, 217, 163, 190, 232, 242, 56, 50, 42,
501            88, 205, 37, 77, 97, 241, 226, 183, 62, 95, 15, 251, 92, 143, 212, 64, 106, 136, 42, 181, 112, 207, 0, 92,
502            18, 125, 20, 170, 210, 106, 60, 170, 41, 254, 255, 119, 66, 41, 213, 154, 218, 103, 222, 96, 123, 214, 80,
503            98, 59, 178, 145, 188, 72, 177, 42, 255, 246, 253, 54, 115, 195, 151, 83, 14, 51, 191, 16, 132, 112, 166,
504            246, 219, 53, 180, 189, 89, 160, 160, 201, 132, 244, 22, 18, 173, 22, 128, 131, 194, 27, 98, 110, 55, 107,
505            253, 240, 0, 137, 250, 58, 41, 181, 175, 206, 130, 86, 204, 167, 194, 192, 228, 108, 108, 134, 33, 123, 3,
506            108, 77, 41, 148, 50, 144, 140, 91, 230, 111, 97, 125, 79, 120, 72, 0, 152, 216, 59, 231, 77, 52, 225, 131,
507            116, 72, 0, 19, 36, 249, 135, 233, 85, 165, 212, 79, 240, 127, 66, 227, 15, 151, 174, 206, 199, 75, 159,
508            211, 235, 209, 59, 107, 212, 34, 230, 51, 18, 140, 35, 148, 168, 81, 71, 128, 20, 43, 39, 255, 18, 218,
509            221, 98, 11, 74, 170, 141, 226, 128, 21, 34, 111, 105, 174, 49, 209, 49, 174, 252, 181, 199, 118, 102, 43,
510            208, 9, 150, 115, 62, 224, 237, 137, 101, 232, 100, 139, 26, 237, 132, 219, 148, 98, 210, 51, 107, 136, 52,
511            57, 222, 161, 98, 37, 34, 35, 109, 188, 106, 57, 232, 184, 104, 47, 170, 113, 37, 134, 225, 226, 251, 125,
512            169, 239, 139, 215, 45, 105, 60, 150, 213, 35, 124, 198, 206, 37, 126, 154, 62, 174, 103, 44, 114, 218,
513            138, 151, 220, 13, 218, 118, 194, 132, 83, 48, 253, 237, 96, 166, 246, 32, 120, 45, 81, 241, 204, 109, 65,
514            113, 234, 53, 217, 173, 141, 233, 47, 71, 120, 110, 225, 163, 177, 62, 240, 235, 149, 57, 251, 231, 133,
515            87, 215, 146, 102, 180, 171, 32, 137, 163, 53, 173, 93, 83, 179, 87, 33, 170, 138, 106, 202, 200, 129, 236,
516            212, 65, 198, 209, 195, 220, 242, 90, 231, 185, 60, 8, 97, 157, 177, 2, 125, 79, 61, 238, 32, 159, 251, 53,
517            21, 6, 114, 17, 240, 210, 143, 17, 177, 164, 129, 160, 48, 129, 157, 160, 3, 2, 1, 18, 162, 129, 149, 4,
518            129, 146, 90, 166, 167, 142, 169, 235, 19, 170, 76, 205, 171, 40, 64, 12, 143, 135, 71, 73, 14, 96, 195,
519            162, 246, 230, 85, 140, 39, 30, 9, 52, 131, 245, 101, 73, 138, 126, 219, 118, 5, 124, 107, 163, 52, 55,
520            158, 56, 102, 190, 51, 87, 39, 34, 138, 125, 67, 208, 4, 99, 208, 29, 154, 243, 69, 93, 178, 233, 175, 232,
521            139, 133, 186, 106, 29, 105, 5, 71, 188, 181, 141, 140, 220, 31, 11, 19, 153, 53, 144, 159, 12, 59, 26, 29,
522            4, 30, 180, 32, 152, 198, 203, 144, 77, 149, 29, 141, 66, 223, 190, 6, 247, 162, 40, 15, 96, 127, 117, 230,
523            60, 37, 53, 169, 156, 179, 9, 161, 154, 4, 245, 236, 76, 93, 132, 236, 29, 64, 66, 99, 239, 20, 245, 115,
524            173, 214, 16, 19, 44, 74, 117, 98, 48, 96, 160, 3, 2, 1, 5, 161, 3, 2, 1, 21, 163, 84, 48, 82, 160, 3, 2,
525            1, 18, 162, 75, 4, 73, 251, 203, 165, 65, 153, 175, 145, 139, 228, 247, 183, 60, 132, 84, 138, 176, 207,
526            39, 144, 229, 155, 61, 235, 203, 48, 225, 81, 200, 141, 154, 169, 86, 173, 136, 255, 17, 200, 185, 164,
527            233, 123, 86, 147, 182, 0, 66, 194, 77, 248, 33, 51, 10, 48, 206, 216, 214, 47, 12, 39, 238, 115, 28, 137,
528            254, 178, 188, 52, 173, 216, 110, 145, 49, 159,
529        ];
530        let expected = KrbPrivMessage {
531            ap_message: ApMessage::ApReq(ApReq::from(ApReqInner {
532                pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x05])),
533                msg_type: ExplicitContextTag1::from(IntegerAsn1::from(vec![0x0e])),
534                ap_options: ExplicitContextTag2::from(ApOptions::from(BitString::with_bytes(vec![0, 0, 0, 0]))),
535                ticket: ExplicitContextTag3::from(Ticket::from(TicketInner {
536                    tkt_vno: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x05])),
537                    realm: ExplicitContextTag1::from(GeneralStringAsn1::from(
538                        Ia5String::from_string("QKATION.COM".into()).unwrap(),
539                    )),
540                    sname: ExplicitContextTag2::from(PrincipalName {
541                        name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x02])),
542                        name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
543                            GeneralStringAsn1::from(Ia5String::from_string("kadmin".into()).unwrap()),
544                            GeneralStringAsn1::from(Ia5String::from_string("changepw".into()).unwrap()),
545                        ])),
546                    }),
547                    enc_part: ExplicitContextTag3::from(EncryptedData {
548                        etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])),
549                        kvno: Optional::from(Some(ExplicitContextTag1::from(IntegerAsn1::from(vec![0x02])))),
550                        cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
551                            111, 86, 147, 251, 215, 29, 83, 198, 94, 151, 136, 27, 199, 220, 167, 21, 228, 231, 25, 42,
552                            81, 220, 76, 168, 63, 248, 7, 70, 229, 251, 160, 184, 86, 31, 157, 224, 190, 19, 211, 201,
553                            209, 24, 167, 98, 12, 241, 25, 182, 53, 11, 99, 196, 249, 53, 173, 176, 74, 172, 119, 219,
554                            208, 49, 102, 187, 219, 120, 216, 79, 219, 180, 37, 148, 9, 49, 176, 79, 173, 231, 16, 10,
555                            70, 91, 224, 15, 147, 41, 26, 219, 156, 26, 157, 205, 245, 187, 33, 230, 179, 158, 205, 24,
556                            253, 79, 208, 202, 252, 12, 75, 87, 52, 215, 230, 3, 251, 162, 76, 108, 120, 154, 32, 56,
557                            125, 168, 237, 218, 135, 37, 124, 255, 240, 248, 167, 19, 139, 155, 171, 119, 215, 146,
558                            149, 91, 154, 92, 161, 55, 139, 240, 41, 45, 227, 174, 33, 178, 232, 230, 206, 50, 46, 129,
559                            239, 109, 213, 239, 6, 90, 127, 222, 5, 182, 247, 168, 220, 223, 86, 45, 68, 203, 170, 207,
560                            19, 96, 229, 83, 104, 23, 181, 138, 67, 233, 113, 157, 241, 36, 59, 138, 246, 251, 65, 211,
561                            244, 165, 103, 42, 22, 90, 114, 181, 192, 151, 243, 27, 92, 158, 53, 36, 123, 127, 169,
562                            180, 48, 248, 18, 212, 171, 213, 206, 94, 202, 11, 154, 23, 82, 130, 155, 130, 78, 26, 197,
563                            35, 159, 150, 212, 239, 164, 0, 38, 70, 186, 110, 224, 64, 204, 185, 29, 203, 222, 74, 242,
564                            252, 169, 128, 193, 18, 234, 135, 122, 150, 170, 34, 73, 110, 146, 113, 169, 218, 111, 44,
565                            233, 214, 160, 174, 63, 181, 216, 75, 36, 79, 135, 173, 110, 247, 130, 174, 242, 234, 54,
566                            107, 90, 166, 111, 219, 2, 6, 25, 48, 11, 163, 205, 148, 228, 40, 251, 91, 34, 132, 119,
567                            63, 127, 73, 38, 20, 40, 245, 172, 219, 91, 241, 57, 177, 142, 229, 138, 45, 56, 237, 121,
568                            14, 26, 196, 162, 25, 86, 3, 255, 45, 140, 209, 254, 49, 253, 24, 133, 222, 212, 18, 229,
569                            142, 70, 174, 13, 30, 0, 201, 94, 205, 160, 20, 73, 220, 154, 82, 154, 155, 1, 230, 99,
570                            201, 174, 233, 137, 250, 17, 126, 74, 101, 35, 141, 255, 9, 112, 169, 100, 181, 145, 76,
571                            11, 4, 129, 146, 195, 171, 182, 38, 134, 113, 8, 113, 246, 87, 91, 199, 88, 128, 5, 133,
572                            112, 221, 205, 85, 5, 58, 218, 140, 176, 219, 84, 76, 7, 56, 106, 64, 90, 230, 179, 220,
573                            137, 76, 140, 98, 189, 28, 77, 197, 145, 247, 137, 76, 103, 173, 198, 22, 5, 124, 57, 192,
574                            250, 30, 51, 66, 164, 213, 142, 4, 46, 102, 21, 95, 200, 105, 200, 95, 1, 33, 186, 246,
575                            202, 93, 252, 98, 85, 145, 128, 251, 90, 171, 185, 201, 96, 253, 245, 44, 166, 89, 68, 216,
576                            204, 200, 198, 179, 61, 172, 154, 49, 195, 199, 11, 108, 13, 212, 45, 73, 76, 89, 76, 164,
577                            24, 170, 90, 227, 50, 3, 187, 255, 44, 98, 180, 192, 80, 119, 197, 208, 130, 192, 64, 103,
578                            186, 162, 217, 163, 190, 232, 242, 56, 50, 42, 88, 205, 37, 77, 97, 241, 226, 183, 62, 95,
579                            15, 251, 92, 143, 212, 64, 106, 136, 42, 181, 112, 207, 0, 92, 18, 125, 20, 170, 210, 106,
580                            60, 170, 41, 254, 255, 119, 66, 41, 213, 154, 218, 103, 222, 96, 123, 214, 80, 98, 59, 178,
581                            145, 188, 72, 177, 42, 255, 246, 253, 54, 115, 195, 151, 83, 14, 51, 191, 16, 132, 112,
582                            166, 246, 219, 53, 180, 189, 89, 160, 160, 201, 132, 244, 22, 18, 173, 22, 128, 131, 194,
583                            27, 98, 110, 55, 107, 253, 240, 0, 137, 250, 58, 41, 181, 175, 206, 130, 86, 204, 167, 194,
584                            192, 228, 108, 108, 134, 33, 123, 3, 108, 77, 41, 148, 50, 144, 140, 91, 230, 111, 97, 125,
585                            79, 120, 72, 0, 152, 216, 59, 231, 77, 52, 225, 131, 116, 72, 0, 19, 36, 249, 135, 233, 85,
586                            165, 212, 79, 240, 127, 66, 227, 15, 151, 174, 206, 199, 75, 159, 211, 235, 209, 59, 107,
587                            212, 34, 230, 51, 18, 140, 35, 148, 168, 81, 71, 128, 20, 43, 39, 255, 18, 218, 221, 98,
588                            11, 74, 170, 141, 226, 128, 21, 34, 111, 105, 174, 49, 209, 49, 174, 252, 181, 199, 118,
589                            102, 43, 208, 9, 150, 115, 62, 224, 237, 137, 101, 232, 100, 139, 26, 237, 132, 219, 148,
590                            98, 210, 51, 107, 136, 52, 57, 222, 161, 98, 37, 34, 35, 109, 188, 106, 57, 232, 184, 104,
591                            47, 170, 113, 37, 134, 225, 226, 251, 125, 169, 239, 139, 215, 45, 105, 60, 150, 213, 35,
592                            124, 198, 206, 37, 126, 154, 62, 174, 103, 44, 114, 218, 138, 151, 220, 13, 218, 118, 194,
593                            132, 83, 48, 253, 237, 96, 166, 246, 32, 120, 45, 81, 241, 204, 109, 65, 113, 234, 53, 217,
594                            173, 141, 233, 47, 71, 120, 110, 225, 163, 177, 62, 240, 235, 149, 57, 251, 231, 133, 87,
595                            215, 146, 102, 180, 171, 32, 137, 163, 53, 173, 93, 83, 179, 87, 33, 170, 138, 106, 202,
596                            200, 129, 236, 212, 65, 198, 209, 195, 220, 242, 90, 231, 185, 60, 8, 97, 157, 177, 2, 125,
597                            79, 61, 238, 32, 159, 251, 53, 21, 6, 114, 17, 240, 210, 143, 17, 177,
598                        ])),
599                    }),
600                })),
601                authenticator: ExplicitContextTag4::from(EncryptedData {
602                    etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])),
603                    kvno: Optional::from(None),
604                    cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
605                        90, 166, 167, 142, 169, 235, 19, 170, 76, 205, 171, 40, 64, 12, 143, 135, 71, 73, 14, 96, 195,
606                        162, 246, 230, 85, 140, 39, 30, 9, 52, 131, 245, 101, 73, 138, 126, 219, 118, 5, 124, 107, 163,
607                        52, 55, 158, 56, 102, 190, 51, 87, 39, 34, 138, 125, 67, 208, 4, 99, 208, 29, 154, 243, 69, 93,
608                        178, 233, 175, 232, 139, 133, 186, 106, 29, 105, 5, 71, 188, 181, 141, 140, 220, 31, 11, 19,
609                        153, 53, 144, 159, 12, 59, 26, 29, 4, 30, 180, 32, 152, 198, 203, 144, 77, 149, 29, 141, 66,
610                        223, 190, 6, 247, 162, 40, 15, 96, 127, 117, 230, 60, 37, 53, 169, 156, 179, 9, 161, 154, 4,
611                        245, 236, 76, 93, 132, 236, 29, 64, 66, 99, 239, 20, 245, 115, 173, 214, 16, 19, 44, 74,
612                    ])),
613                }),
614            })),
615            krb_priv: KrbPriv::from(KrbPrivInner {
616                pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x05])),
617                msg_type: ExplicitContextTag1::from(IntegerAsn1::from(vec![0x15])),
618                enc_part: ExplicitContextTag3::from(EncryptedData {
619                    etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])),
620                    kvno: Optional::from(None),
621                    cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
622                        251, 203, 165, 65, 153, 175, 145, 139, 228, 247, 183, 60, 132, 84, 138, 176, 207, 39, 144, 229,
623                        155, 61, 235, 203, 48, 225, 81, 200, 141, 154, 169, 86, 173, 136, 255, 17, 200, 185, 164, 233,
624                        123, 86, 147, 182, 0, 66, 194, 77, 248, 33, 51, 10, 48, 206, 216, 214, 47, 12, 39, 238, 115,
625                        28, 137, 254, 178, 188, 52, 173, 216, 110, 145, 49, 159,
626                    ])),
627                }),
628            }),
629        };
630
631        let krb_priv_request = KrbPrivMessage::deserialize(&expected_raw as &[u8]).unwrap();
632        let raw_krb_priv_request = picky_asn1_der::to_vec(&krb_priv_request).unwrap();
633
634        assert_eq!(krb_priv_request, expected);
635        assert_eq!(raw_krb_priv_request, expected_raw);
636    }
637
638    #[test]
639    fn krb_priv_response_deserialization() {
640        let expected_raw: [u8; 171] = [
641            0, 171, 0, 1, 0, 83, 111, 81, 48, 79, 160, 3, 2, 1, 5, 161, 3, 2, 1, 15, 162, 67, 48, 65, 160, 3, 2, 1, 18,
642            162, 58, 4, 56, 218, 123, 236, 220, 101, 47, 45, 70, 106, 25, 67, 106, 10, 200, 237, 233, 168, 230, 209,
643            134, 210, 70, 15, 179, 21, 129, 41, 72, 205, 206, 37, 58, 143, 60, 37, 48, 137, 187, 89, 131, 16, 52, 68,
644            37, 60, 28, 215, 252, 225, 97, 29, 147, 62, 127, 19, 216, 117, 80, 48, 78, 160, 3, 2, 1, 5, 161, 3, 2, 1,
645            21, 163, 66, 48, 64, 160, 3, 2, 1, 18, 162, 57, 4, 55, 244, 180, 210, 36, 82, 20, 173, 202, 122, 213, 65,
646            87, 59, 79, 72, 138, 41, 183, 39, 148, 25, 196, 189, 182, 26, 48, 252, 101, 54, 24, 238, 24, 228, 212, 69,
647            37, 151, 225, 49, 193, 172, 32, 236, 245, 125, 139, 33, 149, 71, 31, 65, 220, 230, 121, 86,
648        ];
649        let expected = KrbPrivMessage {
650            ap_message: ApMessage::ApRep(ApRep::from(ApRepInner {
651                pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x05])),
652                msg_type: ExplicitContextTag1::from(IntegerAsn1::from(vec![0x0f])),
653                enc_part: ExplicitContextTag2::from(EncryptedData {
654                    etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])),
655                    kvno: Optional::from(None),
656                    cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
657                        218, 123, 236, 220, 101, 47, 45, 70, 106, 25, 67, 106, 10, 200, 237, 233, 168, 230, 209, 134,
658                        210, 70, 15, 179, 21, 129, 41, 72, 205, 206, 37, 58, 143, 60, 37, 48, 137, 187, 89, 131, 16,
659                        52, 68, 37, 60, 28, 215, 252, 225, 97, 29, 147, 62, 127, 19, 216,
660                    ])),
661                }),
662            })),
663            krb_priv: KrbPriv::from(KrbPrivInner {
664                pvno: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x05])),
665                msg_type: ExplicitContextTag1::from(IntegerAsn1::from(vec![0x15])),
666                enc_part: ExplicitContextTag3::from(EncryptedData {
667                    etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])),
668                    kvno: Optional::from(None),
669                    cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
670                        244, 180, 210, 36, 82, 20, 173, 202, 122, 213, 65, 87, 59, 79, 72, 138, 41, 183, 39, 148, 25,
671                        196, 189, 182, 26, 48, 252, 101, 54, 24, 238, 24, 228, 212, 69, 37, 151, 225, 49, 193, 172, 32,
672                        236, 245, 125, 139, 33, 149, 71, 31, 65, 220, 230, 121, 86,
673                    ])),
674                }),
675            }),
676        };
677
678        let krb_priv_response = KrbPrivMessage::deserialize(&expected_raw as &[u8]).unwrap();
679        let raw_krb_priv_response = picky_asn1_der::to_vec(&krb_priv_response).unwrap();
680
681        assert_eq!(expected, krb_priv_response);
682        assert_eq!(raw_krb_priv_response, expected_raw);
683    }
684
685    #[test]
686    fn kdc_proxy_message() {
687        let expected_raw = [
688            0x30, 0x81, 0xd1, 0xa0, 0x81, 0xbf, 0x04, 0x81, 0xbc, 0x00, 0x00, 0x00, 0xb8, 0x6a, 0x81, 0xb5, 0x30, 0x81,
689            0xb2, 0xa1, 0x03, 0x02, 0x01, 0x05, 0xa2, 0x03, 0x02, 0x01, 0x0a, 0xa3, 0x1a, 0x30, 0x18, 0x30, 0x0a, 0xa1,
690            0x04, 0x02, 0x02, 0x00, 0x96, 0xa2, 0x02, 0x04, 0x00, 0x30, 0x0a, 0xa1, 0x04, 0x02, 0x02, 0x00, 0x95, 0xa2,
691            0x02, 0x04, 0x00, 0xa4, 0x81, 0x89, 0x30, 0x81, 0x86, 0xa0, 0x07, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10,
692            0xa1, 0x13, 0x30, 0x11, 0xa0, 0x03, 0x02, 0x01, 0x01, 0xa1, 0x0a, 0x30, 0x08, 0x1b, 0x06, 0x6d, 0x79, 0x75,
693            0x73, 0x65, 0x72, 0xa2, 0x0d, 0x1b, 0x0b, 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x2e, 0x43, 0x4f, 0x4d,
694            0xa3, 0x20, 0x30, 0x1e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0xa1, 0x17, 0x30, 0x15, 0x1b, 0x06, 0x6b, 0x72, 0x62,
695            0x74, 0x67, 0x74, 0x1b, 0x0b, 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x2e, 0x43, 0x4f, 0x4d, 0xa5, 0x11,
696            0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x31, 0x36, 0x31, 0x38, 0x35, 0x35, 0x31, 0x30, 0x5a, 0xa7,
697            0x06, 0x02, 0x04, 0x22, 0x33, 0xc9, 0xe9, 0xa8, 0x1a, 0x30, 0x18, 0x02, 0x01, 0x12, 0x02, 0x01, 0x11, 0x02,
698            0x01, 0x14, 0x02, 0x01, 0x13, 0x02, 0x01, 0x10, 0x02, 0x01, 0x17, 0x02, 0x01, 0x19, 0x02, 0x01, 0x1a, 0xa1,
699            0x0d, 0x1b, 0x0b, 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x2e, 0x43, 0x4f, 0x4d,
700        ];
701
702        let expected = KdcProxyMessage {
703            kerb_message: ExplicitContextTag0::from(OctetStringAsn1::from(vec![
704                0, 0, 0, 184, 106, 129, 181, 48, 129, 178, 161, 3, 2, 1, 5, 162, 3, 2, 1, 10, 163, 26, 48, 24, 48, 10,
705                161, 4, 2, 2, 0, 150, 162, 2, 4, 0, 48, 10, 161, 4, 2, 2, 0, 149, 162, 2, 4, 0, 164, 129, 137, 48, 129,
706                134, 160, 7, 3, 5, 0, 0, 0, 0, 16, 161, 19, 48, 17, 160, 3, 2, 1, 1, 161, 10, 48, 8, 27, 6, 109, 121,
707                117, 115, 101, 114, 162, 13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 163, 32, 48, 30, 160,
708                3, 2, 1, 2, 161, 23, 48, 21, 27, 6, 107, 114, 98, 116, 103, 116, 27, 11, 69, 88, 65, 77, 80, 76, 69,
709                46, 67, 79, 77, 165, 17, 24, 15, 50, 48, 50, 49, 49, 50, 49, 54, 49, 56, 53, 53, 49, 48, 90, 167, 6, 2,
710                4, 34, 51, 201, 233, 168, 26, 48, 24, 2, 1, 18, 2, 1, 17, 2, 1, 20, 2, 1, 19, 2, 1, 16, 2, 1, 23, 2, 1,
711                25, 2, 1, 26,
712            ])),
713            target_domain: Optional::from(Some(ExplicitContextTag1::from(GeneralStringAsn1::from(
714                Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
715            )))),
716            dclocator_hint: Optional::from(None),
717        };
718
719        let message: KdcProxyMessage = picky_asn1_der::from_bytes(&expected_raw).unwrap();
720        let message_raw = picky_asn1_der::to_vec(&message).unwrap();
721
722        assert_eq!(message, expected);
723        assert_eq!(message_raw, expected_raw);
724    }
725
726    #[test]
727    fn kdc_req() {
728        let expected_raw = vec![
729            48, 129, 178, 161, 3, 2, 1, 5, 162, 3, 2, 1, 10, 163, 26, 48, 24, 48, 10, 161, 4, 2, 2, 0, 150, 162, 2, 4,
730            0, 48, 10, 161, 4, 2, 2, 0, 149, 162, 2, 4, 0, 164, 129, 137, 48, 129, 134, 160, 7, 3, 5, 0, 0, 0, 0, 16,
731            161, 19, 48, 17, 160, 3, 2, 1, 1, 161, 10, 48, 8, 27, 6, 109, 121, 117, 115, 101, 114, 162, 13, 27, 11, 69,
732            88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 163, 32, 48, 30, 160, 3, 2, 1, 2, 161, 23, 48, 21, 27, 6, 107, 114,
733            98, 116, 103, 116, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 165, 17, 24, 15, 50, 48, 50, 49, 49,
734            50, 50, 52, 50, 49, 49, 55, 51, 51, 90, 167, 6, 2, 4, 73, 141, 213, 43, 168, 26, 48, 24, 2, 1, 18, 2, 1,
735            17, 2, 1, 20, 2, 1, 19, 2, 1, 16, 2, 1, 23, 2, 1, 25, 2, 1, 26,
736        ];
737
738        let expected = KdcReq {
739            pvno: ExplicitContextTag1::from(IntegerAsn1(vec![5])),
740            msg_type: ExplicitContextTag2::from(IntegerAsn1(vec![10])),
741            padata: Optional::from(Some(ExplicitContextTag3::from(Asn1SequenceOf(vec![
742                PaData {
743                    padata_type: ExplicitContextTag1::from(IntegerAsn1(vec![0, 150])),
744                    padata_data: ExplicitContextTag2::from(OctetStringAsn1(Vec::new())),
745                },
746                PaData {
747                    padata_type: ExplicitContextTag1::from(IntegerAsn1(vec![0, 149])),
748                    padata_data: ExplicitContextTag2::from(OctetStringAsn1(Vec::new())),
749                },
750            ])))),
751            req_body: ExplicitContextTag4::from(KdcReqBody {
752                kdc_options: ExplicitContextTag0::from(BitStringAsn1::from(BitString::with_bytes(vec![0, 0, 0, 16]))),
753                cname: Optional::from(Some(ExplicitContextTag1::from(PrincipalName {
754                    name_type: ExplicitContextTag0::from(IntegerAsn1(vec![1])),
755                    name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![GeneralStringAsn1::from(
756                        Ia5String::from_string("myuser".to_owned()).unwrap(),
757                    )])),
758                }))),
759                realm: ExplicitContextTag2::from(GeneralStringAsn1::from(
760                    Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
761                )),
762                sname: Optional::from(Some(ExplicitContextTag3::from(PrincipalName {
763                    name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
764                    name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
765                        KerberosStringAsn1::from(Ia5String::from_string("krbtgt".to_owned()).unwrap()),
766                        KerberosStringAsn1::from(Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
767                    ])),
768                }))),
769                from: Optional::from(None),
770                till: ExplicitContextTag5::from(KerberosTime::from(Date::new(2021, 12, 24, 21, 17, 33).unwrap())),
771                rtime: Optional::from(None),
772                nonce: ExplicitContextTag7::from(IntegerAsn1(vec![73, 141, 213, 43])),
773                etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![
774                    IntegerAsn1(vec![18]),
775                    IntegerAsn1(vec![17]),
776                    IntegerAsn1(vec![20]),
777                    IntegerAsn1(vec![19]),
778                    IntegerAsn1(vec![16]),
779                    IntegerAsn1(vec![23]),
780                    IntegerAsn1(vec![25]),
781                    IntegerAsn1(vec![26]),
782                ])),
783                addresses: Optional::from(None),
784                enc_authorization_data: Optional::from(None),
785                additional_tickets: Optional::from(None),
786            }),
787        };
788
789        let kdc_req: KdcReq = picky_asn1_der::from_bytes(&expected_raw).unwrap();
790        let kdc_req_raw = picky_asn1_der::to_vec(&kdc_req).unwrap();
791
792        assert_eq!(expected, kdc_req);
793        assert_eq!(expected_raw, kdc_req_raw);
794    }
795
796    #[test]
797    fn as_req() {
798        let expected_raw = vec![
799            106, 129, 181, 48, 129, 178, 161, 3, 2, 1, 5, 162, 3, 2, 1, 10, 163, 26, 48, 24, 48, 10, 161, 4, 2, 2, 0,
800            150, 162, 2, 4, 0, 48, 10, 161, 4, 2, 2, 0, 149, 162, 2, 4, 0, 164, 129, 137, 48, 129, 134, 160, 7, 3, 5,
801            0, 0, 0, 0, 16, 161, 19, 48, 17, 160, 3, 2, 1, 1, 161, 10, 48, 8, 27, 6, 109, 121, 117, 115, 101, 114, 162,
802            13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 163, 32, 48, 30, 160, 3, 2, 1, 2, 161, 23, 48, 21,
803            27, 6, 107, 114, 98, 116, 103, 116, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 165, 17, 24, 15,
804            50, 48, 50, 49, 49, 50, 50, 57, 49, 48, 51, 54, 48, 54, 90, 167, 6, 2, 4, 29, 32, 235, 11, 168, 26, 48, 24,
805            2, 1, 18, 2, 1, 17, 2, 1, 20, 2, 1, 19, 2, 1, 16, 2, 1, 23, 2, 1, 25, 2, 1, 26,
806        ];
807
808        let expected = AsReq::from(KdcReq {
809            pvno: ExplicitContextTag1::from(IntegerAsn1(vec![5])),
810            msg_type: ExplicitContextTag2::from(IntegerAsn1(vec![10])),
811            padata: Optional::from(Some(ExplicitContextTag3::from(Asn1SequenceOf::from(vec![
812                PaData {
813                    padata_type: ExplicitContextTag1::from(IntegerAsn1(vec![0, 150])),
814                    padata_data: ExplicitContextTag2::from(OctetStringAsn1(Vec::new())),
815                },
816                PaData {
817                    padata_type: ExplicitContextTag1::from(IntegerAsn1(vec![0, 149])),
818                    padata_data: ExplicitContextTag2::from(OctetStringAsn1(Vec::new())),
819                },
820            ])))),
821            req_body: ExplicitContextTag4::from(KdcReqBody {
822                kdc_options: ExplicitContextTag0::from(BitStringAsn1::from(BitString::with_bytes(vec![0, 0, 0, 16]))),
823                cname: Optional::from(Some(ExplicitContextTag1::from(PrincipalName {
824                    name_type: ExplicitContextTag0::from(IntegerAsn1(vec![1])),
825                    name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![GeneralStringAsn1::from(
826                        Ia5String::from_string("myuser".to_owned()).unwrap(),
827                    )])),
828                }))),
829                realm: ExplicitContextTag2::from(GeneralStringAsn1::from(
830                    Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
831                )),
832                sname: Optional::from(Some(ExplicitContextTag3::from(PrincipalName {
833                    name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
834                    name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
835                        KerberosStringAsn1::from(Ia5String::from_string("krbtgt".to_owned()).unwrap()),
836                        KerberosStringAsn1::from(Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
837                    ])),
838                }))),
839                from: Optional::from(None),
840                till: ExplicitContextTag5::from(KerberosTime::from(Date::new(2021, 12, 29, 10, 36, 6).unwrap())),
841                rtime: Optional::from(None),
842                nonce: ExplicitContextTag7::from(IntegerAsn1(vec![29, 32, 235, 11])),
843                etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![
844                    IntegerAsn1(vec![18]),
845                    IntegerAsn1(vec![17]),
846                    IntegerAsn1(vec![20]),
847                    IntegerAsn1(vec![19]),
848                    IntegerAsn1(vec![16]),
849                    IntegerAsn1(vec![23]),
850                    IntegerAsn1(vec![25]),
851                    IntegerAsn1(vec![26]),
852                ])),
853                addresses: Optional::from(None),
854                enc_authorization_data: Optional::from(None),
855                additional_tickets: Optional::from(None),
856            }),
857        });
858
859        let as_req: AsReq = picky_asn1_der::from_bytes(&expected_raw).unwrap();
860        let as_req_raw = picky_asn1_der::to_vec(&as_req).unwrap();
861
862        assert_eq!(expected, as_req);
863        assert_eq!(expected_raw, as_req_raw);
864    }
865
866    #[test]
867    fn as_rep() {
868        let expected_raw = vec![
869            107, 130, 2, 192, 48, 130, 2, 188, 160, 3, 2, 1, 5, 161, 3, 2, 1, 11, 162, 43, 48, 41, 48, 39, 161, 3, 2,
870            1, 19, 162, 32, 4, 30, 48, 28, 48, 26, 160, 3, 2, 1, 18, 161, 19, 27, 17, 69, 88, 65, 77, 80, 76, 69, 46,
871            67, 79, 77, 109, 121, 117, 115, 101, 114, 163, 13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 164,
872            19, 48, 17, 160, 3, 2, 1, 1, 161, 10, 48, 8, 27, 6, 109, 121, 117, 115, 101, 114, 165, 130, 1, 64, 97, 130,
873            1, 60, 48, 130, 1, 56, 160, 3, 2, 1, 5, 161, 13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 162,
874            32, 48, 30, 160, 3, 2, 1, 2, 161, 23, 48, 21, 27, 6, 107, 114, 98, 116, 103, 116, 27, 11, 69, 88, 65, 77,
875            80, 76, 69, 46, 67, 79, 77, 163, 129, 255, 48, 129, 252, 160, 3, 2, 1, 18, 161, 3, 2, 1, 1, 162, 129, 239,
876            4, 129, 236, 229, 108, 127, 175, 235, 22, 11, 195, 254, 62, 101, 153, 38, 64, 83, 27, 109, 35, 253, 196,
877            59, 21, 69, 124, 36, 145, 117, 98, 146, 80, 179, 3, 37, 191, 32, 69, 182, 19, 45, 245, 225, 205, 40, 33,
878            245, 64, 96, 250, 167, 233, 4, 72, 222, 172, 23, 0, 66, 223, 108, 229, 56, 177, 9, 85, 252, 15, 249, 242,
879            189, 240, 4, 45, 235, 72, 169, 207, 81, 60, 129, 61, 66, 191, 142, 254, 11, 231, 111, 219, 21, 155, 126,
880            70, 20, 99, 169, 235, 134, 171, 70, 71, 238, 136, 156, 165, 46, 170, 53, 25, 233, 107, 78, 36, 141, 183,
881            78, 123, 45, 239, 14, 239, 119, 178, 115, 146, 115, 93, 240, 130, 198, 225, 13, 175, 99, 71, 193, 252, 183,
882            41, 77, 109, 158, 237, 159, 185, 164, 103, 132, 248, 223, 55, 201, 44, 74, 25, 130, 188, 76, 255, 128, 199,
883            71, 137, 1, 154, 144, 17, 237, 167, 157, 123, 253, 150, 129, 189, 10, 121, 148, 70, 137, 249, 133, 43, 223,
884            160, 250, 202, 175, 15, 6, 199, 177, 181, 237, 224, 226, 26, 230, 123, 219, 223, 164, 249, 206, 41, 40, 32,
885            190, 14, 3, 196, 163, 41, 56, 118, 157, 114, 87, 233, 89, 178, 246, 74, 224, 43, 207, 53, 131, 32, 78, 111,
886            114, 246, 153, 100, 110, 7, 166, 130, 1, 25, 48, 130, 1, 21, 160, 3, 2, 1, 18, 162, 130, 1, 12, 4, 130, 1,
887            8, 14, 180, 181, 83, 180, 223, 85, 143, 123, 246, 189, 59, 97, 51, 73, 198, 5, 147, 87, 42, 240, 94, 250,
888            203, 240, 45, 46, 190, 32, 135, 13, 24, 123, 127, 223, 30, 53, 200, 226, 164, 80, 207, 227, 34, 63, 139, 3,
889            129, 240, 10, 193, 222, 123, 0, 64, 28, 232, 140, 63, 22, 143, 211, 114, 182, 138, 233, 103, 39, 233, 158,
890            119, 215, 73, 227, 197, 80, 98, 48, 60, 62, 71, 207, 233, 144, 160, 28, 203, 79, 242, 40, 197, 224, 246,
891            84, 9, 184, 188, 250, 231, 190, 97, 255, 41, 234, 238, 213, 203, 3, 192, 160, 220, 78, 78, 197, 45, 255,
892            176, 13, 190, 245, 35, 208, 12, 80, 93, 81, 65, 252, 199, 184, 202, 197, 95, 49, 179, 237, 64, 116, 52,
893            220, 109, 123, 202, 78, 63, 146, 121, 178, 168, 157, 84, 80, 246, 250, 75, 69, 93, 184, 48, 115, 32, 139,
894            4, 90, 164, 30, 208, 100, 37, 220, 168, 165, 2, 224, 124, 102, 164, 130, 34, 66, 134, 131, 16, 7, 206, 32,
895            138, 30, 217, 225, 125, 69, 82, 78, 127, 73, 216, 235, 130, 159, 41, 23, 28, 197, 19, 39, 207, 144, 160,
896            197, 11, 85, 39, 102, 167, 237, 83, 132, 78, 165, 215, 173, 61, 90, 113, 215, 201, 213, 158, 19, 190, 68,
897            135, 94, 136, 63, 105, 119, 225, 127, 193, 148, 33, 74, 41, 154, 68, 104, 52, 227, 188, 19, 62, 26, 55, 15,
898            20, 53, 221, 200, 137, 197, 2, 243,
899        ];
900
901        let expected = AsRep::from(KdcRep {
902            pvno: ExplicitContextTag0::from(IntegerAsn1(vec![5])),
903            msg_type: ExplicitContextTag1::from(IntegerAsn1(vec![11])),
904            padata: Optional::from(Some(ExplicitContextTag2::from(Asn1SequenceOf::from(vec![PaData {
905                padata_type: ExplicitContextTag1::from(IntegerAsn1(vec![19])),
906                padata_data: ExplicitContextTag2::from(OctetStringAsn1(vec![
907                    48, 28, 48, 26, 160, 3, 2, 1, 18, 161, 19, 27, 17, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 109,
908                    121, 117, 115, 101, 114,
909                ])),
910            }])))),
911            crealm: ExplicitContextTag3::from(GeneralStringAsn1::from(
912                Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
913            )),
914            cname: ExplicitContextTag4::from(PrincipalName {
915                name_type: ExplicitContextTag0::from(IntegerAsn1(vec![1])),
916                name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![GeneralStringAsn1::from(
917                    Ia5String::from_string("myuser".to_owned()).unwrap(),
918                )])),
919            }),
920            ticket: ExplicitContextTag5::from(Ticket::from(TicketInner {
921                tkt_vno: ExplicitContextTag0::from(IntegerAsn1(vec![5])),
922                realm: ExplicitContextTag1::from(GeneralStringAsn1::from(
923                    Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
924                )),
925                sname: ExplicitContextTag2::from(PrincipalName {
926                    name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
927                    name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
928                        KerberosStringAsn1::from(Ia5String::from_string("krbtgt".to_owned()).unwrap()),
929                        KerberosStringAsn1::from(Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
930                    ])),
931                }),
932                enc_part: ExplicitContextTag3::from(EncryptedData {
933                    etype: ExplicitContextTag0::from(IntegerAsn1(vec![18])),
934                    kvno: Optional::from(Some(ExplicitContextTag1::from(IntegerAsn1(vec![1])))),
935                    cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
936                        229, 108, 127, 175, 235, 22, 11, 195, 254, 62, 101, 153, 38, 64, 83, 27, 109, 35, 253, 196, 59,
937                        21, 69, 124, 36, 145, 117, 98, 146, 80, 179, 3, 37, 191, 32, 69, 182, 19, 45, 245, 225, 205,
938                        40, 33, 245, 64, 96, 250, 167, 233, 4, 72, 222, 172, 23, 0, 66, 223, 108, 229, 56, 177, 9, 85,
939                        252, 15, 249, 242, 189, 240, 4, 45, 235, 72, 169, 207, 81, 60, 129, 61, 66, 191, 142, 254, 11,
940                        231, 111, 219, 21, 155, 126, 70, 20, 99, 169, 235, 134, 171, 70, 71, 238, 136, 156, 165, 46,
941                        170, 53, 25, 233, 107, 78, 36, 141, 183, 78, 123, 45, 239, 14, 239, 119, 178, 115, 146, 115,
942                        93, 240, 130, 198, 225, 13, 175, 99, 71, 193, 252, 183, 41, 77, 109, 158, 237, 159, 185, 164,
943                        103, 132, 248, 223, 55, 201, 44, 74, 25, 130, 188, 76, 255, 128, 199, 71, 137, 1, 154, 144, 17,
944                        237, 167, 157, 123, 253, 150, 129, 189, 10, 121, 148, 70, 137, 249, 133, 43, 223, 160, 250,
945                        202, 175, 15, 6, 199, 177, 181, 237, 224, 226, 26, 230, 123, 219, 223, 164, 249, 206, 41, 40,
946                        32, 190, 14, 3, 196, 163, 41, 56, 118, 157, 114, 87, 233, 89, 178, 246, 74, 224, 43, 207, 53,
947                        131, 32, 78, 111, 114, 246, 153, 100, 110, 7,
948                    ])),
949                }),
950            })),
951            enc_part: ExplicitContextTag6::from(EncryptedData {
952                etype: ExplicitContextTag0::from(IntegerAsn1(vec![18])),
953                kvno: Optional::from(None),
954                cipher: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
955                    14, 180, 181, 83, 180, 223, 85, 143, 123, 246, 189, 59, 97, 51, 73, 198, 5, 147, 87, 42, 240, 94,
956                    250, 203, 240, 45, 46, 190, 32, 135, 13, 24, 123, 127, 223, 30, 53, 200, 226, 164, 80, 207, 227,
957                    34, 63, 139, 3, 129, 240, 10, 193, 222, 123, 0, 64, 28, 232, 140, 63, 22, 143, 211, 114, 182, 138,
958                    233, 103, 39, 233, 158, 119, 215, 73, 227, 197, 80, 98, 48, 60, 62, 71, 207, 233, 144, 160, 28,
959                    203, 79, 242, 40, 197, 224, 246, 84, 9, 184, 188, 250, 231, 190, 97, 255, 41, 234, 238, 213, 203,
960                    3, 192, 160, 220, 78, 78, 197, 45, 255, 176, 13, 190, 245, 35, 208, 12, 80, 93, 81, 65, 252, 199,
961                    184, 202, 197, 95, 49, 179, 237, 64, 116, 52, 220, 109, 123, 202, 78, 63, 146, 121, 178, 168, 157,
962                    84, 80, 246, 250, 75, 69, 93, 184, 48, 115, 32, 139, 4, 90, 164, 30, 208, 100, 37, 220, 168, 165,
963                    2, 224, 124, 102, 164, 130, 34, 66, 134, 131, 16, 7, 206, 32, 138, 30, 217, 225, 125, 69, 82, 78,
964                    127, 73, 216, 235, 130, 159, 41, 23, 28, 197, 19, 39, 207, 144, 160, 197, 11, 85, 39, 102, 167,
965                    237, 83, 132, 78, 165, 215, 173, 61, 90, 113, 215, 201, 213, 158, 19, 190, 68, 135, 94, 136, 63,
966                    105, 119, 225, 127, 193, 148, 33, 74, 41, 154, 68, 104, 52, 227, 188, 19, 62, 26, 55, 15, 20, 53,
967                    221, 200, 137, 197, 2, 243,
968                ])),
969            }),
970        });
971
972        let as_rep: AsRep = picky_asn1_der::from_bytes(&expected_raw).unwrap();
973        let as_rep_raw = picky_asn1_der::to_vec(&as_rep).unwrap();
974
975        assert_eq!(expected, as_rep);
976        assert_eq!(expected_raw, as_rep_raw);
977    }
978
979    #[test]
980    fn krb_process_tgs_error() {
981        let expected_raw = vec![
982            126, 129, 146, 48, 129, 143, 160, 3, 2, 1, 5, 161, 3, 2, 1, 30, 164, 17, 24, 15, 50, 48, 50, 49, 49, 50,
983            51, 49, 49, 49, 48, 54, 48, 49, 90, 165, 5, 2, 3, 10, 12, 135, 166, 3, 2, 1, 50, 167, 13, 27, 11, 69, 88,
984            65, 77, 80, 76, 69, 46, 67, 79, 77, 168, 19, 48, 17, 160, 3, 2, 1, 1, 161, 10, 48, 8, 27, 6, 109, 121, 117,
985            115, 101, 114, 169, 13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 170, 34, 48, 32, 160, 3, 2, 1,
986            2, 161, 25, 48, 23, 27, 8, 115, 111, 109, 101, 110, 97, 109, 101, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46,
987            67, 79, 77, 171, 13, 27, 11, 80, 82, 79, 67, 69, 83, 83, 95, 84, 71, 83,
988        ];
989
990        let expected = KrbError::from(KrbErrorInner {
991            pvno: ExplicitContextTag0::from(IntegerAsn1(vec![5])),
992            msg_type: ExplicitContextTag1::from(IntegerAsn1(vec![30])),
993            ctime: Optional::from(None),
994            cusec: Optional::from(None),
995            stime: ExplicitContextTag4::from(GeneralizedTimeAsn1::from(Date::new(2021, 12, 31, 11, 6, 1).unwrap())),
996            susec: ExplicitContextTag5::from(IntegerAsn1(vec![0x0a, 0x0c, 0x87])),
997            error_code: ExplicitContextTag6::from(KRB_AP_ERR_INAPP_CKSUM),
998            crealm: Optional::from(Some(ExplicitContextTag7::from(GeneralStringAsn1::from(
999                Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
1000            )))),
1001            cname: Optional::from(Some(ExplicitContextTag8::from(PrincipalName {
1002                name_type: ExplicitContextTag0::from(IntegerAsn1(vec![1])),
1003                name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![GeneralStringAsn1::from(
1004                    Ia5String::from_string("myuser".to_owned()).unwrap(),
1005                )])),
1006            }))),
1007            realm: ExplicitContextTag9::from(GeneralStringAsn1::from(
1008                Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
1009            )),
1010            sname: ExplicitContextTag10::from(PrincipalName {
1011                name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
1012                name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
1013                    KerberosStringAsn1::from(Ia5String::from_string("somename".to_owned()).unwrap()),
1014                    KerberosStringAsn1::from(Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
1015                ])),
1016            }),
1017            e_text: Optional::from(Some(ExplicitContextTag11::from(GeneralStringAsn1::from(
1018                Ia5String::from_string("PROCESS_TGS".to_owned()).unwrap(),
1019            )))),
1020            e_data: Optional::from(None),
1021        });
1022
1023        let krb_error: KrbError = picky_asn1_der::from_bytes(&expected_raw).unwrap();
1024        let krb_error_raw = picky_asn1_der::to_vec(&krb_error).unwrap();
1025
1026        assert_eq!(expected, krb_error);
1027        assert_eq!(expected_raw, krb_error_raw);
1028    }
1029
1030    #[test]
1031    fn krb_client_not_found_error() {
1032        let expected_raw = vec![
1033            126, 129, 151, 48, 129, 148, 160, 3, 2, 1, 5, 161, 3, 2, 1, 30, 164, 17, 24, 15, 50, 48, 50, 49, 49, 50,
1034            50, 56, 49, 51, 52, 48, 49, 49, 90, 165, 5, 2, 3, 12, 139, 242, 166, 3, 2, 1, 6, 167, 13, 27, 11, 69, 88,
1035            65, 77, 80, 76, 69, 46, 67, 79, 77, 168, 21, 48, 19, 160, 3, 2, 1, 1, 161, 12, 48, 10, 27, 8, 98, 97, 100,
1036            95, 117, 115, 101, 114, 169, 13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 170, 32, 48, 30, 160,
1037            3, 2, 1, 2, 161, 23, 48, 21, 27, 6, 107, 114, 98, 116, 103, 116, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46,
1038            67, 79, 77, 171, 18, 27, 16, 67, 76, 73, 69, 78, 84, 95, 78, 79, 84, 95, 70, 79, 85, 78, 68,
1039        ];
1040
1041        let expected = KrbError::from(KrbErrorInner {
1042            pvno: ExplicitContextTag0::from(IntegerAsn1(vec![5])),
1043            msg_type: ExplicitContextTag1::from(IntegerAsn1(vec![30])),
1044            ctime: Optional::from(None),
1045            cusec: Optional::from(None),
1046            stime: ExplicitContextTag4::from(GeneralizedTimeAsn1::from(Date::new(2021, 12, 28, 13, 40, 11).unwrap())),
1047            susec: ExplicitContextTag5::from(IntegerAsn1(vec![12, 139, 242])),
1048            error_code: ExplicitContextTag6::from(KDC_ERR_C_PRINCIPAL_UNKNOWN),
1049            crealm: Optional::from(Some(ExplicitContextTag7::from(GeneralStringAsn1::from(
1050                Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
1051            )))),
1052            cname: Optional::from(Some(ExplicitContextTag8::from(PrincipalName {
1053                name_type: ExplicitContextTag0::from(IntegerAsn1(vec![1])),
1054                name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![GeneralStringAsn1::from(
1055                    Ia5String::from_string("bad_user".to_owned()).unwrap(),
1056                )])),
1057            }))),
1058            realm: ExplicitContextTag9::from(GeneralStringAsn1::from(
1059                Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
1060            )),
1061            sname: ExplicitContextTag10::from(PrincipalName {
1062                name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
1063                name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
1064                    KerberosStringAsn1::from(Ia5String::from_string("krbtgt".to_owned()).unwrap()),
1065                    KerberosStringAsn1::from(Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
1066                ])),
1067            }),
1068            e_text: Optional::from(Some(ExplicitContextTag11::from(GeneralStringAsn1::from(
1069                Ia5String::from_string("CLIENT_NOT_FOUND".to_owned()).unwrap(),
1070            )))),
1071            e_data: Optional::from(None),
1072        });
1073
1074        let krb_error: KrbError = picky_asn1_der::from_bytes(&expected_raw).unwrap();
1075        let krb_error_raw = picky_asn1_der::to_vec(&krb_error).unwrap();
1076
1077        assert_eq!(expected, krb_error);
1078        assert_eq!(expected_raw, krb_error_raw);
1079    }
1080
1081    #[test]
1082    fn tgs_req() {
1083        let expected_raw = vec![
1084            108, 130, 2, 135, 48, 130, 2, 131, 161, 3, 2, 1, 5, 162, 3, 2, 1, 12, 163, 130, 1, 250, 48, 130, 1, 246,
1085            48, 130, 1, 242, 161, 3, 2, 1, 1, 162, 130, 1, 233, 4, 130, 1, 229, 110, 130, 1, 225, 48, 130, 1, 221, 160,
1086            3, 2, 1, 5, 161, 3, 2, 1, 14, 162, 7, 3, 5, 0, 0, 0, 0, 0, 163, 130, 1, 86, 97, 130, 1, 82, 48, 130, 1, 78,
1087            160, 3, 2, 1, 5, 161, 13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 162, 32, 48, 30, 160, 3, 2,
1088            1, 1, 161, 23, 48, 21, 27, 6, 107, 114, 98, 116, 103, 116, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79,
1089            77, 163, 130, 1, 20, 48, 130, 1, 16, 160, 3, 2, 1, 18, 161, 3, 2, 1, 1, 162, 130, 1, 2, 4, 129, 255, 208,
1090            37, 251, 184, 33, 173, 54, 72, 142, 105, 213, 119, 99, 50, 12, 51, 85, 130, 118, 156, 163, 115, 233, 59,
1091            195, 44, 190, 17, 224, 214, 18, 196, 225, 140, 185, 117, 127, 179, 187, 178, 215, 23, 99, 158, 37, 55, 203,
1092            145, 101, 117, 161, 119, 132, 192, 3, 62, 2, 193, 16, 20, 81, 57, 55, 92, 222, 222, 67, 178, 43, 208, 213,
1093            126, 246, 84, 110, 105, 43, 225, 82, 89, 197, 129, 46, 145, 185, 12, 10, 53, 77, 142, 155, 59, 149, 88, 5,
1094            189, 96, 20, 240, 67, 208, 118, 74, 242, 53, 160, 167, 14, 184, 170, 76, 1, 143, 174, 120, 137, 24, 182,
1095            72, 34, 218, 56, 94, 215, 241, 221, 0, 105, 55, 217, 195, 230, 122, 222, 73, 232, 90, 115, 217, 19, 107,
1096            33, 181, 111, 217, 150, 142, 86, 183, 108, 2, 197, 131, 57, 170, 221, 162, 206, 147, 93, 6, 226, 156, 179,
1097            46, 177, 233, 184, 167, 104, 183, 137, 74, 99, 132, 174, 19, 146, 200, 59, 140, 241, 251, 108, 51, 3, 207,
1098            76, 19, 220, 149, 29, 12, 62, 241, 184, 112, 188, 77, 216, 208, 73, 104, 223, 153, 139, 247, 6, 46, 244,
1099            75, 106, 181, 233, 188, 184, 81, 247, 123, 231, 46, 139, 176, 204, 31, 18, 0, 222, 43, 113, 4, 64, 92, 63,
1100            1, 72, 99, 108, 226, 222, 175, 87, 85, 60, 156, 73, 75, 79, 159, 250, 232, 10, 241, 214, 191, 164, 110, 48,
1101            108, 160, 3, 2, 1, 18, 162, 101, 4, 99, 106, 94, 37, 142, 223, 93, 36, 146, 1, 124, 172, 242, 9, 76, 186,
1102            171, 5, 77, 225, 43, 160, 252, 253, 38, 235, 37, 210, 141, 117, 149, 90, 1, 37, 130, 188, 5, 244, 120, 135,
1103            207, 78, 51, 29, 145, 172, 119, 85, 62, 115, 181, 150, 53, 5, 85, 199, 195, 125, 106, 46, 244, 102, 110,
1104            195, 8, 11, 158, 4, 44, 51, 208, 88, 2, 171, 238, 108, 125, 139, 32, 25, 5, 25, 183, 43, 184, 250, 77, 164,
1105            24, 65, 247, 150, 138, 86, 57, 81, 74, 201, 60, 151, 164, 121, 48, 119, 160, 7, 3, 5, 0, 64, 129, 0, 16,
1106            162, 13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 163, 34, 48, 32, 160, 3, 2, 1, 2, 161, 25, 48,
1107            23, 27, 8, 115, 111, 109, 101, 110, 97, 109, 101, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 165,
1108            17, 24, 15, 50, 48, 52, 49, 49, 50, 48, 53, 49, 55, 52, 53, 50, 48, 90, 166, 17, 24, 15, 50, 48, 52, 49,
1109            49, 50, 48, 53, 49, 55, 52, 53, 50, 48, 90, 167, 6, 2, 4, 74, 26, 112, 174, 168, 11, 48, 9, 2, 1, 18, 2, 1,
1110            17, 2, 1, 23,
1111        ];
1112
1113        let expected = TgsReq::from(KdcReq {
1114            pvno: ExplicitContextTag1::from(IntegerAsn1(vec![5])),
1115            msg_type: ExplicitContextTag2::from(IntegerAsn1(vec![12])),
1116            padata: Optional::from(Some(ExplicitContextTag3::from(Asn1SequenceOf::from(vec![PaData {
1117                padata_type: ExplicitContextTag1::from(IntegerAsn1(vec![1])),
1118                padata_data: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
1119                    110, 130, 1, 225, 48, 130, 1, 221, 160, 3, 2, 1, 5, 161, 3, 2, 1, 14, 162, 7, 3, 5, 0, 0, 0, 0, 0,
1120                    163, 130, 1, 86, 97, 130, 1, 82, 48, 130, 1, 78, 160, 3, 2, 1, 5, 161, 13, 27, 11, 69, 88, 65, 77,
1121                    80, 76, 69, 46, 67, 79, 77, 162, 32, 48, 30, 160, 3, 2, 1, 1, 161, 23, 48, 21, 27, 6, 107, 114, 98,
1122                    116, 103, 116, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 163, 130, 1, 20, 48, 130, 1, 16,
1123                    160, 3, 2, 1, 18, 161, 3, 2, 1, 1, 162, 130, 1, 2, 4, 129, 255, 208, 37, 251, 184, 33, 173, 54, 72,
1124                    142, 105, 213, 119, 99, 50, 12, 51, 85, 130, 118, 156, 163, 115, 233, 59, 195, 44, 190, 17, 224,
1125                    214, 18, 196, 225, 140, 185, 117, 127, 179, 187, 178, 215, 23, 99, 158, 37, 55, 203, 145, 101, 117,
1126                    161, 119, 132, 192, 3, 62, 2, 193, 16, 20, 81, 57, 55, 92, 222, 222, 67, 178, 43, 208, 213, 126,
1127                    246, 84, 110, 105, 43, 225, 82, 89, 197, 129, 46, 145, 185, 12, 10, 53, 77, 142, 155, 59, 149, 88,
1128                    5, 189, 96, 20, 240, 67, 208, 118, 74, 242, 53, 160, 167, 14, 184, 170, 76, 1, 143, 174, 120, 137,
1129                    24, 182, 72, 34, 218, 56, 94, 215, 241, 221, 0, 105, 55, 217, 195, 230, 122, 222, 73, 232, 90, 115,
1130                    217, 19, 107, 33, 181, 111, 217, 150, 142, 86, 183, 108, 2, 197, 131, 57, 170, 221, 162, 206, 147,
1131                    93, 6, 226, 156, 179, 46, 177, 233, 184, 167, 104, 183, 137, 74, 99, 132, 174, 19, 146, 200, 59,
1132                    140, 241, 251, 108, 51, 3, 207, 76, 19, 220, 149, 29, 12, 62, 241, 184, 112, 188, 77, 216, 208, 73,
1133                    104, 223, 153, 139, 247, 6, 46, 244, 75, 106, 181, 233, 188, 184, 81, 247, 123, 231, 46, 139, 176,
1134                    204, 31, 18, 0, 222, 43, 113, 4, 64, 92, 63, 1, 72, 99, 108, 226, 222, 175, 87, 85, 60, 156, 73,
1135                    75, 79, 159, 250, 232, 10, 241, 214, 191, 164, 110, 48, 108, 160, 3, 2, 1, 18, 162, 101, 4, 99,
1136                    106, 94, 37, 142, 223, 93, 36, 146, 1, 124, 172, 242, 9, 76, 186, 171, 5, 77, 225, 43, 160, 252,
1137                    253, 38, 235, 37, 210, 141, 117, 149, 90, 1, 37, 130, 188, 5, 244, 120, 135, 207, 78, 51, 29, 145,
1138                    172, 119, 85, 62, 115, 181, 150, 53, 5, 85, 199, 195, 125, 106, 46, 244, 102, 110, 195, 8, 11, 158,
1139                    4, 44, 51, 208, 88, 2, 171, 238, 108, 125, 139, 32, 25, 5, 25, 183, 43, 184, 250, 77, 164, 24, 65,
1140                    247, 150, 138, 86, 57, 81, 74, 201, 60, 151,
1141                ])),
1142            }])))),
1143            req_body: ExplicitContextTag4::from(KdcReqBody {
1144                kdc_options: ExplicitContextTag0::from(KerberosFlags::from(BitString::with_bytes([
1145                    0x40, 0x81, 0x00, 0x10,
1146                ]))),
1147                cname: Optional::from(None),
1148                realm: ExplicitContextTag2::from(Realm::from(
1149                    Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
1150                )),
1151                sname: Optional::from(Some(ExplicitContextTag3::from(PrincipalName {
1152                    name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
1153                    name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
1154                        KerberosStringAsn1::from(Ia5String::from_string("somename".to_owned()).unwrap()),
1155                        KerberosStringAsn1::from(Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
1156                    ])),
1157                }))),
1158                from: Optional::from(None),
1159                till: ExplicitContextTag5::from(KerberosTime::from(Date::new(2041, 12, 5, 17, 45, 20).unwrap())),
1160                rtime: Optional::from(Some(ExplicitContextTag6::from(KerberosTime::from(
1161                    Date::new(2041, 12, 5, 17, 45, 20).unwrap(),
1162                )))),
1163                nonce: ExplicitContextTag7::from(IntegerAsn1(vec![0x4a, 0x1a, 0x70, 0xae])),
1164                etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![
1165                    IntegerAsn1(vec![18]),
1166                    IntegerAsn1(vec![17]),
1167                    IntegerAsn1(vec![23]),
1168                ])),
1169                addresses: Optional::from(None),
1170                enc_authorization_data: Optional::from(None),
1171                additional_tickets: Optional::from(None),
1172            }),
1173        });
1174
1175        let tgs_req: TgsReq = picky_asn1_der::from_bytes(&expected_raw).unwrap();
1176        let tgs_req_raw = picky_asn1_der::to_vec(&tgs_req).unwrap();
1177
1178        assert_eq!(expected, tgs_req);
1179        assert_eq!(expected_raw, tgs_req_raw);
1180    }
1181}