1use crate::error::IPsecError;
2use crate::ikev2::*;
3use crate::ikev2_notify::NotifyType;
4use crate::ikev2_transforms::*;
5use nom::bytes::streaming::take;
6use nom::combinator::{complete, cond, map, map_parser, verify};
7use nom::error::{make_error, ErrorKind};
8use nom::multi::{count, many1};
9use nom::number::streaming::{be_u16, be_u32, be_u64, be_u8};
10use nom::{Err, IResult, Needed};
11
12pub fn parse_ikev2_header(i: &[u8]) -> IResult<&[u8], IkeV2Header> {
13 if i.len() < 28 {
14 return Err(Err::Incomplete(Needed::new(28)));
15 }
16 let (i, init_spi) = be_u64(i)?;
17 let (i, resp_spi) = be_u64(i)?;
18 let (i, next_payload) = map(be_u8, IkePayloadType)(i)?;
19 let (i, vers) = be_u8(i)?;
20 let maj_ver = vers >> 4;
21 let min_ver = vers & 0b1111;
22 let (i, exch_type) = map(be_u8, IkeExchangeType)(i)?;
23 let (i, flags) = be_u8(i)?;
24 let (i, msg_id) = be_u32(i)?;
25 let (i, length) = be_u32(i)?;
26 let hdr = IkeV2Header {
27 init_spi,
28 resp_spi,
29 next_payload,
30 maj_ver,
31 min_ver,
32 exch_type,
33 flags,
34 msg_id,
35 length,
36 };
37 Ok((i, hdr))
38}
39
40#[inline]
41fn bits_split_1(i: &[u8]) -> IResult<&[u8], (u8, u8)> {
42 let (i, b) = be_u8(i)?;
43 let b1 = b >> 7;
44 let b2_7 = b & 0b_0111_1111;
45 Ok((i, (b1, b2_7)))
46}
47
48pub fn parse_ikev2_payload_generic(i: &[u8]) -> IResult<&[u8], IkeV2GenericPayload> {
49 let (i, next_payload_type) = map(be_u8, IkePayloadType)(i)?;
50 let (i, b) = bits_split_1(i)?;
51 let (i, payload_length) = verify(be_u16, |&n| n >= 4)(i)?;
52 let (i, payload) = take(payload_length - 4)(i)?;
53 let hdr = IkeV2PayloadHeader {
54 next_payload_type,
55 critical: b.0 == 1,
56 reserved: b.1,
57 payload_length,
58 };
59 let payload = IkeV2GenericPayload { hdr, payload };
60 Ok((i, payload))
61}
62
63pub fn parse_ikev2_transform(i: &[u8]) -> IResult<&[u8], IkeV2RawTransform> {
64 let (i, last) = be_u8(i)?;
65 let (i, reserved1) = be_u8(i)?;
66 let (i, transform_length) = be_u16(i)?;
67 let (i, transform_type) = be_u8(i)?;
68 let (i, reserved2) = be_u8(i)?;
69 let (i, transform_id) = be_u16(i)?;
70 let (i, attributes) = cond(transform_length > 8, |d| take(transform_length - 8)(d))(i)?;
73 let transform = IkeV2RawTransform {
74 last,
75 reserved1,
76 transform_length,
77 transform_type: IkeTransformType(transform_type),
78 reserved2,
79 transform_id,
80 attributes,
81 };
82 Ok((i, transform))
83}
84
85pub fn parse_ikev2_proposal(i: &[u8]) -> IResult<&[u8], IkeV2Proposal> {
86 if i.len() < 8 {
87 return Err(Err::Incomplete(Needed::new(8)));
88 }
89 let (i, last) = be_u8(i)?;
90 let (i, reserved) = be_u8(i)?;
91 let (i, proposal_length) = be_u16(i)?;
92 let (i, proposal_num) = be_u8(i)?;
93 let (i, protocol_id) = map(be_u8, ProtocolID)(i)?;
94 let (i, spi_size) = be_u8(i)?;
95 let (i, num_transforms) = be_u8(i)?;
96 let (i, spi) = cond(spi_size > 0, take(spi_size))(i)?;
97 if proposal_length < (8u16 + spi_size as u16) {
98 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
99 }
100 let (i, transforms) = map_parser(
101 take(proposal_length - 8 - (spi_size as u16)),
102 count(parse_ikev2_transform, num_transforms as usize),
103 )(i)?;
104 let proposal = IkeV2Proposal {
105 last,
106 reserved,
107 proposal_length,
108 proposal_num,
109 protocol_id,
110 spi_size,
111 num_transforms,
112 spi,
113 transforms,
114 };
115 Ok((i, proposal))
116}
117
118pub fn parse_ikev2_payload_sa(i: &[u8], _length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
119 map(
120 many1(complete(parse_ikev2_proposal)),
121 IkeV2PayloadContent::SA,
122 )(i)
123}
124
125pub fn parse_ikev2_payload_kex(i: &[u8], length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
126 if length < 4 {
127 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
128 }
129 let (i, dh_group) = map(be_u16, IkeTransformDHType)(i)?;
130 let (i, reserved) = be_u16(i)?;
131 let (i, kex_data) = take(length - 4)(i)?;
132 let payload = KeyExchangePayload {
133 dh_group,
134 reserved,
135 kex_data,
136 };
137 Ok((i, IkeV2PayloadContent::KE(payload)))
138}
139
140pub fn parse_ikev2_payload_ident_init(
141 i: &[u8],
142 length: u16,
143) -> IResult<&[u8], IkeV2PayloadContent> {
144 if length < 4 {
145 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
146 }
147 let (i, id_type) = map(be_u8, IdentificationType)(i)?;
148 let (i, reserved1) = be_u8(i)?;
149 let (i, reserved2) = be_u16(i)?;
150 let (i, ident_data) = take(length - 4)(i)?;
151 let payload = IdentificationPayload {
152 id_type,
153 reserved1,
154 reserved2,
155 ident_data,
156 };
157 Ok((i, IkeV2PayloadContent::IDi(payload)))
158}
159
160pub fn parse_ikev2_payload_ident_resp(
161 i: &[u8],
162 length: u16,
163) -> IResult<&[u8], IkeV2PayloadContent> {
164 if length < 4 {
165 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
166 }
167 let (i, id_type) = map(be_u8, IdentificationType)(i)?;
168 let (i, reserved1) = be_u8(i)?;
169 let (i, reserved2) = be_u16(i)?;
170 let (i, ident_data) = take(length - 4)(i)?;
171 let payload = IdentificationPayload {
172 id_type,
173 reserved1,
174 reserved2,
175 ident_data,
176 };
177 Ok((i, IkeV2PayloadContent::IDr(payload)))
178}
179
180pub fn parse_ikev2_payload_certificate(
181 i: &[u8],
182 length: u16,
183) -> IResult<&[u8], IkeV2PayloadContent> {
184 if length < 1 {
185 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
186 }
187 let (i, cert_encoding) = map(be_u8, CertificateEncoding)(i)?;
188 let (i, cert_data) = take(length - 1)(i)?;
189 let payload = CertificatePayload {
190 cert_encoding,
191 cert_data,
192 };
193 Ok((i, IkeV2PayloadContent::Certificate(payload)))
194}
195
196pub fn parse_ikev2_payload_certificate_request(
197 i: &[u8],
198 length: u16,
199) -> IResult<&[u8], IkeV2PayloadContent> {
200 if length < 1 {
201 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
202 }
203 let (i, cert_encoding) = map(be_u8, CertificateEncoding)(i)?;
204 let (i, ca_data) = take(length - 1)(i)?;
205 let payload = CertificateRequestPayload {
206 cert_encoding,
207 ca_data,
208 };
209 Ok((i, IkeV2PayloadContent::CertificateRequest(payload)))
210}
211
212pub fn parse_ikev2_payload_authentication(
213 i: &[u8],
214 length: u16,
215) -> IResult<&[u8], IkeV2PayloadContent> {
216 if length < 4 {
217 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
218 }
219 let (i, auth_method) = map(be_u8, AuthenticationMethod)(i)?;
220 let (i, auth_data) = take(length - 4)(i)?;
221 let payload = AuthenticationPayload {
222 auth_method,
223 auth_data,
224 };
225 Ok((i, IkeV2PayloadContent::Authentication(payload)))
226}
227
228pub fn parse_ikev2_payload_nonce(i: &[u8], length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
229 let (i, nonce_data) = take(length)(i)?;
230 Ok((i, IkeV2PayloadContent::Nonce(NoncePayload { nonce_data })))
231}
232
233pub fn parse_ikev2_payload_notify(i: &[u8], length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
234 let (i, protocol_id) = map(be_u8, ProtocolID)(i)?;
235 let (i, spi_size) = be_u8(i)?;
236 let (i, notify_type) = map(be_u16, NotifyType)(i)?;
237 let (i, spi) = cond(spi_size > 0, take(spi_size))(i)?;
238 let (i, notify_data) = cond(
239 length > 8 + spi_size as u16,
240 |d| take(length - (8 + spi_size as u16))(d),
243 )(i)?;
244 let payload = NotifyPayload {
245 protocol_id,
246 spi_size,
247 notify_type,
248 spi,
249 notify_data,
250 };
251 Ok((i, IkeV2PayloadContent::Notify(payload)))
252}
253
254pub fn parse_ikev2_payload_vendor_id(i: &[u8], length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
255 if length < 8 {
256 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
257 }
258 let (i, vendor_id) = take(length - 8)(i)?;
259 Ok((
260 i,
261 IkeV2PayloadContent::VendorID(VendorIDPayload { vendor_id }),
262 ))
263}
264
265pub fn parse_ikev2_payload_delete(i: &[u8], length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
266 if length < 8 {
267 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
268 }
269 let (i, protocol_id) = map(be_u8, ProtocolID)(i)?;
270 let (i, spi_size) = be_u8(i)?;
271 let (i, num_spi) = be_u16(i)?;
272 let (i, spi) = take(length - 8)(i)?;
273 let payload = DeletePayload {
274 protocol_id,
275 spi_size,
276 num_spi,
277 spi,
278 };
279 Ok((i, IkeV2PayloadContent::Delete(payload)))
280}
281
282fn parse_ts_addr(i: &[u8], t: TSType) -> IResult<&[u8], &[u8]> {
283 match t {
284 TSType::IPv4AddrRange => take(4usize)(i),
285 TSType::IPv6AddrRange => take(16usize)(i),
286 _ => Err(nom::Err::Error(make_error(i, ErrorKind::Switch))),
287 }
288}
289
290fn parse_ikev2_ts(i: &[u8]) -> IResult<&[u8], TrafficSelector> {
291 let (i, ts_type) = map(be_u8, TSType)(i)?;
292 let (i, ip_proto_id) = be_u8(i)?;
293 let (i, sel_length) = be_u16(i)?;
294 let (i, start_port) = be_u16(i)?;
295 let (i, end_port) = be_u16(i)?;
296 let (i, start_addr) = parse_ts_addr(i, ts_type)?;
297 let (i, end_addr) = parse_ts_addr(i, ts_type)?;
298 let ts = TrafficSelector {
299 ts_type,
300 ip_proto_id,
301 sel_length,
302 start_port,
303 end_port,
304 start_addr,
305 end_addr,
306 };
307 Ok((i, ts))
308}
309
310pub fn parse_ikev2_payload_ts(i: &[u8], length: u16) -> IResult<&[u8], TrafficSelectorPayload> {
311 if length < 4 {
312 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
313 }
314 let (i, num_ts) = be_u8(i)?;
315 let (i, reserved) = take(3usize)(i)?;
316 let (i, ts) = map_parser(take(length - 4), many1(complete(parse_ikev2_ts)))(i)?;
317 let payload = TrafficSelectorPayload {
318 num_ts,
319 reserved,
320 ts,
321 };
322 Ok((i, payload))
323}
324
325pub fn parse_ikev2_payload_ts_init(i: &[u8], length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
326 map(
327 |d| parse_ikev2_payload_ts(d, length),
328 IkeV2PayloadContent::TSi,
329 )(i)
330}
331
332pub fn parse_ikev2_payload_ts_resp(i: &[u8], length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
333 map(
334 |d| parse_ikev2_payload_ts(d, length),
335 IkeV2PayloadContent::TSr,
336 )(i)
337}
338
339pub fn parse_ikev2_payload_encrypted(i: &[u8], length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
340 map(take(length), |d| {
341 IkeV2PayloadContent::Encrypted(EncryptedPayload(d))
342 })(i)
343}
344
345pub fn parse_ikev2_payload_unknown(i: &[u8], length: u16) -> IResult<&[u8], IkeV2PayloadContent> {
346 map(take(length), IkeV2PayloadContent::Unknown)(i)
347}
348
349#[rustfmt::skip]
350pub fn parse_ikev2_payload_with_type(
351 i: &[u8],
352 length: u16,
353 next_payload_type: IkePayloadType,
354) -> IResult<&[u8], IkeV2PayloadContent> {
355 let f = match next_payload_type {
356 IkePayloadType::SecurityAssociation => parse_ikev2_payload_sa,
358 IkePayloadType::KeyExchange => parse_ikev2_payload_kex,
359 IkePayloadType::IdentInitiator => parse_ikev2_payload_ident_init,
360 IkePayloadType::IdentResponder => parse_ikev2_payload_ident_resp,
361 IkePayloadType::Certificate => parse_ikev2_payload_certificate,
362 IkePayloadType::CertificateRequest => parse_ikev2_payload_certificate_request,
363 IkePayloadType::Authentication => parse_ikev2_payload_authentication,
364 IkePayloadType::Nonce => parse_ikev2_payload_nonce,
365 IkePayloadType::Notify => parse_ikev2_payload_notify,
366 IkePayloadType::Delete => parse_ikev2_payload_delete,
367 IkePayloadType::VendorID => parse_ikev2_payload_vendor_id,
368 IkePayloadType::TrafficSelectorInitiator => parse_ikev2_payload_ts_init,
369 IkePayloadType::TrafficSelectorResponder => parse_ikev2_payload_ts_resp,
370 IkePayloadType::EncryptedAndAuthenticated => parse_ikev2_payload_encrypted,
371 _ => parse_ikev2_payload_unknown,
373 };
375 map_parser(take(length),move |d| f(d, length))(i)
376}
377
378fn parse_ikev2_payload_list_fold<'a>(
379 res_v: Result<Vec<IkeV2Payload<'a>>, IPsecError>,
380 p: IkeV2GenericPayload<'a>,
381) -> Result<Vec<IkeV2Payload<'a>>, IPsecError> {
382 let mut v = res_v?;
383 debug_assert!(!v.is_empty());
385 let last_payload = v
386 .last()
387 .expect("parse_payload_list_fold: called with empty input");
388 let next_payload_type = last_payload.hdr.next_payload_type;
389 if p.hdr.payload_length < 4 {
390 return Err(IPsecError::PayloadTooSmall);
391 }
392 match parse_ikev2_payload_with_type(p.payload, p.hdr.payload_length - 4, next_payload_type) {
393 Ok((rem, p2)) => {
394 if !rem.is_empty() {
396 return Err(IPsecError::ExtraBytesInPayload); }
398 let payload = IkeV2Payload {
399 hdr: p.hdr.clone(),
400 content: p2,
401 };
402 v.push(payload);
403 Ok(v)
404 }
405 Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => Err(IPsecError::NomError(e.code)),
406 Err(nom::Err::Incomplete(_)) => Err(IPsecError::NomError(ErrorKind::Complete)),
407 }
408}
409
410pub fn parse_ikev2_payload_list(
411 i: &[u8],
412 initial_type: IkePayloadType,
413) -> IResult<&[u8], Result<Vec<IkeV2Payload>, IPsecError>> {
414 let mut acc = Ok(vec![IkeV2Payload {
417 hdr: IkeV2PayloadHeader {
418 next_payload_type: initial_type,
419 critical: false,
420 reserved: 0,
421 payload_length: 0,
422 },
423 content: IkeV2PayloadContent::Dummy,
424 }]);
425 #[allow(clippy::clone_double_ref)]
426 let mut i = i.clone();
427 loop {
428 if i.is_empty() {
429 break;
430 }
431
432 let (rem, p) = complete(parse_ikev2_payload_generic)(i)?;
433
434 acc = parse_ikev2_payload_list_fold(acc, p);
435
436 i = rem;
437 }
438 Ok((i, acc))
439 }
441
442#[allow(clippy::type_complexity)]
446pub fn parse_ikev2_message(
447 i: &[u8],
448) -> IResult<&[u8], (IkeV2Header, Result<Vec<IkeV2Payload>, IPsecError>)> {
449 let (i, hdr) = parse_ikev2_header(i)?;
450 if hdr.length < 28 {
451 return Err(Err::Error(make_error(i, ErrorKind::Verify)));
452 }
453 let (i, msg) = map_parser(take(hdr.length - 28), |d| {
454 parse_ikev2_payload_list(d, hdr.next_payload)
455 })(i)?;
456 Ok((i, (hdr, msg)))
457}
458
459#[cfg(test)]
460mod tests {
461 use crate::ikev2_parser::*;
462
463 #[rustfmt::skip]
464static IKEV2_INIT_REQ: &[u8] = &[
465 0x01, 0xf8, 0xc3, 0xd4, 0xbb, 0x77, 0x3f, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x21, 0x20, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x22, 0x00, 0x00, 0x30,
467 0x00, 0x00, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x04, 0x03, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x14,
468 0x80, 0x0e, 0x00, 0x80, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x08,
469 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x1e, 0x28, 0x00, 0x00, 0x88,
470 0x00, 0x1e, 0x00, 0x00, 0x8f, 0xe6, 0xf3, 0x6e, 0x88, 0x7b, 0x18, 0x9b, 0x5e, 0xce, 0xf2, 0x56,
471 0xf9, 0x8d, 0x76, 0xaa, 0xcb, 0x07, 0xb3, 0xb9, 0x58, 0xee, 0x73, 0xea, 0x7b, 0x73, 0xb1, 0x04,
472 0x7e, 0xa4, 0x2a, 0x4e, 0x44, 0x1f, 0xb9, 0x3e, 0xf9, 0xa9, 0xab, 0x0c, 0x54, 0x5a, 0xa7, 0x46,
473 0x2e, 0x58, 0x3c, 0x06, 0xb2, 0xed, 0x91, 0x8d, 0x11, 0xca, 0x67, 0xdb, 0x21, 0x6b, 0xb8, 0xad,
474 0xbf, 0x57, 0x3f, 0xba, 0x5a, 0xa6, 0x7d, 0x49, 0x83, 0x4b, 0xa9, 0x93, 0x6f, 0x4c, 0xe9, 0x66,
475 0xcd, 0x57, 0x5c, 0xba, 0x07, 0x42, 0xfa, 0x0b, 0xe8, 0xb9, 0xd0, 0x25, 0xc4, 0xb9, 0xdf, 0x29,
476 0xd7, 0xe4, 0x6e, 0xd6, 0x54, 0x78, 0xaa, 0x95, 0x02, 0xbf, 0x25, 0x55, 0x71, 0xfa, 0x9e, 0xcb,
477 0x05, 0xea, 0x8f, 0x7b, 0x14, 0x0e, 0x1d, 0xdf, 0xb4, 0x03, 0x5f, 0x2d, 0x21, 0x66, 0x58, 0x6e,
478 0x42, 0x72, 0x32, 0x03, 0x29, 0x00, 0x00, 0x24, 0xe3, 0x3b, 0x52, 0xaa, 0x6f, 0x6d, 0x62, 0x87,
479 0x16, 0xd7, 0xab, 0xc6, 0x45, 0xa6, 0xcc, 0x97, 0x07, 0x43, 0x3d, 0x85, 0x83, 0xde, 0xab, 0x97,
480 0xdb, 0xbf, 0x08, 0xce, 0x0f, 0xad, 0x59, 0x71, 0x29, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x04,
481 0xcc, 0xc0, 0x64, 0x5c, 0x1e, 0xeb, 0xc2, 0x1d, 0x09, 0x2b, 0xf0, 0x7f, 0xca, 0x34, 0xc3, 0xe6,
482 0x2b, 0x20, 0xec, 0x8f, 0x29, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x05, 0x15, 0x39, 0x75, 0x77,
483 0xf5, 0x54, 0x87, 0xa3, 0x8f, 0xd8, 0xaf, 0x70, 0xb0, 0x9c, 0x20, 0x9c, 0xff, 0x4a, 0x37, 0xd1,
484 0x29, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x2f, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
485 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x16
486];
487
488 #[test]
489 fn test_ikev2_init_req() {
490 let empty = &b""[..];
491 let bytes = &IKEV2_INIT_REQ[0..28];
492 let expected = Ok((
493 empty,
494 IkeV2Header {
495 init_spi: 0x01f8c3d4bb773f2f,
496 resp_spi: 0x0,
497 next_payload: IkePayloadType::SecurityAssociation,
498 maj_ver: 2,
499 min_ver: 0,
500 exch_type: IkeExchangeType::IKE_SA_INIT,
501 flags: 0x8,
502 msg_id: 0,
503 length: 328,
504 },
505 ));
506 let res = parse_ikev2_header(bytes);
507 assert_eq!(res, expected);
508 }
509
510 static IKEV2_INIT_RESP: &[u8] = include_bytes!("../assets/ike-sa-init-resp.bin");
511
512 #[test]
513 fn test_ikev2_init_resp() {
514 let bytes = IKEV2_INIT_RESP;
515 let (rem, ref hdr) = parse_ikev2_header(bytes).expect("parsing header failed");
516 let (rem2, res_p) =
517 parse_ikev2_payload_list(rem, hdr.next_payload).expect("parsing payload failed");
518 assert!(rem2.is_empty());
519 let p = res_p.expect("parsing payload failed");
520 assert_eq!(p.len(), 6);
522 assert_eq!(p[0].content, IkeV2PayloadContent::Dummy);
524 }
525
526 #[rustfmt::skip]
527static IKEV2_PAYLOAD_SA: &[u8] = &[
528 0x22, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x01, 0x01, 0x00, 0x03, 0x03, 0x00, 0x00, 0x0c,
529 0x01, 0x00, 0x00, 0x14, 0x80, 0x0e, 0x00, 0x80, 0x03, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x05,
530 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x1e
531];
532
533 #[test]
534 fn test_ikev2_payload_sa() {
535 let bytes = IKEV2_PAYLOAD_SA;
536 let expected1 = IkeV2GenericPayload {
537 hdr: IkeV2PayloadHeader {
538 next_payload_type: IkePayloadType::KeyExchange,
539 critical: false,
540 reserved: 0,
541 payload_length: 40,
542 },
543 payload: &bytes[4..],
544 };
545 let (_, res) = parse_ikev2_payload_generic(bytes).expect("Failed to parse");
546 assert_eq!(res, expected1);
547 let attrs1 = &[0x80, 0x0e, 0x00, 0x80];
548 let expected2 = IkeV2PayloadContent::SA(vec![IkeV2Proposal {
549 last: 0,
550 reserved: 0,
551 proposal_length: 36,
552 proposal_num: 1,
553 protocol_id: ProtocolID::IKE,
554 spi_size: 0,
555 num_transforms: 3,
556 spi: None,
557 transforms: vec![
558 IkeV2RawTransform {
559 last: 3,
560 reserved1: 0,
561 transform_length: 12,
562 transform_type: IkeTransformType::EncryptionAlgorithm,
563 reserved2: 0,
564 transform_id: 20,
565 attributes: Some(attrs1),
566 },
567 IkeV2RawTransform {
568 last: 3,
569 reserved1: 0,
570 transform_length: 8,
571 transform_type: IkeTransformType::PseudoRandomFunction,
572 reserved2: 0,
573 transform_id: 5,
574 attributes: None,
575 },
576 IkeV2RawTransform {
577 last: 0,
578 reserved1: 0,
579 transform_length: 8,
580 transform_type: IkeTransformType::DiffieHellmanGroup,
581 reserved2: 0,
582 transform_id: 30,
583 attributes: None,
584 },
585 ],
586 }]);
587
588 let (rem, res2) = parse_ikev2_payload_sa(res.payload, 0).expect("Failed to parse");
589 assert!(rem.is_empty());
590 assert_eq!(res2, expected2);
591 }
592
593 #[test]
594 fn test_ikev2_parse_payload_many() {
595 let bytes = &IKEV2_INIT_REQ[28..];
597 let res = parse_ikev2_payload_list(bytes, IkePayloadType::SecurityAssociation);
598 println!("{:?}", res);
599 }
600}