1use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
2use picky_asn1::wrapper::{
3 Asn1SequenceOf, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, ExplicitContextTag3,
4 ExplicitContextTag4, ExplicitContextTag5, ExplicitContextTag6, ExplicitContextTag7, ExplicitContextTag8,
5 ExplicitContextTag9, ExplicitContextTag10, GeneralStringAsn1, GeneralizedTimeAsn1, IntegerAsn1, OctetStringAsn1,
6 Optional,
7};
8use picky_asn1_der::application_tag::ApplicationTag;
9use serde::de::Error;
10use serde::{Deserialize, Deserializer, Serialize, de};
11
12use std::fmt::Debug;
13use std::io::{Read, Write};
14use std::marker::PhantomData;
15use std::{fmt, io};
16
17use crate::constants::types::{
18 AUTHENTICATOR_TYPE, ENC_AP_REP_PART_TYPE, ENC_TICKET_PART_TYPE, KRB_PRIV_ENC_PART, TICKET_TYPE,
19};
20use crate::messages::KrbError;
21
22pub type KerberosStringAsn1 = GeneralStringAsn1;
28
29pub type Realm = KerberosStringAsn1;
31
32#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
41pub struct PrincipalName {
42 pub name_type: ExplicitContextTag0<IntegerAsn1>,
43 pub name_string: ExplicitContextTag1<Asn1SequenceOf<KerberosStringAsn1>>,
44}
45
46pub type KerberosTime = GeneralizedTimeAsn1;
52
53pub type Microseconds = IntegerAsn1;
59
60#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
69pub struct HostAddress {
70 pub addr_type: ExplicitContextTag0<IntegerAsn1>,
71 pub address: ExplicitContextTag1<OctetStringAsn1>,
72}
73
74pub type HostAddresses = Asn1SequenceOf<HostAddress>;
82
83#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
92pub struct AuthorizationDataInner {
93 pub ad_type: ExplicitContextTag0<IntegerAsn1>,
94 pub ad_data: ExplicitContextTag1<OctetStringAsn1>,
95}
96
97pub type AuthorizationData = Asn1SequenceOf<AuthorizationDataInner>;
98
99#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
108pub struct PaData {
109 pub padata_type: ExplicitContextTag1<IntegerAsn1>,
110 pub padata_data: ExplicitContextTag2<OctetStringAsn1>,
111}
112
113pub type KerberosFlags = BitStringAsn1;
119
120#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
130pub struct EncryptedData {
131 pub etype: ExplicitContextTag0<IntegerAsn1>,
132 pub kvno: Optional<Option<ExplicitContextTag1<IntegerAsn1>>>,
133 pub cipher: ExplicitContextTag2<OctetStringAsn1>,
134}
135
136#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
145pub struct EncryptionKey {
146 pub key_type: ExplicitContextTag0<IntegerAsn1>,
147 pub key_value: ExplicitContextTag1<OctetStringAsn1>,
148}
149
150#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
161pub struct TicketInner {
162 pub tkt_vno: ExplicitContextTag0<IntegerAsn1>,
163 pub realm: ExplicitContextTag1<Realm>,
164 pub sname: ExplicitContextTag2<PrincipalName>,
165 pub enc_part: ExplicitContextTag3<EncryptedData>,
166}
167
168pub type Ticket = ApplicationTag<TicketInner, TICKET_TYPE>;
169
170#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
179pub struct TransitedEncoding {
180 pub tr_type: ExplicitContextTag0<IntegerAsn1>,
181 pub contents: ExplicitContextTag1<OctetStringAsn1>,
182}
183
184#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
202pub struct EncTicketPartInner {
203 pub flags: ExplicitContextTag0<KerberosFlags>,
204 pub key: ExplicitContextTag1<EncryptionKey>,
205 pub crealm: ExplicitContextTag2<Realm>,
206 pub cname: ExplicitContextTag3<PrincipalName>,
207 pub transited: ExplicitContextTag4<TransitedEncoding>,
208 pub auth_time: ExplicitContextTag5<KerberosTime>,
209 pub starttime: Optional<Option<ExplicitContextTag6<KerberosTime>>>,
210 pub endtime: ExplicitContextTag7<KerberosTime>,
211 #[serde(default)]
212 pub renew_till: Optional<Option<ExplicitContextTag8<KerberosTime>>>,
213 #[serde(default)]
214 pub caddr: Optional<Option<ExplicitContextTag9<HostAddresses>>>,
215 #[serde(default)]
216 pub authorization_data: Optional<Option<ExplicitContextTag10<AuthorizationData>>>,
217}
218
219pub type EncTicketPart = ApplicationTag<EncTicketPartInner, ENC_TICKET_PART_TYPE>;
220
221#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
230pub struct LastReqInner {
231 pub lr_type: ExplicitContextTag0<IntegerAsn1>,
232 pub lr_value: ExplicitContextTag1<KerberosTime>,
233}
234pub type LastReq = Asn1SequenceOf<LastReqInner>;
235
236#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
245pub struct KerbErrorData {
246 pub data_type: ExplicitContextTag1<IntegerAsn1>,
247 #[serde(default)]
248 pub data_value: Optional<Option<ExplicitContextTag2<BitStringAsn1>>>,
249}
250
251#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
260pub struct PaEncTsEnc {
261 pub patimestamp: ExplicitContextTag0<KerberosTime>,
262 #[serde(default)]
263 pub pausec: Optional<Option<ExplicitContextTag1<Microseconds>>>,
264}
265
266pub type PaEncTimestamp = EncryptedData;
272
273#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
281pub struct KerbPaPacRequest {
282 pub include_pac: ExplicitContextTag0<bool>,
283}
284
285#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
293pub struct PaPacOptions {
294 pub flags: ExplicitContextTag0<KerberosFlags>,
295}
296
297pub type ApOptions = KerberosFlags;
303
304#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
313pub struct Checksum {
314 pub cksumtype: ExplicitContextTag0<IntegerAsn1>,
315 pub checksum: ExplicitContextTag1<OctetStringAsn1>,
316}
317
318#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
334pub struct AuthenticatorInner {
335 pub authenticator_vno: ExplicitContextTag0<IntegerAsn1>,
336 pub crealm: ExplicitContextTag1<Realm>,
337 pub cname: ExplicitContextTag2<PrincipalName>,
338 pub cksum: Optional<Option<ExplicitContextTag3<Checksum>>>,
339 pub cusec: ExplicitContextTag4<Microseconds>,
340 pub ctime: ExplicitContextTag5<KerberosTime>,
341 #[serde(default)]
342 pub subkey: Optional<Option<ExplicitContextTag6<EncryptionKey>>>,
343 #[serde(default)]
344 pub seq_number: Optional<Option<ExplicitContextTag7<IntegerAsn1>>>,
345 #[serde(default)]
346 pub authorization_data: Optional<Option<ExplicitContextTag8<AuthorizationData>>>,
347}
348pub type Authenticator = ApplicationTag<AuthenticatorInner, AUTHENTICATOR_TYPE>;
349
350#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
361pub struct EncApRepPartInner {
362 pub ctime: ExplicitContextTag0<KerberosTime>,
363 pub cusec: ExplicitContextTag1<Microseconds>,
364 #[serde(default)]
365 pub subkey: Optional<Option<ExplicitContextTag2<EncryptionKey>>>,
366 #[serde(default)]
367 pub seq_number: Optional<Option<ExplicitContextTag3<IntegerAsn1>>>,
368}
369pub type EncApRepPart = ApplicationTag<EncApRepPartInner, ENC_AP_REP_PART_TYPE>;
370
371#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
381pub struct EtypeInfo2Entry {
382 pub etype: ExplicitContextTag0<IntegerAsn1>,
383 #[serde(default)]
384 pub salt: Optional<Option<ExplicitContextTag1<KerberosStringAsn1>>>,
385 #[serde(default)]
386 pub s2kparams: Optional<Option<ExplicitContextTag2<OctetStringAsn1>>>,
387}
388
389pub type EtypeInfo2 = Asn1SequenceOf<EtypeInfo2Entry>;
395
396#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
409pub struct EncKrbPrivPartInner {
410 pub user_data: ExplicitContextTag0<OctetStringAsn1>,
411 pub timestamp: Optional<Option<ExplicitContextTag1<KerberosTime>>>,
412 pub usec: Optional<Option<ExplicitContextTag2<KerberosTime>>>,
413 pub seq_number: Optional<Option<ExplicitContextTag3<IntegerAsn1>>>,
414 pub s_address: ExplicitContextTag4<HostAddress>,
415 #[serde(default)]
416 pub r_address: Optional<Option<ExplicitContextTag5<HostAddress>>>,
417}
418
419pub type EncKrbPrivPart = ApplicationTag<EncKrbPrivPartInner, KRB_PRIV_ENC_PART>;
420
421#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
431pub struct ChangePasswdData {
432 pub new_passwd: ExplicitContextTag0<OctetStringAsn1>,
433 pub target_name: Optional<Option<ExplicitContextTag1<PrincipalName>>>,
434 pub target_realm: Optional<Option<ExplicitContextTag2<Realm>>>,
435}
436
437pub trait ResultExt<'a, T>
438where
439 T: Deserialize<'a>,
440{
441 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
442 where
443 D: Deserializer<'a>,
444 Self: Sized;
445}
446
447impl<'de, T: Deserialize<'de>> ResultExt<'de, T> for Result<T, KrbError> {
448 fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
449 where
450 D: Deserializer<'de>,
451 Self: Sized,
452 {
453 struct Visitor<V>(PhantomData<V>);
454
455 impl<'de, V: de::Deserialize<'de>> de::Visitor<'de> for Visitor<V> {
456 type Value = Result<V, KrbError>;
457
458 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
459 formatter.write_str("a valid DER-encoded KbResult")
460 }
461
462 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
463 where
464 A: de::SeqAccess<'de>,
465 {
466 match seq.next_element() {
467 Ok(value) => value
468 .ok_or_else(|| A::Error::missing_field("Missing KrbResult value"))
469 .map(|value| Ok(value)),
470 Err(_) => match seq.next_element() {
471 Ok(error_value) => error_value
472 .ok_or_else(|| A::Error::missing_field("Missing KrbResult value"))
473 .map(|error_value| Err(error_value)),
474 Err(err) => Err(err),
475 },
476 }
477 }
478 }
479
480 deserializer.deserialize_enum("KrbResult", &["Ok", "Err"], Visitor::<T>(PhantomData))
481 }
482}
483
484pub type KrbResult<T> = Result<T, KrbError>;
485
486#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
495pub struct KerbAdRestrictionEntry {
496 pub restriction_type: ExplicitContextTag0<IntegerAsn1>,
497 pub restriction: ExplicitContextTag1<OctetStringAsn1>,
498}
499
500pub const MACHINE_ID_LENGTH: usize = 32;
503
504#[derive(Debug, PartialEq, Eq, Clone)]
514pub struct LsapTokenInfoIntegrity {
515 pub flags: u32,
516 pub token_il: u32,
517 pub machine_id: [u8; MACHINE_ID_LENGTH],
518}
519
520impl LsapTokenInfoIntegrity {
521 pub fn encode(&self, mut to: impl Write) -> io::Result<()> {
522 to.write_u32::<LittleEndian>(self.flags)?;
523 to.write_u32::<LittleEndian>(self.token_il)?;
524 to.write_all(&self.machine_id)?;
525
526 Ok(())
527 }
528
529 pub fn decode(mut from: impl Read) -> io::Result<Self> {
530 let flags = from.read_u32::<LittleEndian>()?;
531 let token_il = from.read_u32::<LittleEndian>()?;
532
533 let mut machine_id = [0; MACHINE_ID_LENGTH];
534 from.read_exact(&mut machine_id)?;
535
536 Ok(Self {
537 flags,
538 token_il,
539 machine_id,
540 })
541 }
542}
543
544#[cfg(test)]
545mod tests {
546 use crate::constants::error_codes::KDC_ERR_C_PRINCIPAL_UNKNOWN;
547 use crate::data_types::{
548 AuthenticatorInner, AuthorizationData, AuthorizationDataInner, Checksum, EncApRepPart, EncApRepPartInner,
549 EncKrbPrivPart, EncKrbPrivPartInner, EncryptedData, EncryptionKey, EtypeInfo2Entry, HostAddress,
550 KerbPaPacRequest, KerberosStringAsn1, KerberosTime, LastReqInner, PaData, PrincipalName,
551 };
552 use crate::messages::{AsReq, KdcReq, KdcReqBody, KrbError, KrbErrorInner};
553 use picky_asn1::bit_string::BitString;
554 use picky_asn1::date::Date;
555 use picky_asn1::restricted_string::Ia5String;
556 use picky_asn1::wrapper::{
557 Asn1SequenceOf, BitStringAsn1, ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2,
558 ExplicitContextTag3, ExplicitContextTag4, ExplicitContextTag5, ExplicitContextTag6, ExplicitContextTag7,
559 ExplicitContextTag8, ExplicitContextTag9, ExplicitContextTag10, ExplicitContextTag11, GeneralStringAsn1,
560 GeneralizedTimeAsn1, IntegerAsn1, OctetStringAsn1, Optional,
561 };
562 use picky_asn1_der::application_tag::ApplicationTag;
563
564 use super::{ChangePasswdData, Microseconds, PaEncTsEnc};
565
566 #[test]
567 fn change_passwd_data() {
568 let expected_raw = [
569 48, 47, 160, 14, 4, 12, 113, 119, 101, 81, 87, 69, 49, 50, 51, 33, 64, 35, 161, 14, 48, 12, 160, 2, 2, 0,
570 161, 6, 48, 4, 27, 2, 101, 51, 162, 13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77,
571 ];
572 let expected = ChangePasswdData {
573 new_passwd: ExplicitContextTag0::from(OctetStringAsn1::from(vec![
575 113, 119, 101, 81, 87, 69, 49, 50, 51, 33, 64, 35,
576 ])),
577 target_name: Optional::from(Some(ExplicitContextTag1::from(PrincipalName {
578 name_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![])),
579 name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![KerberosStringAsn1::from(
580 Ia5String::from_string("e3".into()).unwrap(),
581 )])),
582 }))),
583 target_realm: Optional::from(Some(ExplicitContextTag2::from(KerberosStringAsn1::from(
584 Ia5String::from_string("EXAMPLE.COM".into()).unwrap(),
585 )))),
586 };
587
588 let change_password_data: ChangePasswdData = picky_asn1_der::from_bytes(&expected_raw).unwrap();
589 let raw_change_password_data = picky_asn1_der::to_vec(&change_password_data).unwrap();
590
591 assert_eq!(change_password_data, expected);
592 assert_eq!(raw_change_password_data, expected_raw);
593 }
594
595 #[test]
596 fn enc_krb_priv_part() {
597 let expected_raw = [
598 124, 25, 48, 23, 160, 4, 4, 2, 0, 0, 164, 15, 48, 13, 160, 3, 2, 1, 2, 161, 6, 4, 4, 192, 168, 0, 108,
599 ];
600 let expected = EncKrbPrivPart::from(EncKrbPrivPartInner {
601 user_data: ExplicitContextTag0::from(OctetStringAsn1::from(vec![0, 0])),
602 timestamp: Optional::from(None),
603 usec: Optional::from(None),
604 seq_number: Optional::from(None),
605 s_address: ExplicitContextTag4::from(HostAddress {
606 addr_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x02])),
607 address: ExplicitContextTag1::from(OctetStringAsn1::from(vec![0xc0, 0xa8, 0x00, 0x6c])),
608 }),
609 r_address: Optional::from(None),
610 });
611
612 let enc_krb_priv: EncKrbPrivPart = picky_asn1_der::from_bytes(&expected_raw).unwrap();
613 let raw_enc_krb_priv = picky_asn1_der::to_vec(&enc_krb_priv).unwrap();
614
615 assert_eq!(enc_krb_priv, expected);
616 assert_eq!(raw_enc_krb_priv, expected_raw);
617 }
618
619 #[test]
620 fn kerberos_string_decode() {
621 let expected = [27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77];
623
624 let s: KerberosStringAsn1 = picky_asn1_der::from_bytes(&expected).unwrap();
625 let data = picky_asn1_der::to_vec(&s).unwrap();
626
627 assert_eq!(data, expected);
628 }
629
630 #[test]
631 fn pa_data() {
632 let expected_raw = [
633 48, 39, 161, 3, 2, 1, 19, 162, 32, 4, 30, 48, 28, 48, 26, 160, 3, 2, 1, 18, 161, 19, 27, 17, 69, 88, 65,
634 77, 80, 76, 69, 46, 67, 79, 77, 109, 121, 117, 115, 101, 114,
635 ];
636 let expected = PaData {
637 padata_type: ExplicitContextTag1::from(IntegerAsn1(vec![19])),
638 padata_data: ExplicitContextTag2::from(OctetStringAsn1::from(vec![
639 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,
640 121, 117, 115, 101, 114,
641 ])),
642 };
643
644 let pa_data: PaData = picky_asn1_der::from_bytes(&expected_raw).unwrap();
645 let pa_data_raw = picky_asn1_der::to_vec(&pa_data).unwrap();
646
647 assert_eq!(pa_data, expected);
648 assert_eq!(pa_data_raw, expected_raw);
649 }
650
651 #[test]
652 fn simple_principal_name() {
653 let expected_raw = [
654 48, 17, 160, 3, 2, 1, 1, 161, 10, 48, 8, 27, 6, 109, 121, 117, 115, 101, 114,
655 ];
656 let expected = PrincipalName {
657 name_type: ExplicitContextTag0::from(IntegerAsn1(vec![1])),
658 name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![GeneralStringAsn1::from(
659 Ia5String::from_string("myuser".to_owned()).unwrap(),
660 )])),
661 };
662
663 let principal_name: PrincipalName = picky_asn1_der::from_bytes(&expected_raw).unwrap();
664 let principal_name_raw = picky_asn1_der::to_vec(&principal_name).unwrap();
665
666 assert_eq!(principal_name, expected);
667 assert_eq!(principal_name_raw, expected_raw);
668 }
669
670 #[test]
671 fn principal_name_with_two_names() {
672 let expected_raw = [
673 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, 80,
674 76, 69, 46, 67, 79, 77,
675 ];
676 let expected = PrincipalName {
677 name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
678 name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
679 GeneralStringAsn1::from(Ia5String::from_string("krbtgt".to_owned()).unwrap()),
680 GeneralStringAsn1::from(Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
681 ])),
682 };
683
684 let principal_name: PrincipalName = picky_asn1_der::from_bytes(&expected_raw).unwrap();
685 let principal_name_raw = picky_asn1_der::to_vec(&principal_name).unwrap();
686
687 assert_eq!(principal_name, expected);
688 assert_eq!(principal_name_raw, expected_raw);
689 }
690
691 #[test]
692 fn encrypted_data() {
693 let expected_raw = [
694 48, 129, 252, 160, 3, 2, 1, 18, 161, 3, 2, 1, 1, 162, 129, 239, 4, 129, 236, 166, 11, 233, 202, 198, 160,
695 29, 10, 87, 131, 189, 15, 170, 61, 216, 210, 116, 104, 91, 174, 27, 255, 246, 126, 9, 92, 141, 206, 172,
696 100, 96, 56, 84, 172, 9, 156, 37, 4, 92, 135, 41, 130, 246, 8, 54, 42, 41, 176, 92, 106, 237, 35, 183, 179,
697 141, 35, 17, 246, 38, 42, 131, 226, 151, 25, 155, 134, 251, 197, 4, 209, 223, 122, 135, 145, 113, 169, 139,
698 100, 130, 4, 142, 227, 213, 137, 187, 187, 116, 173, 88, 35, 219, 206, 106, 232, 35, 124, 199, 228, 153,
699 170, 194, 86, 183, 67, 40, 142, 56, 178, 201, 25, 33, 213, 76, 70, 189, 240, 217, 22, 78, 147, 70, 0, 176,
700 78, 67, 33, 216, 37, 52, 200, 21, 104, 186, 190, 171, 60, 13, 250, 138, 135, 27, 159, 235, 29, 163, 193, 2,
701 67, 193, 141, 29, 199, 166, 251, 18, 114, 237, 192, 174, 207, 150, 33, 219, 215, 79, 157, 85, 132, 250,
702 159, 108, 151, 54, 134, 207, 119, 91, 132, 123, 47, 36, 56, 24, 110, 26, 7, 182, 219, 17, 220, 11, 44, 181,
703 227, 25, 25, 244, 14, 56, 130, 82, 227, 114, 54, 167, 75, 202, 140, 245, 136, 61, 29, 22, 247, 154, 5, 33,
704 161, 145, 60, 203, 132, 37, 17, 134, 162, 141, 159, 46, 146, 88, 115, 114, 245, 76, 57,
705 ];
706 let expected = EncryptedData {
707 etype: ExplicitContextTag0::from(IntegerAsn1(vec![18])),
708 kvno: Optional::from(Option::Some(ExplicitContextTag1::from(IntegerAsn1(vec![1])))),
709 cipher: ExplicitContextTag2::from(OctetStringAsn1(vec![
710 166, 11, 233, 202, 198, 160, 29, 10, 87, 131, 189, 15, 170, 61, 216, 210, 116, 104, 91, 174, 27, 255,
711 246, 126, 9, 92, 141, 206, 172, 100, 96, 56, 84, 172, 9, 156, 37, 4, 92, 135, 41, 130, 246, 8, 54, 42,
712 41, 176, 92, 106, 237, 35, 183, 179, 141, 35, 17, 246, 38, 42, 131, 226, 151, 25, 155, 134, 251, 197,
713 4, 209, 223, 122, 135, 145, 113, 169, 139, 100, 130, 4, 142, 227, 213, 137, 187, 187, 116, 173, 88, 35,
714 219, 206, 106, 232, 35, 124, 199, 228, 153, 170, 194, 86, 183, 67, 40, 142, 56, 178, 201, 25, 33, 213,
715 76, 70, 189, 240, 217, 22, 78, 147, 70, 0, 176, 78, 67, 33, 216, 37, 52, 200, 21, 104, 186, 190, 171,
716 60, 13, 250, 138, 135, 27, 159, 235, 29, 163, 193, 2, 67, 193, 141, 29, 199, 166, 251, 18, 114, 237,
717 192, 174, 207, 150, 33, 219, 215, 79, 157, 85, 132, 250, 159, 108, 151, 54, 134, 207, 119, 91, 132,
718 123, 47, 36, 56, 24, 110, 26, 7, 182, 219, 17, 220, 11, 44, 181, 227, 25, 25, 244, 14, 56, 130, 82,
719 227, 114, 54, 167, 75, 202, 140, 245, 136, 61, 29, 22, 247, 154, 5, 33, 161, 145, 60, 203, 132, 37, 17,
720 134, 162, 141, 159, 46, 146, 88, 115, 114, 245, 76, 57,
721 ])),
722 };
723
724 let encrypted_data: EncryptedData = picky_asn1_der::from_bytes(&expected_raw).unwrap();
725 let encrypted_data_raw = picky_asn1_der::to_vec(&encrypted_data).unwrap();
726
727 assert_eq!(encrypted_data, expected);
728 assert_eq!(encrypted_data_raw, expected_raw);
729 }
730
731 #[test]
732 fn encrypted_data_without_kvno() {
733 let expected_raw = [
734 48, 130, 1, 21, 160, 3, 2, 1, 18, 162, 130, 1, 12, 4, 130, 1, 8, 198, 68, 255, 54, 137, 75, 224, 202, 101,
735 33, 67, 17, 110, 98, 71, 39, 211, 155, 248, 29, 67, 235, 64, 135, 38, 247, 252, 121, 38, 244, 112, 7, 92,
736 223, 58, 122, 21, 75, 1, 183, 126, 177, 187, 35, 220, 164, 120, 191, 136, 112, 166, 111, 34, 115, 221, 212,
737 207, 236, 145, 74, 218, 228, 6, 251, 150, 88, 5, 199, 157, 87, 69, 191, 129, 114, 240, 96, 216, 115, 34,
738 43, 124, 147, 144, 154, 148, 221, 49, 107, 4, 38, 242, 48, 80, 144, 188, 74, 23, 0, 113, 223, 172, 60, 185,
739 84, 71, 18, 174, 116, 47, 53, 194, 8, 111, 184, 62, 178, 21, 231, 245, 102, 113, 15, 224, 32, 92, 108, 177,
740 22, 114, 31, 14, 147, 34, 77, 69, 90, 30, 77, 83, 75, 223, 245, 140, 148, 243, 39, 224, 51, 228, 101, 36,
741 221, 5, 255, 184, 46, 254, 218, 229, 175, 41, 207, 229, 107, 247, 160, 6, 83, 91, 1, 77, 195, 201, 148, 27,
742 184, 197, 93, 255, 58, 101, 70, 225, 253, 247, 20, 247, 1, 31, 209, 47, 198, 35, 201, 28, 24, 188, 189,
743 177, 198, 141, 65, 249, 178, 224, 27, 79, 183, 238, 206, 181, 94, 0, 116, 114, 244, 155, 83, 88, 3, 10,
744 223, 2, 215, 133, 201, 99, 136, 211, 56, 105, 144, 140, 196, 232, 216, 54, 173, 195, 10, 92, 161, 233, 13,
745 170, 136, 25, 162, 203, 75, 83, 149, 180, 47, 66, 147, 10, 206, 211, 146, 253, 18, 212, 17,
746 ];
747 let expected = EncryptedData {
748 etype: ExplicitContextTag0::from(IntegerAsn1(vec![18])),
749 kvno: Optional::from(Option::None),
750 cipher: ExplicitContextTag2::from(OctetStringAsn1(vec![
751 198, 68, 255, 54, 137, 75, 224, 202, 101, 33, 67, 17, 110, 98, 71, 39, 211, 155, 248, 29, 67, 235, 64,
752 135, 38, 247, 252, 121, 38, 244, 112, 7, 92, 223, 58, 122, 21, 75, 1, 183, 126, 177, 187, 35, 220, 164,
753 120, 191, 136, 112, 166, 111, 34, 115, 221, 212, 207, 236, 145, 74, 218, 228, 6, 251, 150, 88, 5, 199,
754 157, 87, 69, 191, 129, 114, 240, 96, 216, 115, 34, 43, 124, 147, 144, 154, 148, 221, 49, 107, 4, 38,
755 242, 48, 80, 144, 188, 74, 23, 0, 113, 223, 172, 60, 185, 84, 71, 18, 174, 116, 47, 53, 194, 8, 111,
756 184, 62, 178, 21, 231, 245, 102, 113, 15, 224, 32, 92, 108, 177, 22, 114, 31, 14, 147, 34, 77, 69, 90,
757 30, 77, 83, 75, 223, 245, 140, 148, 243, 39, 224, 51, 228, 101, 36, 221, 5, 255, 184, 46, 254, 218,
758 229, 175, 41, 207, 229, 107, 247, 160, 6, 83, 91, 1, 77, 195, 201, 148, 27, 184, 197, 93, 255, 58, 101,
759 70, 225, 253, 247, 20, 247, 1, 31, 209, 47, 198, 35, 201, 28, 24, 188, 189, 177, 198, 141, 65, 249,
760 178, 224, 27, 79, 183, 238, 206, 181, 94, 0, 116, 114, 244, 155, 83, 88, 3, 10, 223, 2, 215, 133, 201,
761 99, 136, 211, 56, 105, 144, 140, 196, 232, 216, 54, 173, 195, 10, 92, 161, 233, 13, 170, 136, 25, 162,
762 203, 75, 83, 149, 180, 47, 66, 147, 10, 206, 211, 146, 253, 18, 212, 17,
763 ])),
764 };
765
766 let encrypted_data: EncryptedData = picky_asn1_der::from_bytes(&expected_raw).unwrap();
767 let encrypted_data_raw = picky_asn1_der::to_vec(&encrypted_data).unwrap();
768
769 assert_eq!(encrypted_data, expected);
770 assert_eq!(encrypted_data_raw, expected_raw);
771 }
772
773 #[test]
774 fn host_address() {
775 let expected_raw = [
776 0x30, 0x19, 0xa0, 0x03, 0x02, 0x01, 0x14, 0xa1, 0x12, 0x04, 0x10, 0x48, 0x4f, 0x4c, 0x4c, 0x4f, 0x57, 0x42,
777 0x41, 0x53, 0x54, 0x49, 0x4f, 0x4e, 0x20, 0x20, 0x20,
778 ];
779 let expected = HostAddress {
780 addr_type: ExplicitContextTag0::from(IntegerAsn1(vec![20])),
781 address: ExplicitContextTag1::from(OctetStringAsn1(vec![
782 72, 79, 76, 76, 79, 87, 66, 65, 83, 84, 73, 79, 78, 32, 32, 32,
783 ])),
784 };
785
786 let host_address: HostAddress = picky_asn1_der::from_bytes(&expected_raw).unwrap();
787 let host_address_raw = picky_asn1_der::to_vec(&host_address).unwrap();
788
789 assert_eq!(host_address, expected);
790 assert_eq!(host_address_raw, expected_raw);
791 }
792
793 #[test]
794 fn encryption_key() {
795 let expected_raw = [
796 48, 41, 160, 3, 2, 1, 18, 161, 34, 4, 32, 23, 138, 210, 243, 7, 121, 117, 180, 99, 86, 230, 62, 222, 63,
797 251, 46, 242, 161, 37, 67, 254, 103, 199, 93, 74, 174, 166, 64, 17, 198, 242, 144,
798 ];
799 let expected = EncryptionKey {
800 key_type: ExplicitContextTag0::from(IntegerAsn1(vec![18])),
801 key_value: ExplicitContextTag1::from(OctetStringAsn1(vec![
802 23, 138, 210, 243, 7, 121, 117, 180, 99, 86, 230, 62, 222, 63, 251, 46, 242, 161, 37, 67, 254, 103,
803 199, 93, 74, 174, 166, 64, 17, 198, 242, 144,
804 ])),
805 };
806
807 let encryption_key: EncryptionKey = picky_asn1_der::from_bytes(&expected_raw).unwrap();
808 let encryption_key_raw = picky_asn1_der::to_vec(&encryption_key).unwrap();
809
810 assert_eq!(encryption_key, expected);
811 assert_eq!(encryption_key_raw, expected_raw);
812 }
813
814 #[test]
815 fn last_req_inner() {
816 let expected_raw = [
817 48, 24, 160, 3, 2, 1, 0, 161, 17, 24, 15, 49, 57, 55, 48, 48, 49, 48, 49, 48, 48, 48, 48, 48, 48, 90,
818 ];
819 let expected = LastReqInner {
820 lr_type: ExplicitContextTag0::from(IntegerAsn1(vec![0])),
821 lr_value: ExplicitContextTag1::from(KerberosTime::from(Date::new(1970, 1, 1, 0, 0, 0).unwrap())),
822 };
823
824 let last_req_inner: LastReqInner = picky_asn1_der::from_bytes(&expected_raw).unwrap();
825 let last_req_inner_raw = picky_asn1_der::to_vec(&last_req_inner).unwrap();
826
827 assert_eq!(last_req_inner, expected);
828 assert_eq!(last_req_inner_raw, expected_raw);
829 }
830
831 #[test]
832 fn authenticator() {
833 let expected_raw = [
834 98, 130, 1, 14, 48, 130, 1, 10, 160, 3, 2, 1, 5, 161, 13, 27, 11, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79,
835 77, 162, 15, 48, 13, 160, 3, 2, 1, 1, 161, 6, 48, 4, 27, 2, 112, 51, 163, 37, 48, 35, 160, 5, 2, 3, 0, 128,
836 3, 161, 26, 4, 24, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 164, 3, 2, 1,
837 8, 165, 17, 24, 15, 50, 48, 50, 50, 48, 52, 48, 53, 48, 56, 49, 57, 52, 54, 90, 166, 43, 48, 41, 160, 3, 2,
838 1, 18, 161, 34, 4, 32, 137, 180, 229, 144, 148, 18, 158, 111, 110, 0, 13, 63, 21, 116, 77, 186, 198, 9,
839 166, 152, 141, 83, 211, 88, 142, 95, 34, 169, 63, 91, 71, 97, 167, 6, 2, 4, 104, 244, 223, 174, 168, 111,
840 48, 109, 48, 107, 160, 3, 2, 1, 1, 161, 100, 4, 98, 48, 96, 48, 14, 160, 4, 2, 2, 0, 143, 161, 6, 4, 4, 0,
841 64, 0, 0, 48, 78, 160, 4, 2, 2, 0, 144, 161, 70, 4, 68, 84, 0, 69, 0, 82, 0, 77, 0, 83, 0, 82, 0, 86, 0,
842 47, 0, 112, 0, 51, 0, 46, 0, 113, 0, 107, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 46, 0, 99, 0, 111, 0,
843 109, 0, 64, 0, 81, 0, 75, 0, 65, 0, 84, 0, 73, 0, 79, 0, 78, 0, 46, 0, 67, 0, 79, 0, 77, 0,
844 ];
845
846 let expected: ApplicationTag<_, 2> = ApplicationTag(AuthenticatorInner {
847 authenticator_vno: ExplicitContextTag0::from(IntegerAsn1(vec![5])),
848 crealm: ExplicitContextTag1::from(GeneralStringAsn1::from(
849 Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
850 )),
851 cname: ExplicitContextTag2::from(PrincipalName {
852 name_type: ExplicitContextTag0::from(IntegerAsn1(vec![1])),
853 name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![KerberosStringAsn1::from(
854 Ia5String::from_string("p3".to_owned()).unwrap(),
855 )])),
856 }),
857 cksum: Optional::from(Some(ExplicitContextTag3::from(Checksum {
858 cksumtype: ExplicitContextTag0::from(IntegerAsn1(vec![0x00, 0x80, 0x03])),
859 checksum: ExplicitContextTag1::from(OctetStringAsn1::from(vec![
860 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
861 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
862 ])),
863 }))),
864 cusec: ExplicitContextTag4::from(IntegerAsn1::from(vec![0x08])),
865 ctime: ExplicitContextTag5::from(KerberosTime::from(Date::new(2022, 4, 5, 8, 19, 46).unwrap())),
866 subkey: Optional::from(Some(ExplicitContextTag6::from(EncryptionKey {
867 key_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])),
868 key_value: ExplicitContextTag1::from(OctetStringAsn1::from(vec![
869 0x89, 0xB4, 0xE5, 0x90, 0x94, 0x12, 0x9E, 0x6F, 0x6E, 0x00, 0x0D, 0x3F, 0x15, 0x74, 0x4D, 0xBA,
870 0xC6, 0x09, 0xA6, 0x98, 0x8D, 0x53, 0xD3, 0x58, 0x8E, 0x5F, 0x22, 0xA9, 0x3F, 0x5B, 0x47, 0x61,
871 ])),
872 }))),
873 seq_number: Optional::from(Some(ExplicitContextTag7::from(IntegerAsn1::from(vec![
874 0x68, 0xf4, 0xdf, 0xae,
875 ])))),
876 authorization_data: Optional::from(Some(ExplicitContextTag8::from(AuthorizationData::from(vec![
877 AuthorizationDataInner {
878 ad_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x01])),
879 ad_data: ExplicitContextTag1::from(OctetStringAsn1::from(vec![
880 48, 96, 48, 14, 160, 4, 2, 2, 0, 143, 161, 6, 4, 4, 0, 64, 0, 0, 48, 78, 160, 4, 2, 2, 0, 144,
881 161, 70, 4, 68, 84, 0, 69, 0, 82, 0, 77, 0, 83, 0, 82, 0, 86, 0, 47, 0, 112, 0, 51, 0, 46, 0,
882 113, 0, 107, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 46, 0, 99, 0, 111, 0, 109, 0, 64, 0, 81,
883 0, 75, 0, 65, 0, 84, 0, 73, 0, 79, 0, 78, 0, 46, 0, 67, 0, 79, 0, 77, 0,
884 ])),
885 },
886 ])))),
887 });
888
889 let authenticator: ApplicationTag<AuthenticatorInner, 2> = picky_asn1_der::from_bytes(&expected_raw).unwrap();
890 let authenticator_raw = picky_asn1_der::to_vec(&authenticator).unwrap();
891
892 assert_eq!(authenticator, expected);
893 assert_eq!(authenticator_raw, expected_raw);
894 }
895
896 #[test]
897 fn kerb_pa_pac_request() {
898 let expected_raw = [48, 5, 160, 3, 1, 1, 255];
899 let expected = KerbPaPacRequest {
900 include_pac: ExplicitContextTag0::from(true),
901 };
902
903 let kerb_pa_pac_request: KerbPaPacRequest = picky_asn1_der::from_bytes(&expected_raw).unwrap();
904 let kerb_pa_pac_request_raw = picky_asn1_der::to_vec(&kerb_pa_pac_request).unwrap();
905
906 assert_eq!(kerb_pa_pac_request, expected);
907 assert_eq!(kerb_pa_pac_request_raw, expected_raw);
908 }
909
910 #[test]
911 fn etype_info2_entry() {
912 let expected_raw = [
913 48, 22, 160, 3, 2, 1, 18, 161, 15, 27, 13, 69, 88, 65, 77, 80, 76, 69, 46, 67, 79, 77, 112, 51,
914 ];
915 let expected = EtypeInfo2Entry {
916 etype: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])),
917 salt: Optional::from(Some(ExplicitContextTag1::from(KerberosStringAsn1::from(
918 Ia5String::from_string("EXAMPLE.COMp3".to_owned()).unwrap(),
919 )))),
920 s2kparams: Optional::from(None),
921 };
922
923 let etype_info2_entry: EtypeInfo2Entry = picky_asn1_der::from_bytes(&expected_raw).unwrap();
924 let etype_info2_entry_raw = picky_asn1_der::to_vec(&etype_info2_entry).unwrap();
925
926 assert_eq!(etype_info2_entry, expected);
927 assert_eq!(etype_info2_entry_raw, expected_raw);
928 }
929
930 #[test]
931 fn pa_enc_ts_enc() {
932 let expected_raw = vec![
933 48, 24, 160, 17, 24, 15, 50, 48, 50, 50, 48, 52, 48, 53, 48, 56, 49, 57, 52, 54, 90, 161, 3, 2, 1, 32,
934 ];
935 let expected = PaEncTsEnc {
936 patimestamp: ExplicitContextTag0::from(KerberosTime::from(Date::new(2022, 4, 5, 8, 19, 46).unwrap())),
937 pausec: Optional::from(Some(ExplicitContextTag1::from(Microseconds::from(vec![32])))),
938 };
939
940 let pa_enc_ts_enc: PaEncTsEnc = picky_asn1_der::from_bytes(&expected_raw).unwrap();
941 let pa_enc_ts_enc_raw = picky_asn1_der::to_vec(&expected).unwrap();
942
943 assert_eq!(pa_enc_ts_enc, expected);
944 assert_eq!(pa_enc_ts_enc_raw, expected_raw);
945 }
946
947 #[test]
948 fn enc_ap_rep_part() {
949 let expected_raw = vec![
950 123, 79, 48, 77, 160, 17, 24, 15, 50, 48, 50, 50, 48, 52, 48, 57, 49, 49, 49, 54, 52, 52, 90, 161, 3, 2, 1,
951 43, 162, 43, 48, 41, 160, 3, 2, 1, 18, 161, 34, 4, 32, 225, 45, 62, 116, 165, 142, 214, 44, 102, 216, 202,
952 158, 12, 78, 40, 121, 161, 178, 118, 68, 81, 178, 188, 246, 235, 201, 45, 41, 17, 64, 189, 185, 163, 6, 2,
953 4, 74, 244, 122, 62,
954 ];
955 let expected = EncApRepPart::from(EncApRepPartInner {
956 ctime: ExplicitContextTag0::from(KerberosTime::from(Date::new(2022, 4, 9, 11, 16, 44).unwrap())),
957 cusec: ExplicitContextTag1::from(Microseconds::from(vec![0x2b])),
958 subkey: Optional::from(Some(ExplicitContextTag2::from(EncryptionKey {
959 key_type: ExplicitContextTag0::from(IntegerAsn1::from(vec![0x12])),
960 key_value: ExplicitContextTag1::from(OctetStringAsn1::from(vec![
961 0xe1, 0x2d, 0x3e, 0x74, 0xa5, 0x8e, 0xd6, 0x2c, 0x66, 0xd8, 0xca, 0x9e, 0x0c, 0x4e, 0x28, 0x79,
962 0xa1, 0xb2, 0x76, 0x44, 0x51, 0xb2, 0xbc, 0xf6, 0xeb, 0xc9, 0x2d, 0x29, 0x11, 0x40, 0xbd, 0xb9,
963 ])),
964 }))),
965 seq_number: Optional::from(Some(ExplicitContextTag3::from(IntegerAsn1::from(vec![
966 0x4a, 0xf4, 0x7a, 0x3e,
967 ])))),
968 });
969
970 let enc_ap_rep_part: EncApRepPart = picky_asn1_der::from_bytes(&expected_raw).unwrap();
971 let enc_ap_rep_part_raw = picky_asn1_der::to_vec(&expected).unwrap();
972
973 assert_eq!(enc_ap_rep_part, expected);
974 assert_eq!(enc_ap_rep_part_raw, expected_raw);
975 }
976
977 #[test]
978 fn krb_result_decode() {
979 use super::ResultExt;
980 let raw_as_req = vec![
981 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,
982 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,
983 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,
984 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,
985 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,
986 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,
987 2, 1, 18, 2, 1, 17, 2, 1, 20, 2, 1, 19, 2, 1, 16, 2, 1, 23, 2, 1, 25, 2, 1, 26,
988 ];
989 let expected_ap_req = Ok(AsReq::from(KdcReq {
990 pvno: ExplicitContextTag1::from(IntegerAsn1(vec![5])),
991 msg_type: ExplicitContextTag2::from(IntegerAsn1(vec![10])),
992 padata: Optional::from(Some(ExplicitContextTag3::from(Asn1SequenceOf::from(vec![
993 PaData {
994 padata_type: ExplicitContextTag1::from(IntegerAsn1(vec![0, 150])),
995 padata_data: ExplicitContextTag2::from(OctetStringAsn1(Vec::new())),
996 },
997 PaData {
998 padata_type: ExplicitContextTag1::from(IntegerAsn1(vec![0, 149])),
999 padata_data: ExplicitContextTag2::from(OctetStringAsn1(Vec::new())),
1000 },
1001 ])))),
1002 req_body: ExplicitContextTag4::from(KdcReqBody {
1003 kdc_options: ExplicitContextTag0::from(BitStringAsn1::from(BitString::with_bytes(vec![0, 0, 0, 16]))),
1004 cname: Optional::from(Some(ExplicitContextTag1::from(PrincipalName {
1005 name_type: ExplicitContextTag0::from(IntegerAsn1(vec![1])),
1006 name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![GeneralStringAsn1::from(
1007 Ia5String::from_string("myuser".to_owned()).unwrap(),
1008 )])),
1009 }))),
1010 realm: ExplicitContextTag2::from(GeneralStringAsn1::from(
1011 Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
1012 )),
1013 sname: Optional::from(Some(ExplicitContextTag3::from(PrincipalName {
1014 name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
1015 name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
1016 KerberosStringAsn1::from(Ia5String::from_string("krbtgt".to_owned()).unwrap()),
1017 KerberosStringAsn1::from(Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
1018 ])),
1019 }))),
1020 from: Optional::from(None),
1021 till: ExplicitContextTag5::from(KerberosTime::from(Date::new(2021, 12, 29, 10, 36, 6).unwrap())),
1022 rtime: Optional::from(None),
1023 nonce: ExplicitContextTag7::from(IntegerAsn1(vec![29, 32, 235, 11])),
1024 etype: ExplicitContextTag8::from(Asn1SequenceOf::from(vec![
1025 IntegerAsn1(vec![18]),
1026 IntegerAsn1(vec![17]),
1027 IntegerAsn1(vec![20]),
1028 IntegerAsn1(vec![19]),
1029 IntegerAsn1(vec![16]),
1030 IntegerAsn1(vec![23]),
1031 IntegerAsn1(vec![25]),
1032 IntegerAsn1(vec![26]),
1033 ])),
1034 addresses: Optional::from(None),
1035 enc_authorization_data: Optional::from(None),
1036 additional_tickets: Optional::from(None),
1037 }),
1038 }));
1039 let raw_error = vec![
1040 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,
1041 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,
1042 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,
1043 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,
1044 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,
1045 67, 79, 77, 171, 18, 27, 16, 67, 76, 73, 69, 78, 84, 95, 78, 79, 84, 95, 70, 79, 85, 78, 68,
1046 ];
1047 let expected_error = Err(KrbError::from(KrbErrorInner {
1048 pvno: ExplicitContextTag0::from(IntegerAsn1(vec![5])),
1049 msg_type: ExplicitContextTag1::from(IntegerAsn1(vec![30])),
1050 ctime: Optional::from(None),
1051 cusec: Optional::from(None),
1052 stime: ExplicitContextTag4::from(GeneralizedTimeAsn1::from(Date::new(2021, 12, 28, 13, 40, 11).unwrap())),
1053 susec: ExplicitContextTag5::from(IntegerAsn1(vec![12, 139, 242])),
1054 error_code: ExplicitContextTag6::from(KDC_ERR_C_PRINCIPAL_UNKNOWN),
1055 crealm: Optional::from(Some(ExplicitContextTag7::from(GeneralStringAsn1::from(
1056 Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
1057 )))),
1058 cname: Optional::from(Some(ExplicitContextTag8::from(PrincipalName {
1059 name_type: ExplicitContextTag0::from(IntegerAsn1(vec![1])),
1060 name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![GeneralStringAsn1::from(
1061 Ia5String::from_string("bad_user".to_owned()).unwrap(),
1062 )])),
1063 }))),
1064 realm: ExplicitContextTag9::from(GeneralStringAsn1::from(
1065 Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap(),
1066 )),
1067 sname: ExplicitContextTag10::from(PrincipalName {
1068 name_type: ExplicitContextTag0::from(IntegerAsn1(vec![2])),
1069 name_string: ExplicitContextTag1::from(Asn1SequenceOf::from(vec![
1070 KerberosStringAsn1::from(Ia5String::from_string("krbtgt".to_owned()).unwrap()),
1071 KerberosStringAsn1::from(Ia5String::from_string("EXAMPLE.COM".to_owned()).unwrap()),
1072 ])),
1073 }),
1074 e_text: Optional::from(Some(ExplicitContextTag11::from(GeneralStringAsn1::from(
1075 Ia5String::from_string("CLIENT_NOT_FOUND".to_owned()).unwrap(),
1076 )))),
1077 e_data: Optional::from(None),
1078 }));
1079
1080 let mut d = picky_asn1_der::Deserializer::new_from_bytes(&raw_as_req);
1081 let krb_result: Result<AsReq, KrbError> = Result::deserialize(&mut d).unwrap();
1082 assert_eq!(expected_ap_req, krb_result);
1083
1084 let mut d = picky_asn1_der::Deserializer::new_from_bytes(&raw_error);
1085 let krb_result: Result<AsReq, KrbError> = Result::deserialize(&mut d).unwrap();
1086 assert_eq!(expected_error, krb_result);
1087 }
1088}