/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ipsec-parser-0.7.0/src/ikev2.rs
Line | Count | Source |
1 | | use crate::ikev2_notify::NotifyType; |
2 | | use crate::ikev2_transforms::*; |
3 | | use rusticata_macros::newtype_enum; |
4 | | use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; |
5 | | |
6 | | /// Payload exchange type: SA, Auth, CreateChildSA, etc. |
7 | | #[derive(Copy, Clone, PartialEq, Eq)] |
8 | | pub struct IkeExchangeType(pub u8); |
9 | | |
10 | | newtype_enum! { |
11 | | impl 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)] |
23 | | pub struct ProtocolID(pub u8); |
24 | | |
25 | | newtype_enum! { |
26 | | impl debug ProtocolID { |
27 | | IKE = 1, |
28 | | AH = 2, |
29 | | ESP = 3, |
30 | | } |
31 | | } |
32 | | |
33 | | pub const IKEV2_FLAG_INITIATOR: u8 = 0b1000; |
34 | | pub const IKEV2_FLAG_VERSION: u8 = 0b1_0000; |
35 | | pub 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)] |
71 | | pub 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)] |
85 | | pub struct IkePayloadType(pub u8); |
86 | | |
87 | | newtype_enum! { |
88 | | impl 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)] |
113 | | pub 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)] |
187 | | pub 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)] |
208 | | pub 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)] |
229 | | pub 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)] |
238 | | pub struct IdentificationType(pub u8); |
239 | | |
240 | | #[rustfmt::skip] |
241 | | impl 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)] |
283 | | pub 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)] |
292 | | pub struct CertificateEncoding(pub u8); |
293 | | |
294 | | #[allow(non_upper_case_globals)] |
295 | | #[rustfmt::skip] |
296 | | impl 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)] |
337 | | pub 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)] |
349 | | pub 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)] |
358 | | pub struct AuthenticationMethod(pub u8); |
359 | | |
360 | | #[allow(non_upper_case_globals)] |
361 | | #[rustfmt::skip] |
362 | | impl 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 | 0 | pub fn is_unassigned(self) -> bool { |
384 | 0 | (self.0 >= 4 && self.0 <= 8) || |
385 | 0 | (self.0 >= 15 && self.0 <= 200) |
386 | 0 | } Unexecuted instantiation: <ipsec_parser::ikev2::AuthenticationMethod>::is_unassigned Unexecuted instantiation: <ipsec_parser::ikev2::AuthenticationMethod>::is_unassigned |
387 | | |
388 | | /// Test if value is in private use range |
389 | 0 | pub fn is_private_use(self) -> bool { |
390 | 0 | self.0 >= 201 |
391 | 0 | } Unexecuted instantiation: <ipsec_parser::ikev2::AuthenticationMethod>::is_private_use Unexecuted instantiation: <ipsec_parser::ikev2::AuthenticationMethod>::is_private_use |
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)] |
402 | | pub 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)] |
416 | | pub 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)] |
439 | | pub 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)] |
477 | | pub 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)] |
487 | | pub struct TSType(pub u8); |
488 | | |
489 | | #[allow(non_upper_case_globals)] |
490 | | impl 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)] |
503 | | pub 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 | | |
513 | 0 | fn ipv4_from_slice(b: &[u8]) -> Ipv4Addr { |
514 | 0 | Ipv4Addr::new(b[0], b[1], b[2], b[3]) |
515 | 0 | } Unexecuted instantiation: ipsec_parser::ikev2::ipv4_from_slice Unexecuted instantiation: ipsec_parser::ikev2::ipv4_from_slice |
516 | | |
517 | 0 | fn ipv6_from_slice(b: &[u8]) -> Ipv6Addr { |
518 | 0 | Ipv6Addr::new( |
519 | 0 | (b[0] as u16) << 8 | (b[1] as u16), |
520 | 0 | (b[2] as u16) << 8 | (b[3] as u16), |
521 | 0 | (b[4] as u16) << 8 | (b[5] as u16), |
522 | 0 | (b[6] as u16) << 8 | (b[7] as u16), |
523 | 0 | (b[8] as u16) << 8 | (b[9] as u16), |
524 | 0 | (b[10] as u16) << 8 | (b[11] as u16), |
525 | 0 | (b[12] as u16) << 8 | (b[13] as u16), |
526 | 0 | (b[14] as u16) << 8 | (b[15] as u16), |
527 | | ) |
528 | 0 | } Unexecuted instantiation: ipsec_parser::ikev2::ipv6_from_slice Unexecuted instantiation: ipsec_parser::ikev2::ipv6_from_slice |
529 | | |
530 | | impl<'a> TrafficSelector<'a> { |
531 | 0 | pub fn get_ts_type(&self) -> TSType { |
532 | 0 | self.ts_type |
533 | 0 | } Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_ts_type Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_ts_type |
534 | | |
535 | 0 | pub fn get_start_addr(&self) -> Option<IpAddr> { |
536 | 0 | match self.ts_type { |
537 | 0 | TSType::IPv4AddrRange => Some(IpAddr::V4(ipv4_from_slice(self.start_addr))), |
538 | 0 | TSType::IPv6AddrRange => Some(IpAddr::V6(ipv6_from_slice(self.start_addr))), |
539 | 0 | _ => None, |
540 | | } |
541 | 0 | } Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_start_addr Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_start_addr |
542 | | |
543 | 0 | pub fn get_end_addr(&self) -> Option<IpAddr> { |
544 | 0 | match self.ts_type { |
545 | 0 | TSType::IPv4AddrRange => Some(IpAddr::V4(ipv4_from_slice(self.end_addr))), |
546 | 0 | TSType::IPv6AddrRange => Some(IpAddr::V6(ipv6_from_slice(self.end_addr))), |
547 | 0 | _ => None, |
548 | | } |
549 | 0 | } Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_end_addr Unexecuted instantiation: <ipsec_parser::ikev2::TrafficSelector>::get_end_addr |
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)] |
561 | | pub 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)] |
575 | | pub 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)] |
583 | | pub 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)] |
608 | | pub 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)] |
619 | | pub struct IkeV2Payload<'a> { |
620 | | pub hdr: IkeV2PayloadHeader, |
621 | | pub content: IkeV2PayloadContent<'a>, |
622 | | } |