ipsec_parser/ikev2.rs
1use crate::ikev2_notify::NotifyType;
2use crate::ikev2_transforms::*;
3use rusticata_macros::newtype_enum;
4use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
5
6/// Payload exchange type: SA, Auth, CreateChildSA, etc.
7#[derive(Copy, Clone, PartialEq, Eq)]
8pub struct IkeExchangeType(pub u8);
9
10newtype_enum! {
11impl debug IkeExchangeType {
12 IKE_SA_INIT = 34,
13 IKE_AUTH = 35,
14 CREATE_CHILD_SA = 36,
15 INFORMATIONAL = 37,
16}
17}
18
19/// Protocol type: IKE, AH or ESP
20///
21/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.3.1
22#[derive(Clone, Copy, PartialEq, Eq)]
23pub struct ProtocolID(pub u8);
24
25newtype_enum! {
26impl debug ProtocolID {
27 IKE = 1,
28 AH = 2,
29 ESP = 3,
30}
31}
32
33pub const IKEV2_FLAG_INITIATOR: u8 = 0b1000;
34pub const IKEV2_FLAG_VERSION: u8 = 0b1_0000;
35pub const IKEV2_FLAG_RESPONSE: u8 = 0b10_0000;
36
37/// The IKE Header
38///
39/// IKE messages use UDP ports 500 and/or 4500, with one IKE message per
40/// UDP datagram. Information from the beginning of the packet through
41/// the UDP header is largely ignored except that the IP addresses and
42/// UDP ports from the headers are reversed and used for return packets.
43/// When sent on UDP port 500, IKE messages begin immediately following
44/// the UDP header. When sent on UDP port 4500, IKE messages have
45/// prepended four octets of zeros. These four octets of zeros are not
46/// part of the IKE message and are not included in any of the length
47/// fields or checksums defined by IKE. Each IKE message begins with the
48/// IKE header, denoted HDR in this document. Following the header are
49/// one or more IKE payloads each identified by a Next Payload field in
50/// the preceding payload. Payloads are identified in the order in which
51/// they appear in an IKE message by looking in the Next Payload field in
52/// the IKE header, and subsequently according to the Next Payload field
53/// in the IKE payload itself until a Next Payload field of zero
54/// indicates that no payloads follow. If a payload of type "Encrypted"
55/// is found, that payload is decrypted and its contents parsed as
56/// additional payloads. An Encrypted payload MUST be the last payload
57/// in a packet and an Encrypted payload MUST NOT contain another
58/// Encrypted payload.
59///
60/// The responder's SPI in the header identifies an instance of an IKE
61/// Security Association. It is therefore possible for a single instance
62/// of IKE to multiplex distinct sessions with multiple peers, including
63/// multiple sessions per peer.
64///
65/// All multi-octet fields representing integers are laid out in big
66/// endian order (also known as "most significant byte first", or
67/// "network byte order").
68///
69/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.1
70#[derive(Clone, Debug, PartialEq)]
71pub struct IkeV2Header {
72 pub init_spi: u64,
73 pub resp_spi: u64,
74 pub next_payload: IkePayloadType,
75 pub maj_ver: u8,
76 pub min_ver: u8,
77 pub exch_type: IkeExchangeType,
78 pub flags: u8,
79 pub msg_id: u32,
80 pub length: u32,
81}
82
83/// Payload type
84#[derive(Clone, Copy, PartialEq, Eq)]
85pub struct IkePayloadType(pub u8);
86
87newtype_enum! {
88impl debug IkePayloadType {
89 NoNextPayload = 0,
90 SecurityAssociation = 33,
91 KeyExchange = 34,
92 IdentInitiator = 35,
93 IdentResponder = 36,
94 Certificate = 37,
95 CertificateRequest = 38,
96 Authentication = 39,
97 Nonce = 40,
98 Notify = 41,
99 Delete = 42,
100 VendorID = 43,
101 TrafficSelectorInitiator = 44,
102 TrafficSelectorResponder = 45,
103 EncryptedAndAuthenticated = 46,
104 Configuration = 47,
105 ExtensibleAuthentication = 48,
106}
107}
108
109/// Generic (unparsed payload)
110///
111/// Defined in [RFC7296]
112#[derive(Debug, PartialEq)]
113pub struct IkeV2GenericPayload<'a> {
114 pub hdr: IkeV2PayloadHeader,
115 pub payload: &'a [u8],
116}
117
118/// Ciphersuite Proposal
119///
120/// The Proposal structure contains within it a Proposal Num and an IPsec
121/// protocol ID. Each structure MUST have a proposal number one (1)
122/// greater than the previous structure. The first Proposal in the
123/// initiator's SA payload MUST have a Proposal Num of one (1). One
124/// reason to use multiple proposals is to propose both standard crypto
125/// ciphers and combined-mode ciphers. Combined-mode ciphers include
126/// both integrity and encryption in a single encryption algorithm, and
127/// MUST either offer no integrity algorithm or a single integrity
128/// algorithm of "NONE", with no integrity algorithm being the
129/// RECOMMENDED method. If an initiator wants to propose both combined-
130/// mode ciphers and normal ciphers, it must include two proposals: one
131/// will have all the combined-mode ciphers, and the other will have all
132/// the normal ciphers with the integrity algorithms. For example, one
133/// such proposal would have two proposal structures. Proposal 1 is ESP
134/// with AES-128, AES-192, and AES-256 bits in Cipher Block Chaining
135/// (CBC) mode, with either HMAC-SHA1-96 or XCBC-96 as the integrity
136/// algorithm; Proposal 2 is AES-128 or AES-256 in GCM mode with an
137/// 8-octet Integrity Check Value (ICV). Both proposals allow but do not
138/// require the use of ESNs (Extended Sequence Numbers). This can be
139/// illustrated as:
140///
141/// ```ignore
142/// SA Payload
143/// |
144/// +--- Proposal #1 ( Proto ID = ESP(3), SPI size = 4,
145/// | | 7 transforms, SPI = 0x052357bb )
146/// | |
147/// | +-- Transform ENCR ( Name = ENCR_AES_CBC )
148/// | | +-- Attribute ( Key Length = 128 )
149/// | |
150/// | +-- Transform ENCR ( Name = ENCR_AES_CBC )
151/// | | +-- Attribute ( Key Length = 192 )
152/// | |
153/// | +-- Transform ENCR ( Name = ENCR_AES_CBC )
154/// | | +-- Attribute ( Key Length = 256 )
155/// | |
156/// | +-- Transform INTEG ( Name = AUTH_HMAC_SHA1_96 )
157/// | +-- Transform INTEG ( Name = AUTH_AES_XCBC_96 )
158/// | +-- Transform ESN ( Name = ESNs )
159/// | +-- Transform ESN ( Name = No ESNs )
160/// |
161/// +--- Proposal #2 ( Proto ID = ESP(3), SPI size = 4,
162/// | 4 transforms, SPI = 0x35a1d6f2 )
163/// |
164/// +-- Transform ENCR ( Name = AES-GCM with a 8 octet ICV )
165/// | +-- Attribute ( Key Length = 128 )
166/// |
167/// +-- Transform ENCR ( Name = AES-GCM with a 8 octet ICV )
168/// | +-- Attribute ( Key Length = 256 )
169/// |
170/// +-- Transform ESN ( Name = ESNs )
171/// +-- Transform ESN ( Name = No ESNs )
172/// ```
173///
174/// Each Proposal/Protocol structure is followed by one or more transform
175/// structures. The number of different transforms is generally
176/// determined by the Protocol. AH generally has two transforms:
177/// Extended Sequence Numbers (ESNs) and an integrity check algorithm.
178/// ESP generally has three: ESN, an encryption algorithm, and an
179/// integrity check algorithm. IKE generally has four transforms: a
180/// Diffie-Hellman group, an integrity check algorithm, a PRF algorithm,
181/// and an encryption algorithm. For each Protocol, the set of
182/// permissible transforms is assigned Transform ID numbers, which appear
183/// in the header of each transform.
184///
185/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.3.1
186#[derive(Clone, Debug, PartialEq)]
187pub struct IkeV2Proposal<'a> {
188 pub last: u8,
189 pub reserved: u8,
190 pub proposal_length: u16,
191 pub proposal_num: u8,
192 pub protocol_id: ProtocolID,
193 pub spi_size: u8,
194 pub num_transforms: u8,
195 pub spi: Option<&'a [u8]>,
196 pub transforms: Vec<IkeV2RawTransform<'a>>,
197}
198
199/// Key Exchange Payload
200///
201/// The Key Exchange payload, denoted KE in this document, is used to
202/// exchange Diffie-Hellman public numbers as part of a Diffie-Hellman
203/// key exchange. The Key Exchange payload consists of the IKE generic
204/// payload header followed by the Diffie-Hellman public value itself.
205///
206/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.4
207#[derive(Debug, PartialEq)]
208pub struct KeyExchangePayload<'a> {
209 pub dh_group: IkeTransformDHType,
210 pub reserved: u16,
211 pub kex_data: &'a [u8],
212}
213
214/// Identification Payloads
215///
216/// The Identification payloads, denoted IDi and IDr in this document,
217/// allow peers to assert an identity to one another. This identity may
218/// be used for policy lookup, but does not necessarily have to match
219/// anything in the CERT payload; both fields may be used by an
220/// implementation to perform access control decisions. When using the
221/// ID_IPV4_ADDR/ID_IPV6_ADDR identity types in IDi/IDr payloads, IKEv2
222/// does not require this address to match the address in the IP header
223/// of IKEv2 packets, or anything in the TSi/TSr payloads. The contents
224/// of IDi/IDr are used purely to fetch the policy and authentication
225/// data related to the other party.
226///
227/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.5
228#[derive(Debug, PartialEq)]
229pub struct IdentificationPayload<'a> {
230 pub id_type: IdentificationType,
231 pub reserved1: u8,
232 pub reserved2: u16,
233 pub ident_data: &'a [u8],
234}
235
236/// Type of Identification
237#[derive(Clone, Copy, Debug, PartialEq, Eq)]
238pub struct IdentificationType(pub u8);
239
240#[rustfmt::skip]
241impl IdentificationType {
242 /// A single four (4) octet IPv4 address.
243 pub const ID_IPV4_ADDR : IdentificationType = IdentificationType(1);
244 /// A fully-qualified domain name string. An example of an ID_FQDN
245 /// is "example.com". The string MUST NOT contain any terminators
246 /// (e.g., NULL, CR, etc.). All characters in the ID_FQDN are ASCII;
247 /// for an "internationalized domain name", the syntax is as defined
248 /// in [IDNA], for example "xn--tmonesimerkki-bfbb.example.net".
249 pub const ID_FQDN : IdentificationType = IdentificationType(2);
250 /// A fully-qualified RFC 822 email address string. An example of a
251 /// ID_RFC822_ADDR is "jsmith@example.com". The string MUST NOT
252 /// contain any terminators. Because of [EAI], implementations would
253 /// be wise to treat this field as UTF-8 encoded text, not as
254 /// pure ASCII.
255 pub const ID_RFC822_ADDR : IdentificationType = IdentificationType(3);
256 /// A single sixteen (16) octet IPv6 address.
257 pub const ID_IPV6_ADDR : IdentificationType = IdentificationType(5);
258 /// The binary Distinguished Encoding Rules (DER) encoding of an ASN.1 X.500 Distinguished
259 /// Name.
260 pub const ID_DER_ASN1_DN : IdentificationType = IdentificationType(9);
261 /// The binary DER encoding of an ASN.1 X.509 GeneralName.
262 pub const ID_DER_ASN1_GN : IdentificationType = IdentificationType(10);
263 /// An opaque octet stream that may be used to pass vendor-specific information necessary to do
264 /// certain proprietary types of identification.
265 pub const ID_KEY_ID : IdentificationType = IdentificationType(11);
266}
267
268/// Certificate Payload
269///
270/// The Certificate payload, denoted CERT in this document, provides a
271/// means to transport certificates or other authentication-related
272/// information via IKE. Certificate payloads SHOULD be included in an
273/// exchange if certificates are available to the sender. The Hash and
274/// URL formats of the Certificate payloads should be used in case the
275/// peer has indicated an ability to retrieve this information from
276/// elsewhere using an HTTP_CERT_LOOKUP_SUPPORTED Notify payload. Note
277/// that the term "Certificate payload" is somewhat misleading, because
278/// not all authentication mechanisms use certificates and data other
279/// than certificates may be passed in this payload.
280///
281/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.6
282#[derive(Debug, PartialEq)]
283pub struct CertificatePayload<'a> {
284 pub cert_encoding: CertificateEncoding,
285 pub cert_data: &'a [u8],
286}
287
288/// Certificate Encoding
289///
290/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.6
291#[derive(Clone, Copy, Debug, PartialEq, Eq)]
292pub struct CertificateEncoding(pub u8);
293
294#[allow(non_upper_case_globals)]
295#[rustfmt::skip]
296impl CertificateEncoding {
297 /// PKCS #7 wrapped X.509 certificate
298 pub const Pkcs7_X509 : CertificateEncoding = CertificateEncoding(1);
299 /// PGP Certificate
300 pub const PgpCert : CertificateEncoding = CertificateEncoding(2);
301 /// DNS Signed Key
302 pub const DnsKey : CertificateEncoding = CertificateEncoding(3);
303 /// X.509 Certificate - Signature
304 pub const X509Sig : CertificateEncoding = CertificateEncoding(4);
305 /// Kerberos Token
306 pub const Kerberos : CertificateEncoding = CertificateEncoding(6);
307 /// Certificate Revocation List (CRL)
308 pub const Crl : CertificateEncoding = CertificateEncoding(7);
309 /// Authority Revocation List (ARL)
310 pub const Arl : CertificateEncoding = CertificateEncoding(8);
311 /// SPKI Certificate
312 pub const SpkiCert : CertificateEncoding = CertificateEncoding(9);
313 /// X.509 Certificate - Attribute
314 pub const X509CertAttr : CertificateEncoding = CertificateEncoding(10);
315 /// Deprecated (was Raw RSA Key)
316 pub const OldRsaKey : CertificateEncoding = CertificateEncoding(11);
317 /// Hash and URL of X.509 certificate
318 pub const X509Cert_HashUrl : CertificateEncoding = CertificateEncoding(12);
319 /// Hash and URL of X.509 bundle
320 pub const X509Bundle_HashUrl : CertificateEncoding = CertificateEncoding(13);
321 /// OCSP Content ([RFC4806](https://tools.ietf.org/html/rfc4806))
322 pub const OCSPContent : CertificateEncoding = CertificateEncoding(14);
323 /// Raw Public Key ([RFC7670](https://tools.ietf.org/html/rfc7670))
324 pub const RawPublicKey : CertificateEncoding = CertificateEncoding(15);
325}
326
327/// Certificate Request Payload
328///
329/// The Certificate Request payload, denoted CERTREQ in this document,
330/// provides a means to request preferred certificates via IKE and can
331/// appear in the IKE_INIT_SA response and/or the IKE_AUTH request.
332/// Certificate Request payloads MAY be included in an exchange when the
333/// sender needs to get the certificate of the receiver.
334///
335/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.7
336#[derive(Debug, PartialEq)]
337pub struct CertificateRequestPayload<'a> {
338 pub cert_encoding: CertificateEncoding,
339 pub ca_data: &'a [u8],
340}
341
342/// Authentication Payload
343///
344/// The Authentication payload, denoted AUTH in this document, contains
345/// data used for authentication purposes.
346///
347/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.8
348#[derive(Debug, PartialEq)]
349pub struct AuthenticationPayload<'a> {
350 pub auth_method: AuthenticationMethod,
351 pub auth_data: &'a [u8],
352}
353
354/// Method of authentication used.
355///
356/// See also [IKEV2IANA](https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml) for the latest values.
357#[derive(Clone, Copy, Debug, PartialEq, Eq)]
358pub struct AuthenticationMethod(pub u8);
359
360#[allow(non_upper_case_globals)]
361#[rustfmt::skip]
362impl AuthenticationMethod {
363 /// RSA Digital Signature
364 pub const RsaSig : AuthenticationMethod = AuthenticationMethod(1);
365 /// Shared Key Message Integrity Code
366 pub const SharedKeyMIC : AuthenticationMethod = AuthenticationMethod(2);
367 /// DSS Digital Signature
368 pub const DssSig : AuthenticationMethod = AuthenticationMethod(3);
369 /// ECDSA with SHA-256 on the P-256 curve
370 pub const EcdsaSha256P256 : AuthenticationMethod = AuthenticationMethod(9);
371 /// ECDSA with SHA-384 on the P-384 curve
372 pub const EcdsaSha384P384 : AuthenticationMethod = AuthenticationMethod(10);
373 /// ECDSA with SHA-512 on the P-512 curve
374 pub const EcdsaSha512P512 : AuthenticationMethod = AuthenticationMethod(11);
375 /// Generic Secure Password Authentication Method
376 pub const GenericPass : AuthenticationMethod = AuthenticationMethod(12);
377 /// NULL Authentication
378 pub const Null : AuthenticationMethod = AuthenticationMethod(13);
379 /// Digital Signature
380 pub const DigitalSig : AuthenticationMethod = AuthenticationMethod(14);
381
382 /// Test if value is in unassigned range
383 pub fn is_unassigned(self) -> bool {
384 (self.0 >= 4 && self.0 <= 8) ||
385 (self.0 >= 15 && self.0 <= 200)
386 }
387
388 /// Test if value is in private use range
389 pub fn is_private_use(self) -> bool {
390 self.0 >= 201
391 }
392}
393
394/// Nonce Payload
395///
396/// The Nonce payload, denoted as Ni and Nr in this document for the
397/// initiator's and responder's nonce, respectively, contains random data used to guarantee
398/// liveness during an exchange and protect against replay attacks.
399///
400/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.9
401#[derive(PartialEq)]
402pub struct NoncePayload<'a> {
403 pub nonce_data: &'a [u8],
404}
405
406/// Notify Payload
407///
408/// The Notify payload, denoted N in this document, is used to transmit informational data, such as
409/// error conditions and state transitions, to an IKE peer. A Notify payload may appear in a
410/// response message (usually specifying why a request was rejected), in an INFORMATIONAL exchange
411/// (to report an error not in an IKE request), or in any other message to indicate sender
412/// capabilities or to modify the meaning of the request.
413///
414/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.10
415#[derive(PartialEq)]
416pub struct NotifyPayload<'a> {
417 pub protocol_id: ProtocolID,
418 pub spi_size: u8,
419 pub notify_type: NotifyType,
420 pub spi: Option<&'a [u8]>,
421 pub notify_data: Option<&'a [u8]>,
422}
423
424/// Delete Payload
425///
426/// The Delete payload, denoted D in this document, contains a
427/// protocol-specific Security Association identifier that the sender has
428/// removed from its Security Association database and is, therefore, no
429/// longer valid. Figure 17 shows the format of the Delete payload. It
430/// is possible to send multiple SPIs in a Delete payload; however, each
431/// SPI MUST be for the same protocol. Mixing of protocol identifiers
432/// MUST NOT be performed in the Delete payload. It is permitted,
433/// however, to include multiple Delete payloads in a single
434/// INFORMATIONAL exchange where each Delete payload lists SPIs for a
435/// different protocol.
436///
437/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.11
438#[derive(Debug, PartialEq)]
439pub struct DeletePayload<'a> {
440 pub protocol_id: ProtocolID,
441 pub spi_size: u8,
442 pub num_spi: u16,
443 pub spi: &'a [u8],
444}
445
446/// Vendor ID Payload
447///
448/// The Vendor ID payload, denoted V in this document, contains a vendor-
449/// defined constant. The constant is used by vendors to identify and
450/// recognize remote instances of their implementations. This mechanism
451/// allows a vendor to experiment with new features while maintaining
452/// backward compatibility.
453///
454/// A Vendor ID payload MAY announce that the sender is capable of
455/// accepting certain extensions to the protocol, or it MAY simply
456/// identify the implementation as an aid in debugging. A Vendor ID
457/// payload MUST NOT change the interpretation of any information defined
458/// in this specification (i.e., the critical bit MUST be set to 0).
459/// Multiple Vendor ID payloads MAY be sent. An implementation is not
460/// required to send any Vendor ID payload at all.
461///
462/// A Vendor ID payload may be sent as part of any message. Reception of
463/// a familiar Vendor ID payload allows an implementation to make use of
464/// private use numbers described throughout this document, such as
465/// private payloads, private exchanges, private notifications, etc.
466/// Unfamiliar Vendor IDs MUST be ignored.
467///
468/// Writers of documents who wish to extend this protocol MUST define a
469/// Vendor ID payload to announce the ability to implement the extension
470/// in the document. It is expected that documents that gain acceptance
471/// and are standardized will be given "magic numbers" out of the Future
472/// Use range by IANA, and the requirement to use a Vendor ID will go
473/// away.
474///
475/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.12
476#[derive(Debug, PartialEq)]
477pub struct VendorIDPayload<'a> {
478 pub vendor_id: &'a [u8],
479}
480
481/// Type of Traffic Selector
482///
483/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.13.1
484///
485/// See also [IKEV2IANA](https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml) for the latest values.
486#[derive(Clone, Copy, Debug, PartialEq, Eq)]
487pub struct TSType(pub u8);
488
489#[allow(non_upper_case_globals)]
490impl TSType {
491 /// A range of IPv4 addresses
492 pub const IPv4AddrRange: TSType = TSType(7);
493 /// A range of IPv6 addresses
494 pub const IPv6AddrRange: TSType = TSType(8);
495 /// Fibre Channel Traffic Selectors ([RFC4595](https://tools.ietf.org/html/rfc4595))
496 pub const FcAddrRange: TSType = TSType(9);
497}
498
499/// Traffic Selector
500///
501/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.13.1
502#[derive(Debug, PartialEq)]
503pub struct TrafficSelector<'a> {
504 pub ts_type: TSType,
505 pub ip_proto_id: u8,
506 pub sel_length: u16,
507 pub start_port: u16,
508 pub end_port: u16,
509 pub start_addr: &'a [u8],
510 pub end_addr: &'a [u8],
511}
512
513fn ipv4_from_slice(b: &[u8]) -> Ipv4Addr {
514 Ipv4Addr::new(b[0], b[1], b[2], b[3])
515}
516
517fn ipv6_from_slice(b: &[u8]) -> Ipv6Addr {
518 Ipv6Addr::new(
519 (b[0] as u16) << 8 | (b[1] as u16),
520 (b[2] as u16) << 8 | (b[3] as u16),
521 (b[4] as u16) << 8 | (b[5] as u16),
522 (b[6] as u16) << 8 | (b[7] as u16),
523 (b[8] as u16) << 8 | (b[9] as u16),
524 (b[10] as u16) << 8 | (b[11] as u16),
525 (b[12] as u16) << 8 | (b[13] as u16),
526 (b[14] as u16) << 8 | (b[15] as u16),
527 )
528}
529
530impl<'a> TrafficSelector<'a> {
531 pub fn get_ts_type(&self) -> TSType {
532 self.ts_type
533 }
534
535 pub fn get_start_addr(&self) -> Option<IpAddr> {
536 match self.ts_type {
537 TSType::IPv4AddrRange => Some(IpAddr::V4(ipv4_from_slice(self.start_addr))),
538 TSType::IPv6AddrRange => Some(IpAddr::V6(ipv6_from_slice(self.start_addr))),
539 _ => None,
540 }
541 }
542
543 pub fn get_end_addr(&self) -> Option<IpAddr> {
544 match self.ts_type {
545 TSType::IPv4AddrRange => Some(IpAddr::V4(ipv4_from_slice(self.end_addr))),
546 TSType::IPv6AddrRange => Some(IpAddr::V6(ipv6_from_slice(self.end_addr))),
547 _ => None,
548 }
549 }
550}
551
552/// Traffic Selector Payload
553///
554/// The Traffic Selector payload, denoted TS in this document, allows
555/// peers to identify packet flows for processing by IPsec security
556/// services. The Traffic Selector payload consists of the IKE generic
557/// payload header followed by individual Traffic Selectors.
558///
559/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.13
560#[derive(Debug, PartialEq)]
561pub struct TrafficSelectorPayload<'a> {
562 pub num_ts: u8,
563 pub reserved: &'a [u8], // 3 bytes
564 pub ts: Vec<TrafficSelector<'a>>,
565}
566
567/// Encrypted Payload
568///
569/// The Encrypted payload, denoted SK {...} in this document, contains
570/// other payloads in encrypted form. The Encrypted payload, if present
571/// in a message, MUST be the last payload in the message. Often, it is
572/// the only payload in the message. This payload is also called the
573/// "Encrypted and Authenticated" payload.
574#[derive(Debug, PartialEq)]
575pub struct EncryptedPayload<'a>(pub &'a [u8]);
576
577/// IKE Message Payload Content
578///
579/// The content of an IKE message is one of the defined payloads.
580///
581/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.2
582#[derive(Debug, PartialEq)]
583pub enum IkeV2PayloadContent<'a> {
584 SA(Vec<IkeV2Proposal<'a>>),
585 KE(KeyExchangePayload<'a>),
586 IDi(IdentificationPayload<'a>),
587 IDr(IdentificationPayload<'a>),
588 Certificate(CertificatePayload<'a>),
589 CertificateRequest(CertificateRequestPayload<'a>),
590 Authentication(AuthenticationPayload<'a>),
591 Nonce(NoncePayload<'a>),
592 Notify(NotifyPayload<'a>),
593 Delete(DeletePayload<'a>),
594 VendorID(VendorIDPayload<'a>),
595 TSi(TrafficSelectorPayload<'a>),
596 TSr(TrafficSelectorPayload<'a>),
597 Encrypted(EncryptedPayload<'a>),
598
599 Unknown(&'a [u8]),
600
601 Dummy,
602}
603
604/// Generic Payload Header
605///
606/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3.2
607#[derive(Clone, Debug, PartialEq)]
608pub struct IkeV2PayloadHeader {
609 pub next_payload_type: IkePayloadType,
610 pub critical: bool,
611 pub reserved: u8,
612 pub payload_length: u16,
613}
614
615/// IKE Message Payload
616///
617/// Defined in [RFC7296](https://tools.ietf.org/html/rfc7296) section 3
618#[derive(Debug, PartialEq)]
619pub struct IkeV2Payload<'a> {
620 pub hdr: IkeV2PayloadHeader,
621 pub content: IkeV2PayloadContent<'a>,
622}