Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/kerberos-parser-0.7.1/src/krb5_parser.rs
Line
Count
Source
1
//! Kerberos 5 parsing functions
2
3
use der_parser::ber::*;
4
use der_parser::der::*;
5
use der_parser::error::*;
6
use nom::combinator::{complete, map, map_res, opt, verify};
7
use nom::error::{make_error, ErrorKind};
8
use nom::multi::many1;
9
use nom::{Err, IResult};
10
use std::str;
11
12
use crate::krb5::*;
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
98.4k
pub fn parse_der_int32(i: &[u8]) -> IResult<&[u8], i32, BerError> {
21
98.4k
    map_res(parse_der_integer, |x: DerObject| match x.content {
22
54.9k
        BerObjectContent::Integer(i) => match i.len() {
23
8.51k
            1 => Ok(i[0] as i8 as i32),
24
42.9k
            2 => Ok((i[0] as i8 as i32) << 8 | (i[1] as i32)),
25
897
            3 => Ok((i[0] as i8 as i32) << 16 | (i[1] as i32) << 8 | (i[2] as i32)),
26
2.35k
            4 => Ok((i[0] as i8 as i32) << 24
27
2.35k
                | (i[1] as i32) << 16
28
2.35k
                | (i[2] as i32) << 8
29
2.35k
                | (i[3] as i32)),
30
272
            _ => Err(BerError::IntegerTooLarge),
31
        },
32
0
        _ => Err(BerError::BerTypeError),
33
98.4k
    })(i)
34
98.4k
}
35
36
//  Microseconds    ::= INTEGER (0..999999)
37
//                      -- microseconds
38
13.8k
fn parse_der_microseconds(i: &[u8]) -> IResult<&[u8], u32, BerError> {
39
13.8k
    verify(parse_der_u32, |x: &u32| *x <= 999_999)(i)
40
13.8k
}
41
42
/// Parse a Kerberos string object
43
///
44
/// <pre>
45
/// KerberosString  ::= GeneralString (IA5String)
46
/// </pre>
47
93.1k
pub fn parse_kerberos_string(i: &[u8]) -> IResult<&[u8], String, BerError> {
48
93.1k
    match parse_der_generalstring(i) {
49
80.8k
        Ok((rem, ref obj)) => {
50
80.8k
            if let BerObjectContent::GeneralString(s) = obj.content {
51
80.8k
                match str::from_utf8(s) {
52
80.1k
                    Ok(r) => Ok((rem, r.to_owned())),
53
706
                    Err(_) => Err(Err::Error(make_error(i, ErrorKind::IsNot))),
54
                }
55
            } else {
56
0
                Err(Err::Error(make_error(i, ErrorKind::Tag)))
57
            }
58
        }
59
12.2k
        Err(e) => Err(e),
60
    }
61
93.1k
}
62
63
12.0k
fn parse_kerberos_string_sequence(i: &[u8]) -> IResult<&[u8], Vec<String>, BerError> {
64
12.0k
    parse_ber_sequence_of_v(parse_kerberos_string)(i)
65
12.0k
}
66
67
/// Parse Kerberos flags
68
///
69
/// <pre>
70
/// KerberosFlags   ::= BIT STRING (SIZE (32..MAX))
71
///                     -- minimum number of bits shall be sent,
72
///                     -- but no fewer than 32
73
/// </pre>
74
#[inline]
75
61.0k
pub fn parse_kerberos_flags(i: &[u8]) -> IResult<&[u8], DerObject, BerError> {
76
61.0k
    parse_der_bitstring(i)
77
61.0k
}
78
79
/// Parse of a Kerberos Realm
80
///
81
/// <pre>
82
/// Realm           ::= KerberosString
83
/// </pre>
84
#[inline]
85
77.9k
pub fn parse_krb5_realm(i: &[u8]) -> IResult<&[u8], Realm, BerError> {
86
77.9k
    map(parse_kerberos_string, Realm)(i)
87
77.9k
}
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>
97
21.2k
pub fn parse_krb5_principalname(i: &[u8]) -> IResult<&[u8], PrincipalName, BerError> {
98
21.2k
    parse_ber_sequence_defined_g(|i, _| {
99
14.5k
        let (i, name_type) =
100
17.9k
            parse_ber_tagged_explicit_g(0, |a, _| map(parse_der_int32, NameType)(a))(i)?;
101
9.43k
        let (i, name_string) =
102
14.5k
            parse_ber_tagged_explicit_g(1, |a, _| parse_kerberos_string_sequence(a))(i)?;
103
9.43k
        Ok((
104
9.43k
            i,
105
9.43k
            PrincipalName {
106
9.43k
                name_type,
107
9.43k
                name_string,
108
9.43k
            },
109
9.43k
        ))
110
21.2k
    })(i)
111
21.2k
}
112
113
/// Parse of a Kerberos Time
114
///
115
/// <pre>
116
/// KerberosTime    ::= GeneralizedTime -- with no fractional seconds
117
/// </pre>
118
#[inline]
119
69.6k
pub fn parse_kerberos_time(i: &[u8]) -> IResult<&[u8], DerObject, BerError> {
120
69.6k
    parse_der_generalizedtime(i)
121
69.6k
}
122
123
/// Parse Kerberos HostAddress
124
///
125
/// <pre>
126
/// HostAddress     ::= SEQUENCE  {
127
///         addr-type       [0] Int32,
128
///         address         [1] OCTET STRING
129
/// }
130
/// </pre>
131
5.58k
pub fn parse_krb5_hostaddress(i: &[u8]) -> IResult<&[u8], HostAddress, BerError> {
132
5.58k
    parse_ber_sequence_defined_g(|i, _| {
133
1.73k
        let (i, addr_type) =
134
4.00k
            parse_ber_tagged_explicit_g(0, |a, _| map(parse_der_int32, AddressType)(a))(i)?;
135
1.73k
        let (i, address) = parse_ber_tagged_explicit_g(1, |a, _| {
136
214
            map_res(parse_ber_octetstring, |o| o.as_slice())(a)
137
1.73k
        })(i)?;
138
19
        Ok((i, HostAddress { addr_type, address }))
139
5.58k
    })(i)
140
5.58k
}
141
142
/// Parse Kerberos HostAddresses
143
///
144
/// <pre>
145
/// -- NOTE: HostAddresses is always used as an OPTIONAL field and
146
/// -- should not be empty.
147
/// HostAddresses   -- NOTE: subtly different from rfc1510,
148
///                 -- but has a value mapping and encodes the same
149
///         ::= SEQUENCE OF HostAddress
150
/// </pre>
151
13.3k
pub fn parse_krb5_hostaddresses(i: &[u8]) -> IResult<&[u8], Vec<HostAddress>, BerError> {
152
13.3k
    parse_ber_sequence_of_v(parse_krb5_hostaddress)(i)
153
13.3k
}
154
155
/// Parse Kerberos Ticket
156
///
157
/// <pre>
158
/// Ticket          ::= [APPLICATION 1] SEQUENCE {
159
///         tkt-vno         [0] INTEGER (5),
160
///         realm           [1] Realm,
161
///         sname           [2] PrincipalName,
162
///         enc-part        [3] EncryptedData -- EncTicketPart
163
/// }
164
/// </pre>
165
10.7k
pub fn parse_krb5_ticket(i: &[u8]) -> IResult<&[u8], Ticket, BerError> {
166
10.7k
    parse_ber_tagged_explicit_g(BerTag(1), |i, hdr| {
167
5.92k
        if !hdr.is_application() {
168
194
            return Err(Err::Error(BerError::InvalidTag));
169
5.72k
        }
170
5.72k
        parse_ber_sequence_defined_g(|i, _| {
171
4.42k
            let (i, tkt_vno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
172
2.40k
            if tkt_vno != 5 {
173
262
                return Err(Err::Error(BerError::Custom(5)));
174
2.13k
            }
175
2.13k
            let (i, realm) = parse_ber_tagged_explicit_g(1, |a, _| parse_krb5_realm(a))(i)?;
176
169
            let (i, sname) = parse_ber_tagged_explicit_g(2, |a, _| parse_krb5_principalname(a))(i)?;
177
167
            let (i, enc_part) = parse_ber_tagged_explicit_g(3, |a, _| parse_encrypted(a))(i)?;
178
165
            let tkt = Ticket {
179
165
                tkt_vno,
180
165
                realm,
181
165
                sname,
182
165
                enc_part,
183
165
            };
184
165
            Ok((i, tkt))
185
5.72k
        })(i)
186
10.7k
    })(i)
187
10.7k
}
188
189
/// Parse Kerberos EncryptedData
190
///
191
/// <pre>
192
/// EncryptedData   ::= SEQUENCE {
193
///         etype   [0] Int32 -- EncryptionType --,
194
///         kvno    [1] UInt32 OPTIONAL,
195
///         cipher  [2] OCTET STRING -- ciphertext
196
/// }
197
/// </pre>
198
6.57k
pub fn parse_encrypted(i: &[u8]) -> IResult<&[u8], EncryptedData, BerError> {
199
6.57k
    parse_ber_sequence_defined_g(|i, _| {
200
3.08k
        let (i, etype) =
201
5.19k
            parse_ber_tagged_explicit_g(0, |a, _| map(parse_der_int32, EncryptionType)(a))(i)?;
202
3.08k
        let (i, kvno) = opt(complete(parse_ber_tagged_explicit_g(1, |a, _| {
203
370
            parse_der_u32(a)
204
3.08k
        })))(i)?;
205
516
        let (i, cipher) =
206
3.08k
            parse_ber_tagged_explicit_g(2, |a, _| map_res(parse_der, |o| o.as_slice())(a))(i)?;
207
516
        let enc = EncryptedData {
208
516
            etype,
209
516
            kvno,
210
516
            cipher,
211
516
        };
212
516
        Ok((i, enc))
213
6.57k
    })(i)
214
6.57k
}
215
216
/// Parse a Kerberos KDC Request
217
///
218
/// <pre>
219
/// KDC-REQ         ::= SEQUENCE {
220
///         -- NOTE: first tag is [1], not [0]
221
///         pvno            [1] INTEGER (5) ,
222
///         msg-type        [2] INTEGER (10 -- AS -- | 12 -- TGS --),
223
///         padata          [3] SEQUENCE OF PA-DATA OPTIONAL
224
///                             -- NOTE: not empty --,
225
///         req-body        [4] KDC-REQ-BODY
226
/// }
227
/// </pre>
228
130k
pub fn parse_kdc_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError> {
229
130k
    parse_ber_sequence_defined_g(|i, _| {
230
123k
        let (i, pvno) = parse_ber_tagged_explicit_g(1, |a, _| parse_der_u32(a))(i)?;
231
93.0k
        let (i, msg_type) =
232
106k
            parse_ber_tagged_explicit_g(2, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
233
93.0k
        let (i, padata) = parse_ber_tagged_explicit_g(3, |a, _| parse_krb5_padata_sequence(a))(i)
234
93.0k
            .unwrap_or_else(|_| (i, Vec::new()));
235
93.0k
        let (i, req_body) = parse_ber_tagged_explicit_g(4, |a, _| parse_kdc_req_body(a))(i)?;
236
38.1k
        let req = KdcReq {
237
38.1k
            pvno,
238
38.1k
            msg_type,
239
38.1k
            padata,
240
38.1k
            req_body,
241
38.1k
        };
242
38.1k
        Ok((i, req))
243
130k
    })(i)
244
130k
}
245
246
/// Parse the body of a Kerberos KDC Request
247
///
248
/// <pre>
249
/// KDC-REQ-BODY    ::= SEQUENCE {
250
///         kdc-options             [0] KDCOptions,
251
///         cname                   [1] PrincipalName OPTIONAL
252
///                                     -- Used only in AS-REQ --,
253
///         realm                   [2] Realm
254
///                                     -- Server's realm
255
///                                     -- Also client's in AS-REQ --,
256
///         sname                   [3] PrincipalName OPTIONAL,
257
///         from                    [4] KerberosTime OPTIONAL,
258
///         till                    [5] KerberosTime,
259
///         rtime                   [6] KerberosTime OPTIONAL,
260
///         nonce                   [7] UInt32,
261
///         etype                   [8] SEQUENCE OF Int32 -- EncryptionType
262
///                                     -- in preference order --,
263
///         addresses               [9] HostAddresses OPTIONAL,
264
///         enc-authorization-data  [10] EncryptedData OPTIONAL
265
///                                     -- AuthorizationData --,
266
///         additional-tickets      [11] SEQUENCE OF Ticket OPTIONAL
267
///                                        -- NOTE: not empty
268
/// }
269
/// </pre>
270
63.8k
pub fn parse_kdc_req_body(i: &[u8]) -> IResult<&[u8], KdcReqBody, BerError> {
271
63.8k
    parse_ber_sequence_defined_g(|i, _| {
272
61.3k
        let (i, kdc_options) = parse_ber_tagged_explicit_g(0, |a, _| parse_kerberos_flags(a))(i)?;
273
56.4k
        let (i, cname) = opt(complete(parse_ber_tagged_explicit_g(1, |a, _| {
274
1.17k
            parse_krb5_principalname(a)
275
56.4k
        })))(i)?;
276
56.2k
        let (i, realm) = parse_ber_tagged_explicit_g(2, |a, _| parse_krb5_realm(a))(i)?;
277
52.8k
        let (i, sname) = opt(complete(parse_ber_tagged_explicit_g(3, |a, _| {
278
1.23k
            parse_krb5_principalname(a)
279
52.8k
        })))(i)?;
280
52.6k
        let (i, from) = opt(complete(parse_ber_tagged_explicit_g(4, |a, _| {
281
1.22k
            parse_kerberos_time(a)
282
52.6k
        })))(i)?;
283
52.6k
        let (i, till) = parse_ber_tagged_explicit_g(5, |a, _| parse_kerberos_time(a))(i)?;
284
47.8k
        let (i, rtime) = opt(complete(parse_ber_tagged_explicit_g(6, |a, _| {
285
1.73k
            parse_kerberos_time(a)
286
47.8k
        })))(i)?;
287
47.8k
        let (i, nonce) = parse_ber_tagged_explicit_g(7, |a, _| parse_der_u32(a))(i)?;
288
44.3k
        let (i, etype) = parse_ber_tagged_explicit_g(8, |a, _| {
289
42.5k
            map(parse_ber_sequence_of_v(parse_der_int32), |v| {
290
40.6k
                v.iter().map(|&x| EncryptionType(x)).collect()
291
42.5k
            })(a)
292
44.3k
        })(i)?;
293
40.6k
        let (i, addresses) = opt(complete(parse_ber_tagged_explicit_g(9, |a, _| {
294
13.3k
            parse_krb5_hostaddresses(a)
295
40.6k
        })))(i)?;
296
38.1k
        let addresses = addresses.unwrap_or_default();
297
38.1k
        let (i, enc_authorization_data) =
298
38.1k
            opt(complete(parse_ber_tagged_explicit_g(10, |a, _| {
299
6.24k
                parse_encrypted(a)
300
38.1k
            })))(i)?;
301
38.1k
        let (i, additional_tickets) = opt(complete(parse_ber_tagged_explicit_g(11, |a, _| {
302
9.24k
            many1(complete(parse_krb5_ticket))(a)
303
38.1k
        })))(i)?;
304
38.1k
        let additional_tickets = additional_tickets.unwrap_or_default();
305
38.1k
        let body = KdcReqBody {
306
38.1k
            kdc_options,
307
38.1k
            cname,
308
38.1k
            realm,
309
38.1k
            sname,
310
38.1k
            from,
311
38.1k
            till,
312
38.1k
            rtime,
313
38.1k
            nonce,
314
38.1k
            etype,
315
38.1k
            addresses,
316
38.1k
            enc_authorization_data,
317
38.1k
            additional_tickets,
318
38.1k
        };
319
38.1k
        Ok((i, body))
320
63.8k
    })(i)
321
63.8k
}
322
323
/// Parse a Kerberos AS Request
324
///
325
/// <pre>
326
/// AS-REQ          ::= [APPLICATION 10] KDC-REQ
327
/// </pre>
328
105k
pub fn parse_as_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError> {
329
105k
    parse_ber_tagged_explicit_g(BerTag(10), |i, hdr| {
330
61.8k
        if !hdr.is_application() {
331
0
            return Err(Err::Error(BerError::InvalidTag));
332
61.8k
        }
333
61.8k
        parse_kdc_req(i)
334
105k
    })(i)
335
105k
}
336
337
/// Parse a Kerberos TGS Request
338
///
339
/// <pre>
340
/// TGS-REQ          ::= [APPLICATION 12] KDC-REQ
341
/// </pre>
342
87.8k
pub fn parse_tgs_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError> {
343
87.8k
    parse_ber_tagged_explicit_g(BerTag(12), |i, hdr| {
344
68.2k
        if !hdr.is_application() {
345
0
            return Err(Err::Error(BerError::InvalidTag));
346
68.2k
        }
347
68.2k
        parse_kdc_req(i)
348
87.8k
    })(i)
349
87.8k
}
350
351
/// Parse a Kerberos KDC Reply
352
///
353
/// <pre>
354
/// KDC-REP         ::= SEQUENCE {
355
///         pvno            [0] INTEGER (5),
356
///         msg-type        [1] INTEGER (11 -- AS -- | 13 -- TGS --),
357
///         padata          [2] SEQUENCE OF PA-DATA OPTIONAL
358
///                                 -- NOTE: not empty --,
359
///         crealm          [3] Realm,
360
///         cname           [4] PrincipalName,
361
///         ticket          [5] Ticket,
362
///         enc-part        [6] EncryptedData
363
///                                 -- EncASRepPart or EncTGSRepPart,
364
///                                 -- as appropriate
365
/// }
366
/// </pre>
367
112k
pub fn parse_kdc_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError> {
368
112k
    parse_ber_sequence_defined_g(|i, _| {
369
42.0k
        let (i, pvno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
370
22.5k
        let (i, msg_type) =
371
30.7k
            parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
372
22.5k
        let (i, padata) = parse_ber_tagged_explicit_g(2, |a, _| parse_krb5_padata_sequence(a))(i)
373
22.5k
            .unwrap_or_else(|_| (i, Vec::new()));
374
22.5k
        let (i, crealm) = parse_ber_tagged_explicit_g(3, |a, _| parse_krb5_realm(a))(i)?;
375
14.9k
        let (i, cname) = parse_ber_tagged_explicit_g(4, |a, _| parse_krb5_principalname(a))(i)?;
376
3.47k
        let (i, ticket) = parse_ber_tagged_explicit_g(5, |a, _| parse_krb5_ticket(a))(i)?;
377
18
        let (i, enc_part) = parse_ber_tagged_explicit_g(6, |a, _| parse_encrypted(a))(i)?;
378
15
        let rep = KdcRep {
379
15
            pvno,
380
15
            msg_type,
381
15
            padata,
382
15
            crealm,
383
15
            cname,
384
15
            ticket,
385
15
            enc_part,
386
15
        };
387
15
        Ok((i, rep))
388
112k
    })(i)
389
112k
}
390
391
/// Parse a Kerberos AS Reply
392
///
393
/// <pre>
394
/// AS-REP          ::= [APPLICATION 11] KDC-REP
395
/// </pre>
396
90.7k
pub fn parse_as_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError> {
397
90.7k
    parse_ber_tagged_explicit_g(BerTag(11), |i, hdr| {
398
84.7k
        if !hdr.is_application() {
399
0
            return Err(Err::Error(BerError::InvalidTag));
400
84.7k
        }
401
84.7k
        parse_kdc_rep(i)
402
90.7k
    })(i)
403
90.7k
}
404
405
/// Parse a Kerberos TGS Reply
406
///
407
/// <pre>
408
/// TGS-REP          ::= [APPLICATION 13] KDC-REP
409
/// </pre>
410
33.2k
pub fn parse_tgs_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError> {
411
33.2k
    parse_ber_tagged_explicit_g(BerTag(13), |i, hdr| {
412
28.2k
        if !hdr.is_application() {
413
0
            return Err(Err::Error(BerError::InvalidTag));
414
28.2k
        }
415
28.2k
        parse_kdc_rep(i)
416
33.2k
    })(i)
417
33.2k
}
418
419
/// Parse a Kerberos Error
420
///
421
/// <pre>
422
/// KRB-ERROR       ::= [APPLICATION 30] SEQUENCE {
423
///         pvno            [0] INTEGER (5),
424
///         msg-type        [1] INTEGER (30),
425
///         ctime           [2] KerberosTime OPTIONAL,
426
///         cusec           [3] Microseconds OPTIONAL,
427
///         stime           [4] KerberosTime,
428
///         susec           [5] Microseconds,
429
///         error-code      [6] Int32,
430
///         crealm          [7] Realm OPTIONAL,
431
///         cname           [8] PrincipalName OPTIONAL,
432
///         realm           [9] Realm -- service realm --,
433
///         sname           [10] PrincipalName -- service name --,
434
///         e-text          [11] KerberosString OPTIONAL,
435
///         e-data          [12] OCTET STRING OPTIONAL
436
/// }
437
/// </pre>
438
91.9k
pub fn parse_krb_error(i: &[u8]) -> IResult<&[u8], KrbError, BerError> {
439
91.9k
    parse_ber_tagged_explicit_g(BerTag(30), |i, hdr| {
440
55.2k
        if !hdr.is_application() {
441
0
            return Err(Err::Error(BerError::InvalidTag));
442
55.2k
        }
443
55.2k
        parse_ber_sequence_defined_g(|i, _| {
444
48.6k
            let (i, pvno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
445
21.5k
            let (i, msg_type) =
446
28.0k
                parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
447
21.5k
            let (i, ctime) = opt(complete(parse_ber_tagged_explicit_g(2, |a, _| {
448
1.81k
                parse_kerberos_time(a)
449
21.5k
            })))(i)?;
450
21.5k
            let (i, cusec) = opt(complete(parse_ber_tagged_explicit_g(3, |a, _| {
451
774
                parse_der_microseconds(a)
452
21.5k
            })))(i)?;
453
21.5k
            let (i, stime) = parse_ber_tagged_explicit_g(4, |a, _| parse_kerberos_time(a))(i)?;
454
15.1k
            let (i, susec) = parse_ber_tagged_explicit_g(5, |a, _| parse_der_microseconds(a))(i)?;
455
10.3k
            let (i, error_code) =
456
12.4k
                parse_ber_tagged_explicit_g(6, |a, _| map(parse_der_int32, ErrorCode)(a))(i)?;
457
10.3k
            let (i, crealm) = opt(complete(parse_ber_tagged_explicit_g(7, |a, _| {
458
415
                parse_krb5_realm(a)
459
10.3k
            })))(i)?;
460
10.3k
            let (i, cname) = opt(complete(parse_ber_tagged_explicit_g(8, |a, _| {
461
388
                parse_krb5_principalname(a)
462
10.3k
            })))(i)?;
463
10.3k
            let (i, realm) = parse_ber_tagged_explicit_g(9, |a, _| parse_krb5_realm(a))(i)?;
464
4.03k
            let (i, sname) =
465
7.31k
                parse_ber_tagged_explicit_g(10, |a, _| parse_krb5_principalname(a))(i)?;
466
4.03k
            let (i, etext) = opt(complete(parse_ber_tagged_explicit_g(11, |a, _| {
467
384
                parse_kerberos_string(a)
468
4.03k
            })))(i)?;
469
4.03k
            let (i, edata) = opt(complete(parse_ber_tagged_explicit_g(12, |a, _| {
470
1.15k
                parse_der_octetstring(a)
471
4.03k
            })))(i)?;
472
4.03k
            let err = KrbError {
473
4.03k
                pvno,
474
4.03k
                msg_type,
475
4.03k
                ctime,
476
4.03k
                cusec,
477
4.03k
                stime,
478
4.03k
                susec,
479
4.03k
                error_code,
480
4.03k
                crealm,
481
4.03k
                cname,
482
4.03k
                realm,
483
4.03k
                sname,
484
4.03k
                etext,
485
4.03k
                edata,
486
4.03k
            };
487
4.03k
            Ok((i, err))
488
55.2k
        })(i)
489
91.9k
    })(i)
490
91.9k
}
491
492
/// Parse Kerberos PA-Data
493
///
494
/// <pre>
495
/// PA-DATA         ::= SEQUENCE {
496
///         -- NOTE: first tag is [1], not [0]
497
///         padata-type     [1] Int32,
498
///         padata-value    [2] OCTET STRING -- might be encoded AP-REQ
499
/// }
500
/// </pre>
501
31.6k
pub fn parse_krb5_padata(i: &[u8]) -> IResult<&[u8], PAData, BerError> {
502
31.6k
    parse_ber_sequence_defined_g(|i, _| {
503
23.4k
        let (i, padata_type) =
504
25.8k
            parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_int32, PAType)(a))(i)?;
505
6.31k
        let (i, padata_value) =
506
23.4k
            parse_ber_tagged_explicit_g(2, |a, _| map_res(parse_der, |o| o.as_slice())(a))(i)?;
507
6.31k
        let padata = PAData {
508
6.31k
            padata_type,
509
6.31k
            padata_value,
510
6.31k
        };
511
6.31k
        Ok((i, padata))
512
31.6k
    })(i)
513
31.6k
}
514
515
27.3k
fn parse_krb5_padata_sequence(i: &[u8]) -> IResult<&[u8], Vec<PAData>, BerError> {
516
27.3k
    parse_ber_sequence_of_v(parse_krb5_padata)(i)
517
27.3k
}
518
519
/// Parse a Kerberos AP Request
520
///
521
/// <pre>
522
/// AP-REQ          ::= [APPLICATION 14] SEQUENCE {
523
///         pvno            [0] INTEGER (5),
524
///         msg-type        [1] INTEGER (14),
525
///         ap-options      [2] APOptions,
526
///         ticket          [3] Ticket,
527
///         authenticator   [4] EncryptedData -- Authenticator
528
/// }
529
///
530
/// APOptions       ::= KerberosFlags
531
///         -- reserved(0),
532
///         -- use-session-key(1),
533
///         -- mutual-required(2)
534
/// </pre>
535
16.9k
pub fn parse_ap_req(i: &[u8]) -> IResult<&[u8], ApReq, BerError> {
536
16.9k
    parse_ber_tagged_explicit_g(BerTag(14), |i, hdr| {
537
14.1k
        if !hdr.is_application() {
538
66
            return Err(Err::Error(BerError::InvalidTag));
539
14.1k
        }
540
14.1k
        parse_ber_sequence_defined_g(|i, _| {
541
12.5k
            let (i, pvno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
542
4.08k
            let (i, msg_type) =
543
6.86k
                parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
544
1.91k
            let (i, ap_options) =
545
4.08k
                parse_ber_tagged_explicit_g(2, |a, _| parse_kerberos_flags(a))(i)?;
546
1.91k
            let (i, ticket) = parse_ber_tagged_explicit_g(3, |a, _| parse_krb5_ticket(a))(i)?;
547
147
            let (i, authenticator) = parse_ber_tagged_explicit_g(4, |a, _| parse_encrypted(a))(i)?;
548
138
            let req = ApReq {
549
138
                pvno,
550
138
                msg_type,
551
138
                ap_options,
552
138
                ticket,
553
138
                authenticator,
554
138
            };
555
138
            Ok((i, req))
556
14.1k
        })(i)
557
16.9k
    })(i)
558
16.9k
}
559
560
/// Parse a Kerberos AP Reply
561
///
562
/// <pre>
563
/// AP-REP          ::= [APPLICATION 15] SEQUENCE {
564
///         pvno            [0] INTEGER (5),
565
///         msg-type        [1] INTEGER (15),
566
///         enc-part        [2] EncryptedData -- EncAPRepPart
567
/// }
568
/// </pre>
569
0
pub fn parse_ap_rep(i: &[u8]) -> IResult<&[u8], ApRep, BerError> {
570
0
    parse_ber_tagged_explicit_g(BerTag(15), |i, hdr| {
571
0
        if !hdr.is_application() {
572
0
            return Err(Err::Error(BerError::InvalidTag));
573
0
        }
574
0
        parse_ber_sequence_defined_g(|i, _| {
575
0
            let (i, pvno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
576
0
            let (i, msg_type) =
577
0
                parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
578
0
            let (i, enc_part) = parse_ber_tagged_explicit_g(2, |a, _| parse_encrypted(a))(i)?;
579
0
            let rep = ApRep {
580
0
                pvno,
581
0
                msg_type,
582
0
                enc_part,
583
0
            };
584
0
            Ok((i, rep))
585
0
        })(i)
586
0
    })(i)
587
0
}