1 //! Kerberos 5 parsing functions
2
3 use der_parser::ber::*;
4 use der_parser::der::*;
5 use der_parser::error::*;
6 use nom::error::ErrorKind;
7 use nom::{Err, IResult};
8 use std::str;
9
10 use crate::krb5::*;
11
12 /// Parse a signed 32 bits integer
13 ///
14 /// <pre>
15 /// Int32 ::= INTEGER (-2147483648..2147483647)
16 /// -- signed values representable in 32 bits
17 /// </pre>
parse_der_int32(i: &[u8]) -> IResult<&[u8], i32, BerError>18 pub fn parse_der_int32(i: &[u8]) -> IResult<&[u8], i32, BerError> {
19 map_res!(i, parse_der_integer, |x: DerObject| {
20 match x.content {
21 BerObjectContent::Integer(i) => match i.len() {
22 1 => Ok(i[0] as i8 as i32),
23 2 => Ok((i[0] as i8 as i32) << 8 | (i[1] as i32)),
24 3 => Ok((i[0] as i8 as i32) << 16 | (i[1] as i32) << 8 | (i[2] as i32)),
25 4 => Ok((i[0] as i8 as i32) << 24
26 | (i[1] as i32) << 16
27 | (i[2] as i32) << 8
28 | (i[3] as i32)),
29 _ => Err(BerError::IntegerTooLarge),
30 },
31 _ => Err(BerError::BerTypeError),
32 }
33 })
34 }
35
36 // Microseconds ::= INTEGER (0..999999)
37 // -- microseconds
parse_der_microseconds(i: &[u8]) -> IResult<&[u8], u32, BerError>38 fn parse_der_microseconds(i: &[u8]) -> IResult<&[u8], u32, BerError> {
39 verify!(i, parse_der_u32, |x: &u32| *x <= 999_999)
40 }
41
42 // helper macro to give same result as opt!(complete!(parse_der_tagged!(i,tag,fn) but with
43 // less complexity, and faster
44 macro_rules! opt_parse_der_tagged(
45 ($i:expr, EXPLICIT $tag:expr, $submac:ident!( $($args:tt)*)) => ({
46 use der_parser::der::der_read_element_header;
47 use nom::{Err, Needed};
48 match der_read_element_header($i) {
49 Ok((rem,hdr)) => {
50 if $tag != hdr.tag.0 {
51 Ok(($i,None))
52 } else {
53 let len = hdr.len as usize;
54 if rem.len() < len { Err(Err::Incomplete(Needed::Size(len))) } // tag was correct, this really is an error
55 else {
56 match $submac!(&rem[0..len], $($args)*) {
57 Ok((_,res)) => Ok((&rem[len..],Some(res))),
58 _ => Ok(($i,None))
59 }
60 }
61 }
62 },
63 _ => Ok(($i,None))
64 }
65 });
66 ($i:expr, EXPLICIT $tag:expr, $f:ident) => ({
67 opt_parse_der_tagged!($i, EXPLICIT $tag, call!($f))
68 });
69 );
70
71 /// Parse a Kerberos string object
72 ///
73 /// <pre>
74 /// KerberosString ::= GeneralString (IA5String)
75 /// </pre>
parse_kerberos_string(i: &[u8]) -> IResult<&[u8], String, BerError>76 pub fn parse_kerberos_string(i: &[u8]) -> IResult<&[u8], String, BerError> {
77 match parse_der_generalstring(i) {
78 Ok((rem, ref obj)) => {
79 if let BerObjectContent::GeneralString(s) = obj.content {
80 match str::from_utf8(s) {
81 Ok(r) => Ok((rem, r.to_owned())),
82 Err(_) => Err(Err::Error(error_position!(i, ErrorKind::IsNot))),
83 }
84 } else {
85 Err(Err::Error(error_position!(i, ErrorKind::Tag)))
86 }
87 }
88 Err(e) => Err(e),
89 }
90 }
91
parse_kerberos_string_sequence(i: &[u8]) -> IResult<&[u8], Vec<String>, BerError>92 fn parse_kerberos_string_sequence(i: &[u8]) -> IResult<&[u8], Vec<String>, BerError> {
93 parse_der_struct!(
94 i,
95 TAG DerTag::Sequence,
96 v: many0!(complete!(parse_kerberos_string)) >>
97 ( v )
98 )
99 .map(|(rem, x)| (rem, x.1))
100 }
101
102 /// Parse Kerberos flags
103 ///
104 /// <pre>
105 /// KerberosFlags ::= BIT STRING (SIZE (32..MAX))
106 /// -- minimum number of bits shall be sent,
107 /// -- but no fewer than 32
108 /// </pre>
109 #[inline]
parse_kerberos_flags(i: &[u8]) -> IResult<&[u8], DerObject, BerError>110 pub fn parse_kerberos_flags(i: &[u8]) -> IResult<&[u8], DerObject, BerError> {
111 parse_der_bitstring(i)
112 }
113
114 /// Parse of a Kerberos Realm
115 ///
116 /// <pre>
117 /// Realm ::= KerberosString
118 /// </pre>
119 #[inline]
parse_krb5_realm(i: &[u8]) -> IResult<&[u8], Realm, BerError>120 pub fn parse_krb5_realm(i: &[u8]) -> IResult<&[u8], Realm, BerError> {
121 map!(i, parse_kerberos_string, Realm)
122 }
123
124 /// Parse Kerberos PrincipalName
125 ///
126 /// <pre>
127 /// PrincipalName ::= SEQUENCE {
128 /// name-type [0] Int32,
129 /// name-string [1] SEQUENCE OF KerberosString
130 /// }
131 /// </pre>
parse_krb5_principalname(i: &[u8]) -> IResult<&[u8], PrincipalName, BerError>132 pub fn parse_krb5_principalname(i: &[u8]) -> IResult<&[u8], PrincipalName, BerError> {
133 map_res!(
134 i,
135 parse_der_struct!(
136 t: parse_der_tagged!(EXPLICIT 0, parse_der_int32)
137 >> s: parse_der_tagged!(EXPLICIT 1, parse_kerberos_string_sequence)
138 >> (PrincipalName {
139 name_type: NameType(t),
140 name_string: s,
141 })
142 ),
143 |(hdr, t): (BerObjectHeader, PrincipalName)| {
144 if hdr.tag != BerTag::Sequence {
145 return Err("not a sequence!");
146 }
147 Ok(t)
148 }
149 )
150 }
151
152 /// Parse of a Kerberos Time
153 ///
154 /// <pre>
155 /// KerberosTime ::= GeneralizedTime -- with no fractional seconds
156 /// </pre>
157 #[inline]
parse_kerberos_time(i: &[u8]) -> IResult<&[u8], DerObject, BerError>158 pub fn parse_kerberos_time(i: &[u8]) -> IResult<&[u8], DerObject, BerError> {
159 parse_der_generalizedtime(i)
160 }
161
162 /// Parse Kerberos HostAddress
163 ///
164 /// <pre>
165 /// HostAddress ::= SEQUENCE {
166 /// addr-type [0] Int32,
167 /// address [1] OCTET STRING
168 /// }
169 /// </pre>
parse_krb5_hostaddress<'a>(i: &'a [u8]) -> IResult<&'a [u8], HostAddress<'a>, BerError>170 pub fn parse_krb5_hostaddress<'a>(i: &'a [u8]) -> IResult<&'a [u8], HostAddress<'a>, BerError> {
171 parse_der_struct!(
172 i,
173 TAG DerTag::Sequence,
174 t: parse_der_tagged!(EXPLICIT 0, parse_der_int32) >>
175 a: map_res!(parse_der_tagged!(EXPLICIT 1, parse_der_octetstring),|x: DerObject<'a>| x.as_slice()) >>
176 ( HostAddress{
177 addr_type: AddressType(t),
178 address: a,
179 })
180 ).map(|(rem,x)| (rem,x.1))
181 }
182
183 /// Parse Kerberos HostAddresses
184 ///
185 /// <pre>
186 /// -- NOTE: HostAddresses is always used as an OPTIONAL field and
187 /// -- should not be empty.
188 /// HostAddresses -- NOTE: subtly different from rfc1510,
189 /// -- but has a value mapping and encodes the same
190 /// ::= SEQUENCE OF HostAddress
191 /// </pre>
parse_krb5_hostaddresses(i: &[u8]) -> IResult<&[u8], Vec<HostAddress>, BerError>192 pub fn parse_krb5_hostaddresses(i: &[u8]) -> IResult<&[u8], Vec<HostAddress>, BerError> {
193 parse_der_struct!(
194 i,
195 TAG DerTag::Sequence,
196 v: many0!(complete!(parse_krb5_hostaddress)) >>
197 ( v )
198 )
199 .map(|(rem, x)| (rem, x.1))
200 }
201
202 /// Parse Kerberos Ticket
203 ///
204 /// <pre>
205 /// Ticket ::= [APPLICATION 1] SEQUENCE {
206 /// tkt-vno [0] INTEGER (5),
207 /// realm [1] Realm,
208 /// sname [2] PrincipalName,
209 /// enc-part [3] EncryptedData -- EncTicketPart
210 /// }
211 /// </pre>
parse_krb5_ticket<'a>(i: &'a [u8]) -> IResult<&'a [u8], Ticket<'a>, BerError>212 pub fn parse_krb5_ticket<'a>(i: &'a [u8]) -> IResult<&'a [u8], Ticket<'a>, BerError> {
213 parse_der_application!(
214 i,
215 APPLICATION 1,
216 st: parse_der_struct!(
217 TAG DerTag::Sequence,
218 no: parse_der_tagged!(EXPLICIT 0, parse_der_u32) >>
219 error_if!(no != 5, ErrorKind::Tag) >>
220 r: parse_der_tagged!(EXPLICIT 1, parse_krb5_realm) >>
221 s: parse_der_tagged!(EXPLICIT 2, parse_krb5_principalname) >>
222 e: map_res!(parse_der,|x: DerObject<'a>| x.as_slice()) >>
223 ( Ticket{
224 tkt_vno: no,
225 realm: r,
226 sname: s,
227 enc_part: e
228 })
229 ) >> (st)
230 )
231 .map(|(rem, t)| (rem, (t.1).1))
232 }
233
234 /// Parse Kerberos EncryptedData
235 ///
236 /// <pre>
237 /// EncryptedData ::= SEQUENCE {
238 /// etype [0] Int32 -- EncryptionType --,
239 /// kvno [1] UInt32 OPTIONAL,
240 /// cipher [2] OCTET STRING -- ciphertext
241 /// }
242 /// </pre>
parse_encrypted<'a>(i: &'a [u8]) -> IResult<&'a [u8], EncryptedData<'a>, BerError>243 pub fn parse_encrypted<'a>(i: &'a [u8]) -> IResult<&'a [u8], EncryptedData<'a>, BerError> {
244 parse_der_struct!(
245 i,
246 TAG DerTag::Sequence,
247 e: parse_der_tagged!(EXPLICIT 0, parse_der_int32) >>
248 k: opt_parse_der_tagged!(EXPLICIT 1, parse_der_u32) >>
249 c: map_res!(parse_der_tagged!(EXPLICIT 2, parse_der_octetstring), |x: DerObject<'a>| x.as_slice()) >>
250 eof!() >>
251 ( EncryptedData{
252 etype: EncryptionType(e),
253 kvno: k,
254 cipher: c
255 })
256 ).map(|(rem,t)| (rem,t.1))
257 }
258
259 /// Parse a Kerberos KDC Request
260 ///
261 /// <pre>
262 /// KDC-REQ ::= SEQUENCE {
263 /// -- NOTE: first tag is [1], not [0]
264 /// pvno [1] INTEGER (5) ,
265 /// msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --),
266 /// padata [3] SEQUENCE OF PA-DATA OPTIONAL
267 /// -- NOTE: not empty --,
268 /// req-body [4] KDC-REQ-BODY
269 /// }
270 /// </pre>
parse_kdc_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError>271 pub fn parse_kdc_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError> {
272 parse_der_struct!(
273 i,
274 TAG DerTag::Sequence,
275 pvno: parse_der_tagged!(EXPLICIT 1, parse_der_u32) >>
276 t: parse_der_tagged!(EXPLICIT 2, parse_der_u32) >>
277 d: opt_parse_der_tagged!(EXPLICIT 3, parse_krb5_padata_sequence) >>
278 req_body: parse_der_tagged!(EXPLICIT 4, parse_kdc_req_body) >>
279 eof!() >>
280 ( KdcReq{
281 pvno,
282 msg_type: MessageType(t),
283 padata: d.unwrap_or_default(),
284 req_body
285 })
286 )
287 .map(|(rem, t)| (rem, t.1))
288 }
289
290 /// Parse the body of a Kerberos KDC Request
291 ///
292 /// <pre>
293 /// KDC-REQ-BODY ::= SEQUENCE {
294 /// kdc-options [0] KDCOptions,
295 /// cname [1] PrincipalName OPTIONAL
296 /// -- Used only in AS-REQ --,
297 /// realm [2] Realm
298 /// -- Server's realm
299 /// -- Also client's in AS-REQ --,
300 /// sname [3] PrincipalName OPTIONAL,
301 /// from [4] KerberosTime OPTIONAL,
302 /// till [5] KerberosTime,
303 /// rtime [6] KerberosTime OPTIONAL,
304 /// nonce [7] UInt32,
305 /// etype [8] SEQUENCE OF Int32 -- EncryptionType
306 /// -- in preference order --,
307 /// addresses [9] HostAddresses OPTIONAL,
308 /// enc-authorization-data [10] EncryptedData OPTIONAL
309 /// -- AuthorizationData --,
310 /// additional-tickets [11] SEQUENCE OF Ticket OPTIONAL
311 /// -- NOTE: not empty
312 /// }
313 /// </pre>
parse_kdc_req_body(i: &[u8]) -> IResult<&[u8], KdcReqBody, BerError>314 pub fn parse_kdc_req_body(i: &[u8]) -> IResult<&[u8], KdcReqBody, BerError> {
315 parse_der_struct!(
316 i,
317 TAG DerTag::Sequence,
318 o: parse_der_tagged!(EXPLICIT 0,parse_kerberos_flags) >>
319 cname: opt_parse_der_tagged!(EXPLICIT 1,parse_krb5_principalname) >>
320 realm: parse_der_tagged!(EXPLICIT 2,parse_krb5_realm) >>
321 sname: opt_parse_der_tagged!(EXPLICIT 3,parse_krb5_principalname) >>
322 from: opt_parse_der_tagged!(EXPLICIT 4,parse_kerberos_time) >>
323 till: parse_der_tagged!(EXPLICIT 5,parse_kerberos_time) >>
324 rtime: opt_parse_der_tagged!(EXPLICIT 6,parse_kerberos_time) >>
325 nonce: parse_der_tagged!(EXPLICIT 7, parse_der_u32) >>
326 etype: parse_der_tagged!(EXPLICIT 8,
327 parse_der_struct!(v: many1!(complete!(parse_der_int32)) >> (v.iter().map(|&x| EncryptionType(x)).collect()))
328 ) >>
329 addr: opt_parse_der_tagged!(EXPLICIT 9,parse_krb5_hostaddresses) >>
330 ead: opt_parse_der_tagged!(EXPLICIT 10,parse_encrypted) >>
331 atkts: opt_parse_der_tagged!(EXPLICIT 11,
332 parse_der_struct!(v: many1!(complete!(parse_krb5_ticket)) >> (v))
333 ) >>
334 eof!() >>
335 ( KdcReqBody{
336 kdc_options: o,
337 cname,
338 realm,
339 sname,
340 from,
341 till,
342 rtime,
343 nonce,
344 etype: etype.1,
345 addresses: addr.unwrap_or_default(),
346 enc_authorization_data: ead,
347 additional_tickets: if atkts.is_some() { atkts.unwrap().1 } else { vec![] }
348 })
349 ).map(|(rem,t)| (rem,t.1))
350 }
351
352 /// Parse a Kerberos AS Request
353 ///
354 /// <pre>
355 /// AS-REQ ::= [APPLICATION 10] KDC-REQ
356 /// </pre>
parse_as_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError>357 pub fn parse_as_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError> {
358 parse_der_application!(
359 i,
360 APPLICATION 10,
361 req: parse_kdc_req >> (req)
362 )
363 .map(|(rem, t)| (rem, t.1))
364 }
365
366 /// Parse a Kerberos TGS Request
367 ///
368 /// <pre>
369 /// TGS-REQ ::= [APPLICATION 12] KDC-REQ
370 /// </pre>
parse_tgs_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError>371 pub fn parse_tgs_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError> {
372 parse_der_application!(
373 i,
374 APPLICATION 12,
375 req: parse_kdc_req >> (req)
376 )
377 .map(|(rem, t)| (rem, t.1))
378 }
379
380 /// Parse a Kerberos KDC Reply
381 ///
382 /// <pre>
383 /// KDC-REP ::= SEQUENCE {
384 /// pvno [0] INTEGER (5),
385 /// msg-type [1] INTEGER (11 -- AS -- | 13 -- TGS --),
386 /// padata [2] SEQUENCE OF PA-DATA OPTIONAL
387 /// -- NOTE: not empty --,
388 /// crealm [3] Realm,
389 /// cname [4] PrincipalName,
390 /// ticket [5] Ticket,
391 /// enc-part [6] EncryptedData
392 /// -- EncASRepPart or EncTGSRepPart,
393 /// -- as appropriate
394 /// }
395 /// </pre>
parse_kdc_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError>396 pub fn parse_kdc_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError> {
397 parse_der_struct!(
398 i,
399 TAG DerTag::Sequence,
400 pvno: parse_der_tagged!(EXPLICIT 0,parse_der_u32) >>
401 msgtype: parse_der_tagged!(EXPLICIT 1,parse_der_u32) >>
402 padata: opt_parse_der_tagged!(EXPLICIT 2,parse_krb5_padata_sequence) >>
403 crealm: parse_der_tagged!(EXPLICIT 3,parse_krb5_realm) >>
404 cname: parse_der_tagged!(EXPLICIT 4,parse_krb5_principalname) >>
405 ticket: parse_der_tagged!(EXPLICIT 5,parse_krb5_ticket) >>
406 enc_part: parse_der_tagged!(EXPLICIT 6,parse_encrypted) >>
407 eof!() >>
408 ( KdcRep{
409 pvno,
410 msg_type: MessageType(msgtype),
411 padata: padata.unwrap_or_default(),
412 crealm,
413 cname,
414 ticket,
415 enc_part,
416 })
417 )
418 .map(|(rem, t)| (rem, t.1))
419 }
420
421 /// Parse a Kerberos AS Reply
422 ///
423 /// <pre>
424 /// AS-REP ::= [APPLICATION 11] KDC-REP
425 /// </pre>
parse_as_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError>426 pub fn parse_as_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError> {
427 parse_der_application!(
428 i,
429 APPLICATION 11,
430 rep: parse_kdc_rep >> (rep)
431 )
432 .map(|(rem, t)| (rem, t.1))
433 }
434
435 /// Parse a Kerberos TGS Reply
436 ///
437 /// <pre>
438 /// TGS-REP ::= [APPLICATION 13] KDC-REP
439 /// </pre>
parse_tgs_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError>440 pub fn parse_tgs_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError> {
441 parse_der_application!(
442 i,
443 APPLICATION 13,
444 rep: parse_kdc_rep >> (rep)
445 )
446 .map(|(rem, t)| (rem, t.1))
447 }
448
449 /// Parse a Kerberos Error
450 ///
451 /// <pre>
452 /// KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
453 /// pvno [0] INTEGER (5),
454 /// msg-type [1] INTEGER (30),
455 /// ctime [2] KerberosTime OPTIONAL,
456 /// cusec [3] Microseconds OPTIONAL,
457 /// stime [4] KerberosTime,
458 /// susec [5] Microseconds,
459 /// error-code [6] Int32,
460 /// crealm [7] Realm OPTIONAL,
461 /// cname [8] PrincipalName OPTIONAL,
462 /// realm [9] Realm -- service realm --,
463 /// sname [10] PrincipalName -- service name --,
464 /// e-text [11] KerberosString OPTIONAL,
465 /// e-data [12] OCTET STRING OPTIONAL
466 /// }
467 /// </pre>
parse_krb_error(i: &[u8]) -> IResult<&[u8], KrbError, BerError>468 pub fn parse_krb_error(i: &[u8]) -> IResult<&[u8], KrbError, BerError> {
469 parse_der_application!(
470 i,
471 APPLICATION 30,
472 st: parse_der_struct!(
473 TAG DerTag::Sequence,
474 pvno: parse_der_tagged!(EXPLICIT 0,parse_der_u32) >>
475 msgtype: parse_der_tagged!(EXPLICIT 1,parse_der_u32) >>
476 error_if!(pvno != 5 || msgtype != 30, ErrorKind::Tag) >>
477 ctime: opt_parse_der_tagged!(EXPLICIT 2,parse_kerberos_time) >>
478 cusec: opt_parse_der_tagged!(EXPLICIT 3,parse_der_microseconds) >>
479 stime: parse_der_tagged!(EXPLICIT 4,parse_kerberos_time) >>
480 susec: parse_der_tagged!(EXPLICIT 5,parse_der_microseconds) >>
481 errorc: parse_der_tagged!(EXPLICIT 6,parse_der_int32) >>
482 crealm: opt_parse_der_tagged!(EXPLICIT 7,parse_krb5_realm) >>
483 cname: opt_parse_der_tagged!(EXPLICIT 8,parse_krb5_principalname) >>
484 realm: parse_der_tagged!(EXPLICIT 9,parse_krb5_realm) >>
485 sname: parse_der_tagged!(EXPLICIT 10,parse_krb5_principalname) >>
486 etext: opt_parse_der_tagged!(EXPLICIT 11,parse_kerberos_string) >>
487 edata: opt_parse_der_tagged!(EXPLICIT 12,parse_der_octetstring) >>
488 (KrbError{
489 pvno,
490 msg_type: MessageType(msgtype),
491 ctime,
492 cusec,
493 stime,
494 susec,
495 error_code: ErrorCode(errorc),
496 crealm,
497 cname,
498 realm,
499 sname,
500 etext,
501 edata,
502 })
503 )
504 >> (st)
505 )
506 .map(|(rem, t)| (rem, (t.1).1))
507 }
508
509 /// Parse Kerberos PA-Data
510 ///
511 /// <pre>
512 /// PA-DATA ::= SEQUENCE {
513 /// -- NOTE: first tag is [1], not [0]
514 /// padata-type [1] Int32,
515 /// padata-value [2] OCTET STRING -- might be encoded AP-REQ
516 /// }
517 /// </pre>
parse_krb5_padata<'a>(i: &'a [u8]) -> IResult<&'a [u8], PAData<'a>, BerError>518 pub fn parse_krb5_padata<'a>(i: &'a [u8]) -> IResult<&'a [u8], PAData<'a>, BerError> {
519 parse_der_struct!(
520 i,
521 TAG DerTag::Sequence,
522 t: parse_der_tagged!(EXPLICIT 1, parse_der_int32) >>
523 s: map_res!(parse_der_tagged!(EXPLICIT 2, parse_der_octetstring),|x: DerObject<'a>| x.as_slice()) >>
524 ( PAData{
525 padata_type: PAType(t),
526 padata_value: s,
527 })
528 ).map(|(rem,x)| (rem,x.1))
529 }
530
parse_krb5_padata_sequence(i: &[u8]) -> IResult<&[u8], Vec<PAData>, BerError>531 fn parse_krb5_padata_sequence(i: &[u8]) -> IResult<&[u8], Vec<PAData>, BerError> {
532 parse_der_struct!(
533 i,
534 TAG DerTag::Sequence,
535 v: many0!(complete!(parse_krb5_padata)) >>
536 ( v )
537 )
538 .map(|(rem, x)| (rem, x.1))
539 }
540
541 /// Parse a Kerberos AP Request
542 ///
543 /// <pre>
544 /// AP-REQ ::= [APPLICATION 14] SEQUENCE {
545 /// pvno [0] INTEGER (5),
546 /// msg-type [1] INTEGER (14),
547 /// ap-options [2] APOptions,
548 /// ticket [3] Ticket,
549 /// authenticator [4] EncryptedData -- Authenticator
550 /// }
551 ///
552 /// APOptions ::= KerberosFlags
553 /// -- reserved(0),
554 /// -- use-session-key(1),
555 /// -- mutual-required(2)
556 /// </pre>
parse_ap_req(i: &[u8]) -> IResult<&[u8], ApReq, BerError>557 pub fn parse_ap_req(i: &[u8]) -> IResult<&[u8], ApReq, BerError> {
558 parse_der_application!(
559 i,
560 APPLICATION 14,
561 st: parse_der_struct!(
562 TAG DerTag::Sequence,
563 pvno: parse_der_tagged!(EXPLICIT 0,parse_der_u32) >>
564 msgtype: parse_der_tagged!(EXPLICIT 1,parse_der_u32) >>
565 error_if!(pvno != 5 || msgtype != 14, ErrorKind::Tag) >>
566 flags: parse_der_tagged!(EXPLICIT 2,parse_kerberos_flags) >>
567 ticket: parse_der_tagged!(EXPLICIT 3,parse_krb5_ticket) >>
568 auth: parse_der_tagged!(EXPLICIT 4,parse_encrypted) >>
569 ( ApReq{
570 pvno,
571 msg_type: MessageType(msgtype),
572 ap_options: flags,
573 ticket,
574 authenticator: auth,
575 })
576 )
577 >> (st)
578 )
579 .map(|(rem, t)| (rem, (t.1).1))
580 }
581
582 /// Parse a Kerberos AP Reply
583 ///
584 /// <pre>
585 /// AP-REP ::= [APPLICATION 15] SEQUENCE {
586 /// pvno [0] INTEGER (5),
587 /// msg-type [1] INTEGER (15),
588 /// enc-part [2] EncryptedData -- EncAPRepPart
589 /// }
590 /// </pre>
parse_ap_rep(i: &[u8]) -> IResult<&[u8], ApRep, BerError>591 pub fn parse_ap_rep(i: &[u8]) -> IResult<&[u8], ApRep, BerError> {
592 parse_der_application!(
593 i,
594 APPLICATION 15,
595 st: parse_der_struct!(
596 TAG DerTag::Sequence,
597 pvno: parse_der_tagged!(EXPLICIT 0,parse_der_u32) >>
598 msgtype: parse_der_tagged!(EXPLICIT 1,parse_der_u32) >>
599 error_if!(pvno != 5 || msgtype != 15, ErrorKind::Tag) >>
600 edata: parse_der_tagged!(EXPLICIT 4,parse_encrypted) >>
601 ( ApRep{
602 pvno,
603 msg_type: MessageType(msgtype),
604 enc_part: edata,
605 })
606 )
607 >> (st)
608 )
609 .map(|(rem, t)| (rem, (t.1).1))
610 }
611