Repository: secdev/scapy

Issue:
Incorrect length calculations in IKEv2 support
### Brief description

The length calculations for `IKEv2_payload_CERT_CRT` and `IKEv2_payload_CERT_CRL` are currently incorrect.

The length fields are currently defined as follows:

```python
        FieldLenField("length", None, "x509Cert", "H", adjust=lambda pkt, x: x + len(pkt.x509Cert) + 5),  # noqa: E501
```

Because of how `adjust` works, this calculation therefore considers the length of `x509Cert` twice: once as the parameter `x` and once in `len(pkg.x509Cert)`.

### Scapy version

2.4.5

### Python version

3.9

### Operating system

Linux

### Additional environment information

_No response_

### How to reproduce

```python3
from scapy.contrib.ikev2 import *
cert = IKEv2_payload_CERT_CRT()
# Compare the length of the embedded cert...
print(len(cert.x509Cert))
# With the computed length of the packet
cert.show2()

# You'll notice that the computed length is equal to 2 * len(cert.x509Cert) + 5.
# It should be equal to len(cert.x509Cert) + 5
```


### Actual result

_No response_

### Expected result

_No response_

### Related resources

_No response_


Discussion:

Resolving patch:
diff --git a/scapy/contrib/ikev2.py b/scapy/contrib/ikev2.py
--- a/scapy/contrib/ikev2.py
+++ b/scapy/contrib/ikev2.py
@@ -750,7 +750,7 @@ class IKEv2_payload_CERT_CRT(IKEv2_payload_CERT):
     fields_desc = [
         ByteEnumField("next_payload", None, IKEv2_payload_type),
         ByteField("res", 0),
-        FieldLenField("length", None, "x509Cert", "H", adjust=lambda pkt, x: x + len(pkt.x509Cert) + 5),  # noqa: E501
+        FieldLenField("length", None, "x509Cert", "H", adjust=lambda pkt, x: x + 5),  # noqa: E501
         ByteEnumField("cert_type", 4, IKEv2CertificateEncodings),
         PacketLenField("x509Cert", X509_Cert(''), X509_Cert, length_from=lambda x:x.length - 5),  # noqa: E501
     ]
@@ -761,7 +761,7 @@ class IKEv2_payload_CERT_CRL(IKEv2_payload_CERT):
     fields_desc = [
         ByteEnumField("next_payload", None, IKEv2_payload_type),
         ByteField("res", 0),
-        FieldLenField("length", None, "x509CRL", "H", adjust=lambda pkt, x: x + len(pkt.x509CRL) + 5),  # noqa: E501
+        FieldLenField("length", None, "x509CRL", "H", adjust=lambda pkt, x: x + 5),  # noqa: E501
         ByteEnumField("cert_type", 7, IKEv2CertificateEncodings),
         PacketLenField("x509CRL", X509_CRL(''), X509_CRL, length_from=lambda x:x.length - 5),  # noqa: E501
     ]


Test patch:
diff --git a/test/contrib/ikev2.uts b/test/contrib/ikev2.uts
--- a/test/contrib/ikev2.uts
+++ b/test/contrib/ikev2.uts
@@ -92,6 +92,19 @@ assert isinstance(a, IKEv2_payload_CERT_CRL)
 assert isinstance(b, IKEv2_payload_CERT_STR)
 assert isinstance(c, IKEv2_payload_CERT_CRT)
 
+= Test Certs length calculations
+## For the length calculations see Figure 12 in RFC 7296
+a = IKEv2_payload_CERT_CRT(raw(IKEv2_payload_CERT_CRT()))
+assert len(a.x509Cert) > 0
+assert a.length == len(a.x509Cert) + 5
+
+b = IKEv2_payload_CERT_CRL(raw(IKEv2_payload_CERT_CRL()))
+assert len(b.x509CRL) > 0
+assert b.length == len(b.x509CRL) + 5
+
+c = IKEv2_payload_CERT_STR(raw(IKEv2_payload_CERT_STR(cert_data=b'dummy')))
+assert c.length == len(c.cert_data) + 5
+
 = Test TrafficSelector detection
 
 a = TrafficSelector(raw(IPv4TrafficSelector()))