kerberos_parser/
krb5_parser.rs

1//! Kerberos 5 parsing functions
2
3use 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/// Parse a signed 32 bits integer
15///
16/// <pre>
17/// Int32           ::= INTEGER (-2147483648..2147483647)
18///                     -- signed values representable in 32 bits
19/// </pre>
20#[inline]
21pub fn parse_der_int32(i: &[u8]) -> IResult<&[u8], i32, Error> {
22    i32::from_der(i)
23}
24
25//  Microseconds    ::= INTEGER (0..999999)
26//                      -- microseconds
27fn parse_der_microseconds(i: &[u8]) -> IResult<&[u8], u32, Error> {
28    verify(u32::from_der, |x: &u32| *x <= 999_999)(i)
29}
30
31/// Parse a Kerberos string object
32///
33/// <pre>
34/// KerberosString  ::= GeneralString (IA5String)
35/// </pre>
36pub 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/// Parse Kerberos flags
45///
46/// <pre>
47/// KerberosFlags   ::= BIT STRING (SIZE (32..MAX))
48///                     -- minimum number of bits shall be sent,
49///                     -- but no fewer than 32
50/// </pre>
51#[inline]
52pub fn parse_kerberos_flags(i: &[u8]) -> IResult<&[u8], BitString, Error> {
53    BitString::from_der(i)
54}
55
56/// Parse a Kerberos Realm
57///
58/// <pre>
59/// Realm           ::= KerberosString
60/// </pre>
61impl<'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/// Parse Kerberos PrincipalName
73///
74/// <pre>
75/// PrincipalName   ::= SEQUENCE {
76///         name-type       [0] Int32,
77///         name-string     [1] SEQUENCE OF KerberosString
78/// }
79/// </pre>
80#[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
89/// Parse Kerberos PrincipalName
90///
91/// <pre>
92/// PrincipalName   ::= SEQUENCE {
93///         name-type       [0] Int32,
94///         name-string     [1] SEQUENCE OF KerberosString
95/// }
96/// </pre>
97impl<'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/// Parse a Kerberos Time
116///
117/// <pre>
118/// KerberosTime    ::= GeneralizedTime -- with no fractional seconds
119/// </pre>
120#[inline]
121pub fn parse_kerberos_time(i: &[u8]) -> IResult<&[u8], GeneralizedTime, Error> {
122    GeneralizedTime::from_der(i)
123}
124
125/// Parse Kerberos HostAddress
126///
127/// <pre>
128/// HostAddress     ::= SEQUENCE  {
129///         addr-type       [0] Int32,
130///         address         [1] OCTET STRING
131/// }
132/// </pre>
133#[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
153/// Parse Kerberos HostAddresses
154///
155/// <pre>
156/// -- NOTE: HostAddresses is always used as an OPTIONAL field and
157/// -- should not be empty.
158/// HostAddresses   -- NOTE: subtly different from rfc1510,
159///                 -- but has a value mapping and encodes the same
160///         ::= SEQUENCE OF HostAddress
161/// </pre>
162pub fn parse_krb5_hostaddresses(i: &[u8]) -> IResult<&[u8], Vec<HostAddress>, Error> {
163    parse_ber_sequence_of_v(HostAddress::from_der)(i)
164}
165
166/// Parse Kerberos Ticket
167///
168/// <pre>
169/// Ticket          ::= [APPLICATION 1] SEQUENCE {
170///         tkt-vno         [0] INTEGER (5),
171///         realm           [1] Realm,
172///         sname           [2] PrincipalName,
173///         enc-part        [3] EncryptedData -- EncTicketPart
174/// }
175/// </pre>
176#[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/// Parse Kerberos EncryptedData
214///
215/// <pre>
216/// EncryptedData   ::= SEQUENCE {
217///         etype   [0] Int32 -- EncryptionType --,
218///         kvno    [1] UInt32 OPTIONAL,
219///         cipher  [2] OCTET STRING -- ciphertext
220/// }
221/// </pre>
222#[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/// Parse a Kerberos KDC Request
250///
251/// <pre>
252/// KDC-REQ         ::= SEQUENCE {
253///         -- NOTE: first tag is [1], not [0]
254///         pvno            [1] INTEGER (5) ,
255///         msg-type        [2] INTEGER (10 -- AS -- | 12 -- TGS --),
256///         padata          [3] SEQUENCE OF PA-DATA OPTIONAL
257///                             -- NOTE: not empty --,
258///         req-body        [4] KDC-REQ-BODY
259/// }
260/// </pre>
261#[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
270/// Parse a Kerberos KDC Request
271///
272/// <pre>
273/// KDC-REQ         ::= SEQUENCE {
274///         -- NOTE: first tag is [1], not [0]
275///         pvno            [1] INTEGER (5) ,
276///         msg-type        [2] INTEGER (10 -- AS -- | 12 -- TGS --),
277///         padata          [3] SEQUENCE OF PA-DATA OPTIONAL
278///                             -- NOTE: not empty --,
279///         req-body        [4] KDC-REQ-BODY
280/// }
281/// </pre>
282impl<'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
312/// Parse the body of a Kerberos KDC Request
313///
314/// <pre>
315/// KDC-REQ-BODY    ::= SEQUENCE {
316///         kdc-options             [0] KDCOptions,
317///         cname                   [1] PrincipalName OPTIONAL
318///                                     -- Used only in AS-REQ --,
319///         realm                   [2] Realm
320///                                     -- Server's realm
321///                                     -- Also client's in AS-REQ --,
322///         sname                   [3] PrincipalName OPTIONAL,
323///         from                    [4] KerberosTime OPTIONAL,
324///         till                    [5] KerberosTime,
325///         rtime                   [6] KerberosTime OPTIONAL,
326///         nonce                   [7] UInt32,
327///         etype                   [8] SEQUENCE OF Int32 -- EncryptionType
328///                                     -- in preference order --,
329///         addresses               [9] HostAddresses OPTIONAL,
330///         enc-authorization-data  [10] EncryptedData OPTIONAL
331///                                     -- AuthorizationData --,
332///         additional-tickets      [11] SEQUENCE OF Ticket OPTIONAL
333///                                        -- NOTE: not empty
334/// }
335/// </pre>
336impl<'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
383/// Parse a Kerberos AS Request
384///
385/// <pre>
386/// AS-REQ          ::= [APPLICATION 10] KDC-REQ
387/// </pre>
388pub 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
392/// Parse a Kerberos TGS Request
393///
394/// <pre>
395/// TGS-REQ          ::= [APPLICATION 12] KDC-REQ
396/// </pre>
397pub 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/// Parse a Kerberos KDC Reply
402///
403/// <pre>
404/// KDC-REP         ::= SEQUENCE {
405///         pvno            [0] INTEGER (5),
406///         msg-type        [1] INTEGER (11 -- AS -- | 13 -- TGS --),
407///         padata          [2] SEQUENCE OF PA-DATA OPTIONAL
408///                                 -- NOTE: not empty --,
409///         crealm          [3] Realm,
410///         cname           [4] PrincipalName,
411///         ticket          [5] Ticket,
412///         enc-part        [6] EncryptedData
413///                                 -- EncASRepPart or EncTGSRepPart,
414///                                 -- as appropriate
415/// }
416/// </pre>
417#[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
426/// Parse a Kerberos KDC Reply
427///
428/// <pre>
429/// KDC-REP         ::= SEQUENCE {
430///         pvno            [0] INTEGER (5),
431///         msg-type        [1] INTEGER (11 -- AS -- | 13 -- TGS --),
432///         padata          [2] SEQUENCE OF PA-DATA OPTIONAL
433///                                 -- NOTE: not empty --,
434///         crealm          [3] Realm,
435///         cname           [4] PrincipalName,
436///         ticket          [5] Ticket,
437///         enc-part        [6] EncryptedData
438///                                 -- EncASRepPart or EncTGSRepPart,
439///                                 -- as appropriate
440/// }
441/// </pre>
442impl<'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
469/// Parse a Kerberos AS Reply
470///
471/// <pre>
472/// AS-REP          ::= [APPLICATION 11] KDC-REP
473/// </pre>
474pub 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
478/// Parse a Kerberos TGS Reply
479///
480/// <pre>
481/// TGS-REP          ::= [APPLICATION 13] KDC-REP
482/// </pre>
483pub 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/// Parse a Kerberos Error
488///
489/// <pre>
490/// KRB-ERROR       ::= [APPLICATION 30] SEQUENCE {
491///         pvno            [0] INTEGER (5),
492///         msg-type        [1] INTEGER (30),
493///         ctime           [2] KerberosTime OPTIONAL,
494///         cusec           [3] Microseconds OPTIONAL,
495///         stime           [4] KerberosTime,
496///         susec           [5] Microseconds,
497///         error-code      [6] Int32,
498///         crealm          [7] Realm OPTIONAL,
499///         cname           [8] PrincipalName OPTIONAL,
500///         realm           [9] Realm -- service realm --,
501///         sname           [10] PrincipalName -- service name --,
502///         e-text          [11] KerberosString OPTIONAL,
503///         e-data          [12] OCTET STRING OPTIONAL
504/// }
505/// </pre>
506#[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
515/// Parse a Kerberos Error
516///
517/// <pre>
518/// KRB-ERROR       ::= [APPLICATION 30] SEQUENCE {
519///         pvno            [0] INTEGER (5),
520///         msg-type        [1] INTEGER (30),
521///         ctime           [2] KerberosTime OPTIONAL,
522///         cusec           [3] Microseconds OPTIONAL,
523///         stime           [4] KerberosTime,
524///         susec           [5] Microseconds,
525///         error-code      [6] Int32,
526///         crealm          [7] Realm OPTIONAL,
527///         cname           [8] PrincipalName OPTIONAL,
528///         realm           [9] Realm -- service realm --,
529///         sname           [10] PrincipalName -- service name --,
530///         e-text          [11] KerberosString OPTIONAL,
531///         e-data          [12] OCTET STRING OPTIONAL
532/// }
533/// </pre>
534impl<'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/// Parse Kerberos PA-Data
582///
583/// <pre>
584/// PA-DATA         ::= SEQUENCE {
585///         -- NOTE: first tag is [1], not [0]
586///         padata-type     [1] Int32,
587///         padata-value    [2] OCTET STRING -- might be encoded AP-REQ
588/// }
589/// </pre>
590#[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
599/// Parse Kerberos PA-Data
600///
601/// <pre>
602/// PA-DATA         ::= SEQUENCE {
603///         -- NOTE: first tag is [1], not [0]
604///         padata-type     [1] Int32,
605///         padata-value    [2] OCTET STRING -- might be encoded AP-REQ
606/// }
607/// </pre>
608impl<'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/// Parse a Kerberos AP Request
628///
629/// <pre>
630/// AP-REQ          ::= [APPLICATION 14] SEQUENCE {
631///         pvno            [0] INTEGER (5),
632///         msg-type        [1] INTEGER (14),
633///         ap-options      [2] APOptions,
634///         ticket          [3] Ticket,
635///         authenticator   [4] EncryptedData -- Authenticator
636/// }
637///
638/// APOptions       ::= KerberosFlags
639///         -- reserved(0),
640///         -- use-session-key(1),
641///         -- mutual-required(2)
642/// </pre>
643#[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
652/// Parse a Kerberos AP Request
653///
654/// <pre>
655/// AP-REQ          ::= [APPLICATION 14] SEQUENCE {
656///         pvno            [0] INTEGER (5),
657///         msg-type        [1] INTEGER (14),
658///         ap-options      [2] APOptions,
659///         ticket          [3] Ticket,
660///         authenticator   [4] EncryptedData -- Authenticator
661/// }
662///
663/// APOptions       ::= KerberosFlags
664///         -- reserved(0),
665///         -- use-session-key(1),
666///         -- mutual-required(2)
667/// </pre>
668impl<'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/// Parse a Kerberos AP Reply
694///
695/// <pre>
696/// AP-REP          ::= [APPLICATION 15] SEQUENCE {
697///         pvno            [0] INTEGER (5),
698///         msg-type        [1] INTEGER (15),
699///         enc-part        [2] EncryptedData -- EncAPRepPart
700/// }
701/// </pre>
702#[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
711/// Parse a Kerberos AP Reply
712///
713/// <pre>
714/// AP-REP          ::= [APPLICATION 15] SEQUENCE {
715///         pvno            [0] INTEGER (5),
716///         msg-type        [1] INTEGER (15),
717///         enc-part        [2] EncryptedData -- EncAPRepPart
718/// }
719/// </pre>
720impl<'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}