1use der_parser::asn1_rs::{
4 BitString, Class, Error, FromDer, GeneralString, GeneralizedTime, OptTaggedParser, ParseResult,
5 Sequence, TaggedExplicit, TaggedParser,
6};
7use der_parser::ber::*;
8use nom::combinator::{map, verify};
9use nom::{Err, IResult};
10
11use crate::krb5::*;
12use Class::ContextSpecific as CS;
13
14#[inline]
21pub fn parse_der_int32(i: &[u8]) -> IResult<&[u8], i32, Error> {
22 i32::from_der(i)
23}
24
25fn parse_der_microseconds(i: &[u8]) -> IResult<&[u8], u32, Error> {
28 verify(u32::from_der, |x: &u32| *x <= 999_999)(i)
29}
30
31pub fn parse_kerberos_string(i: &[u8]) -> IResult<&[u8], String, Error> {
37 map(GeneralString::from_der, |s| s.string())(i)
38}
39
40fn parse_kerberos_string_sequence(i: &[u8]) -> IResult<&[u8], Vec<String>, Error> {
41 parse_ber_sequence_of_v(parse_kerberos_string)(i)
42}
43
44#[inline]
52pub fn parse_kerberos_flags(i: &[u8]) -> IResult<&[u8], BitString, Error> {
53 BitString::from_der(i)
54}
55
56impl<'a> FromDer<'a> for Realm {
62 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self> {
63 map(parse_kerberos_string, Realm)(bytes)
64 }
65}
66
67#[inline]
68pub fn parse_krb5_realm(i: &[u8]) -> IResult<&[u8], Realm, Error> {
69 Realm::from_der(i)
70}
71
72#[deprecated(
81 since = "0.8.0",
82 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
83)]
84#[inline]
85pub fn parse_krb5_principalname(i: &[u8]) -> IResult<&[u8], PrincipalName, Error> {
86 PrincipalName::from_der(i)
87}
88
89impl<'a> FromDer<'a> for PrincipalName {
98 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self> {
99 Sequence::from_der_and_then(bytes, |i| {
100 let (i, name_type) = TaggedParser::from_der_and_then(CS, 0, i, i32::from_der)?;
101 let name_type = NameType(name_type);
102 let (i, name_string) =
103 TaggedParser::from_der_and_then(CS, 1, i, parse_kerberos_string_sequence)?;
104 Ok((
105 i,
106 PrincipalName {
107 name_type,
108 name_string,
109 },
110 ))
111 })
112 }
113}
114
115#[inline]
121pub fn parse_kerberos_time(i: &[u8]) -> IResult<&[u8], GeneralizedTime, Error> {
122 GeneralizedTime::from_der(i)
123}
124
125#[deprecated(
134 since = "0.8.0",
135 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
136)]
137#[inline]
138pub fn parse_krb5_hostaddress(i: &[u8]) -> IResult<&[u8], HostAddress, Error> {
139 HostAddress::from_der(i)
140}
141
142impl<'a> FromDer<'a> for HostAddress<'a> {
143 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self> {
144 Sequence::from_der_and_then(bytes, |i| {
145 let (i, addr_type) = TaggedParser::from_der_and_then(CS, 0, i, i32::from_der)?;
146 let addr_type = AddressType(addr_type);
147 let (i, address) = TaggedParser::from_der_and_then(CS, 1, i, <&[u8]>::from_der)?;
148 Ok((i, HostAddress { addr_type, address }))
149 })
150 }
151}
152
153pub fn parse_krb5_hostaddresses(i: &[u8]) -> IResult<&[u8], Vec<HostAddress>, Error> {
163 parse_ber_sequence_of_v(HostAddress::from_der)(i)
164}
165
166#[deprecated(
177 since = "0.8.0",
178 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
179)]
180#[inline]
181pub fn parse_krb5_ticket(i: &[u8]) -> IResult<&[u8], Ticket, Error> {
182 Ticket::from_der(i)
183}
184
185impl<'a> FromDer<'a> for Ticket<'a> {
186 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, Error> {
187 TaggedParser::from_der_and_then(Class::Application, 1, bytes, |inner| {
188 Sequence::from_der_and_then(inner, |i| {
189 let (i, tkt_vno) = TaggedParser::from_der_and_then(CS, 0, i, u32::from_der)?;
190 if tkt_vno != 5 {
191 return Err(Err::Error(Error::invalid_value(
192 Tag::Sequence,
193 "Invalid Kerberos version (not 5)".to_string(),
194 )));
195 }
196 let (i, realm) = TaggedParser::from_der_and_then(CS, 1, i, Realm::from_der)?;
197 let (i, sname) =
198 TaggedParser::from_der_and_then(CS, 2, i, PrincipalName::from_der)?;
199 let (i, enc_part) =
200 TaggedParser::from_der_and_then(CS, 3, i, EncryptedData::from_der)?;
201 let tkt = Ticket {
202 tkt_vno,
203 realm,
204 sname,
205 enc_part,
206 };
207 Ok((i, tkt))
208 })
209 })
210 }
211}
212
213#[deprecated(
223 since = "0.8.0",
224 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
225)]
226#[inline]
227pub fn parse_encrypted(i: &[u8]) -> IResult<&[u8], EncryptedData, Error> {
228 EncryptedData::from_der(i)
229}
230
231impl<'a> FromDer<'a> for EncryptedData<'a> {
232 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, Error> {
233 Sequence::from_der_and_then(bytes, |i| {
234 let (i, etype) = TaggedParser::from_der_and_then(CS, 0, i, i32::from_der)?;
235 let etype = EncryptionType(etype);
236 let (i, kvno) =
237 OptTaggedParser::new(CS, Tag(1)).parse_der(i, |_, data| u32::from_der(data))?;
238 let (i, cipher) = TaggedParser::from_der_and_then(CS, 2, i, <&[u8]>::from_der)?;
239 let enc = EncryptedData {
240 etype,
241 kvno,
242 cipher,
243 };
244 Ok((i, enc))
245 })
246 }
247}
248
249#[deprecated(
262 since = "0.8.0",
263 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
264)]
265#[inline]
266pub fn parse_kdc_req(i: &[u8]) -> IResult<&[u8], KdcReq, Error> {
267 KdcReq::from_der(i)
268}
269
270impl<'a> FromDer<'a> for KdcReq<'a> {
283 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, Error> {
284 Sequence::from_der_and_then(bytes, |i| {
285 let (i, pvno) = TaggedParser::from_der_and_then(CS, 1, i, u32::from_der)?;
286 let (i, msg_type) = TaggedParser::from_der_and_then(CS, 2, i, u32::from_der)?;
287 let msg_type = MessageType(msg_type);
288 let (i, padata) = OptTaggedParser::new(CS, Tag(3))
289 .parse_der(i, |_, data| parse_krb5_padata_sequence(data))?;
290 let padata = padata.unwrap_or_default();
291 let (i, req_body) = TaggedParser::from_der_and_then(CS, 4, i, KdcReqBody::from_der)?;
292 let req = KdcReq {
293 pvno,
294 msg_type,
295 padata,
296 req_body,
297 };
298 Ok((i, req))
299 })
300 }
301}
302
303#[deprecated(
304 since = "0.8.0",
305 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
306)]
307#[inline]
308pub fn parse_kdc_req_body(i: &[u8]) -> IResult<&[u8], KdcReqBody, Error> {
309 KdcReqBody::from_der(i)
310}
311
312impl<'a> FromDer<'a> for KdcReqBody<'a> {
337 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, Error> {
338 Sequence::from_der_and_then(bytes, |i| {
339 let (i, kdc_options) = TaggedParser::from_der_and_then(CS, 0, i, parse_kerberos_flags)?;
340 let (i, cname) = OptTaggedParser::new(CS, Tag(1))
341 .parse_der(i, |_, data| PrincipalName::from_der(data))?;
342 let (i, realm) = TaggedParser::from_der_and_then(CS, 2, i, Realm::from_der)?;
343 let (i, sname) = OptTaggedParser::new(CS, Tag(3))
344 .parse_der(i, |_, data| PrincipalName::from_der(data))?;
345 let (i, from) = OptTaggedParser::new(CS, Tag(4))
346 .parse_der(i, |_, data| parse_kerberos_time(data))?;
347 let (i, till) = TaggedParser::from_der_and_then(CS, 5, i, parse_kerberos_time)?;
348 let (i, rtime) = OptTaggedParser::new(CS, Tag(6))
349 .parse_der(i, |_, data| parse_kerberos_time(data))?;
350 let (i, nonce) = TaggedParser::from_der_and_then(CS, 7, i, u32::from_der)?;
351 let (i, etype) = TaggedParser::from_der_and_then(CS, 8, i, |data| {
352 let (rem, v) = <Vec<i32>>::from_der(data)?;
353 let v = v.iter().map(|&e| EncryptionType(e)).collect();
354 Ok((rem, v))
355 })?;
356 let (i, addresses) = OptTaggedParser::new(CS, Tag(9))
357 .parse_der(i, |_, data| parse_krb5_hostaddresses(data))?;
358 let addresses = addresses.unwrap_or_default();
359 let (i, enc_authorization_data) = OptTaggedParser::new(CS, Tag(10))
360 .parse_der(i, |_, data| EncryptedData::from_der(data))?;
361 let (i, additional_tickets) = OptTaggedParser::new(CS, Tag(11))
362 .parse_der(i, |_, data| <Vec<Ticket>>::from_der(data))?;
363 let additional_tickets = additional_tickets.unwrap_or_default();
364 let body = KdcReqBody {
365 kdc_options,
366 cname,
367 realm,
368 sname,
369 from,
370 till,
371 rtime,
372 nonce,
373 etype,
374 addresses,
375 enc_authorization_data,
376 additional_tickets,
377 };
378 Ok((i, body))
379 })
380 }
381}
382
383pub fn parse_as_req(i: &[u8]) -> IResult<&[u8], KdcReq, Error> {
389 TaggedParser::from_der_and_then(Class::Application, 10, i, KdcReq::from_der)
390}
391
392pub fn parse_tgs_req(i: &[u8]) -> IResult<&[u8], KdcReq, Error> {
398 TaggedParser::from_der_and_then(Class::Application, 12, i, KdcReq::from_der)
399}
400
401#[deprecated(
418 since = "0.8.0",
419 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
420)]
421#[inline]
422pub fn parse_kdc_rep(i: &[u8]) -> IResult<&[u8], KdcRep, Error> {
423 KdcRep::from_der(i)
424}
425
426impl<'a> FromDer<'a> for KdcRep<'a> {
443 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, Error> {
444 Sequence::from_der_and_then(bytes, |i| {
445 let (i, pvno) = TaggedParser::from_der_and_then(CS, 0, i, u32::from_der)?;
446 let (i, msg_type) = TaggedParser::from_der_and_then(CS, 1, i, u32::from_der)?;
447 let msg_type = MessageType(msg_type);
448 let (i, padata) = OptTaggedParser::new(CS, Tag(2))
449 .parse_der(i, |_, data| parse_krb5_padata_sequence(data))?;
450 let padata = padata.unwrap_or_default();
451 let (i, crealm) = TaggedParser::from_der_and_then(CS, 3, i, Realm::from_der)?;
452 let (i, cname) = TaggedParser::from_der_and_then(CS, 4, i, PrincipalName::from_der)?;
453 let (i, ticket) = TaggedParser::from_der_and_then(CS, 5, i, Ticket::from_der)?;
454 let (i, enc_part) = TaggedParser::from_der_and_then(CS, 6, i, EncryptedData::from_der)?;
455 let rep = KdcRep {
456 pvno,
457 msg_type,
458 padata,
459 crealm,
460 cname,
461 ticket,
462 enc_part,
463 };
464 Ok((i, rep))
465 })
466 }
467}
468
469pub fn parse_as_rep(i: &[u8]) -> IResult<&[u8], KdcRep, Error> {
475 TaggedParser::from_der_and_then(Class::Application, 11, i, KdcRep::from_der)
476}
477
478pub fn parse_tgs_rep(i: &[u8]) -> IResult<&[u8], KdcRep, Error> {
484 TaggedParser::from_der_and_then(Class::Application, 13, i, KdcRep::from_der)
485}
486
487#[deprecated(
507 since = "0.8.0",
508 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
509)]
510#[inline]
511pub fn parse_krb_error(i: &[u8]) -> IResult<&[u8], KrbError, Error> {
512 KrbError::from_der(i)
513}
514
515impl<'a> FromDer<'a> for KrbError<'a> {
535 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, Error> {
536 TaggedParser::from_der_and_then(Class::Application, 30, bytes, |inner| {
537 Sequence::from_der_and_then(inner, |i| {
538 let (i, pvno) = TaggedParser::from_der_and_then(CS, 0, i, u32::from_der)?;
539 let (i, msg_type) = TaggedParser::from_der_and_then(CS, 1, i, u32::from_der)?;
540 let msg_type = MessageType(msg_type);
541 let (i, ctime) = OptTaggedParser::new(CS, Tag(2))
542 .parse_der(i, |_, data| parse_kerberos_time(data))?;
543 let (i, cusec) = OptTaggedParser::new(CS, Tag(3))
544 .parse_der(i, |_, data| parse_der_microseconds(data))?;
545 let (i, stime) = TaggedParser::from_der_and_then(CS, 4, i, parse_kerberos_time)?;
546 let (i, susec) = TaggedParser::from_der_and_then(CS, 5, i, parse_der_microseconds)?;
547 let (i, error_code) = TaggedParser::from_der_and_then(CS, 6, i, i32::from_der)?;
548 let error_code = ErrorCode(error_code);
549 let (i, crealm) = OptTaggedParser::new(CS, Tag(7))
550 .parse_der(i, |_, data| Realm::from_der(data))?;
551 let (i, cname) = OptTaggedParser::new(CS, Tag(8))
552 .parse_der(i, |_, data| PrincipalName::from_der(data))?;
553 let (i, realm) = TaggedParser::from_der_and_then(CS, 9, i, Realm::from_der)?;
554 let (i, sname) =
555 TaggedParser::from_der_and_then(CS, 10, i, PrincipalName::from_der)?;
556 let (i, etext) = OptTaggedParser::new(CS, Tag(11))
557 .parse_der(i, |_, data| parse_kerberos_string(data))?;
558 let (i, edata) = OptTaggedParser::new(CS, Tag(12))
559 .parse_der(i, |_, data| <&[u8]>::from_der(data))?;
560 let err = KrbError {
561 pvno,
562 msg_type,
563 ctime,
564 cusec,
565 stime,
566 susec,
567 error_code,
568 crealm,
569 cname,
570 realm,
571 sname,
572 etext,
573 edata,
574 };
575 Ok((i, err))
576 })
577 })
578 }
579}
580
581#[deprecated(
591 since = "0.8.0",
592 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
593)]
594#[inline]
595pub fn parse_krb5_padata(i: &[u8]) -> IResult<&[u8], PAData, Error> {
596 PAData::from_der(i)
597}
598
599impl<'a> FromDer<'a> for PAData<'a> {
609 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, Error> {
610 Sequence::from_der_and_then(bytes, |i| {
611 let (i, padata_type) = TaggedParser::from_der_and_then(CS, 1, i, i32::from_der)?;
612 let padata_type = PAType(padata_type);
613 let (i, padata_value) = TaggedParser::from_der_and_then(CS, 2, i, <&[u8]>::from_der)?;
614 let padata = PAData {
615 padata_type,
616 padata_value,
617 };
618 Ok((i, padata))
619 })
620 }
621}
622
623fn parse_krb5_padata_sequence(i: &[u8]) -> IResult<&[u8], Vec<PAData>, Error> {
624 parse_ber_sequence_of_v(PAData::from_der)(i)
625}
626
627#[deprecated(
644 since = "0.8.0",
645 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
646)]
647#[inline]
648pub fn parse_ap_req(i: &[u8]) -> IResult<&[u8], ApReq, Error> {
649 ApReq::from_der(i)
650}
651
652impl<'a> FromDer<'a> for ApReq<'a> {
669 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, Error> {
670 TaggedParser::from_der_and_then(Class::Application, 14, bytes, |inner| {
671 Sequence::from_der_and_then(inner, |i| {
672 let (i, pvno) = TaggedParser::from_der_and_then(CS, 0, i, u32::from_der)?;
673 let (i, msg_type) = TaggedParser::from_der_and_then(CS, 1, i, u32::from_der)?;
674 let msg_type = MessageType(msg_type);
675 let (i, ap_options) =
676 TaggedParser::from_der_and_then(CS, 2, i, parse_kerberos_flags)?;
677 let (i, ticket) = TaggedParser::from_der_and_then(CS, 3, i, Ticket::from_der)?;
678 let (i, authenticator) =
679 TaggedParser::from_der_and_then(CS, 4, i, EncryptedData::from_der)?;
680 let req = ApReq {
681 pvno,
682 msg_type,
683 ap_options,
684 ticket,
685 authenticator,
686 };
687 Ok((i, req))
688 })
689 })
690 }
691}
692
693#[deprecated(
703 since = "0.8.0",
704 note = "Parsing functions are deprecated. Users should instead use the FromDer trait"
705)]
706#[inline]
707pub fn parse_ap_rep(i: &[u8]) -> IResult<&[u8], ApRep, Error> {
708 ApRep::from_der(i)
709}
710
711impl<'a> FromDer<'a> for ApRep<'a> {
721 fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, Error> {
722 TaggedParser::from_der_and_then(Class::Application, 15, bytes, |inner| {
723 Sequence::from_der_and_then(inner, |i| {
724 let (i, pvno) = TaggedExplicit::<u32, Error, 0>::from_der(i)?;
725 let (i, msg_type) = map(TaggedExplicit::<u32, Error, 1>::from_der, |m| {
726 MessageType(m.into_inner())
727 })(i)?;
728 let (i, enc_part) =
729 TaggedParser::from_der_and_then(CS, 2, i, EncryptedData::from_der)?;
730 let rep = ApRep {
731 pvno: pvno.into_inner(),
732 msg_type,
733 enc_part,
734 };
735 Ok((i, rep))
736 })
737 })
738 }
739}