Verify IKEv1 nonce size, send 32 byte nonces
[strongswan.git] / src / libcharon / encoding / payloads / nonce_payload.c
index 684bddc..3c5eeb5 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "nonce_payload.h"
 
+#include <daemon.h>
 #include <encoding/payloads/encodings.h>
 
 typedef struct private_nonce_payload_t private_nonce_payload_t;
@@ -70,7 +71,7 @@ struct private_nonce_payload_t {
  * The defined offsets are the positions in a object of type
  * private_nonce_payload_t.
  */
-encoding_rule_t nonce_payload_encodings[] = {
+static encoding_rule_t encodings[] = {
        /* 1 Byte next payload type, stored in the field next_payload */
        { U_INT_8,                      offsetof(private_nonce_payload_t, next_payload)         },
        /* the critical bit */
@@ -86,7 +87,7 @@ encoding_rule_t nonce_payload_encodings[] = {
        /* Length of the whole nonce payload*/
        { PAYLOAD_LENGTH,       offsetof(private_nonce_payload_t, payload_length)       },
        /* some nonce bytes, lenth is defined in PAYLOAD_LENGTH */
-       { NONCE_DATA,           offsetof(private_nonce_payload_t, nonce)                        },
+       { CHUNK_DATA,           offsetof(private_nonce_payload_t, nonce)                        },
 };
 
 /*                           1                   2                   3
@@ -103,18 +104,42 @@ encoding_rule_t nonce_payload_encodings[] = {
 METHOD(payload_t, verify, status_t,
        private_nonce_payload_t *this)
 {
-       if (this->nonce.len < 16 || this->nonce.len > 256)
+       bool bad_length = FALSE;
+
+       if (this->nonce.len > 256)
+       {
+               bad_length = TRUE;
+       }
+       if (this->type == NONCE &&
+               this->nonce.len < 16)
        {
+               bad_length = TRUE;
+       }
+       if (this->type == NONCE_V1 &&
+               this->nonce.len < 8)
+       {
+               bad_length = TRUE;
+       }
+       if (bad_length)
+       {
+               DBG1(DBG_ENC, "%N payload has invalid length (%d bytes)",
+                        payload_type_names, this->type, this->nonce.len);
                return FAILED;
        }
        return SUCCESS;
 }
 
-METHOD(payload_t, get_encoding_rules, void,
-       private_nonce_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
+METHOD(payload_t, get_encoding_rules, int,
+       private_nonce_payload_t *this, encoding_rule_t **rules)
+{
+       *rules = encodings;
+       return countof(encodings);
+}
+
+METHOD(payload_t, get_header_length, int,
+       private_nonce_payload_t *this)
 {
-       *rules = nonce_payload_encodings;
-       *rule_count = countof(nonce_payload_encodings);
+       return 4;
 }
 
 METHOD(payload_t, get_type, payload_type_t,
@@ -145,7 +170,7 @@ METHOD(nonce_payload_t, set_nonce, void,
         private_nonce_payload_t *this, chunk_t nonce)
 {
        this->nonce = chunk_clone(nonce);
-       this->payload_length = NONCE_PAYLOAD_HEADER_LENGTH + nonce.len;
+       this->payload_length = get_header_length(this) + nonce.len;
 }
 
 METHOD(nonce_payload_t, get_nonce, chunk_t,
@@ -173,6 +198,7 @@ nonce_payload_t *nonce_payload_create(payload_type_t type)
                        .payload_interface = {
                                .verify = _verify,
                                .get_encoding_rules = _get_encoding_rules,
+                               .get_header_length = _get_header_length,
                                .get_length = _get_length,
                                .get_next_type = _get_next_type,
                                .set_next_type = _set_next_type,
@@ -184,7 +210,7 @@ nonce_payload_t *nonce_payload_create(payload_type_t type)
                        .destroy = _destroy,
                },
                .next_payload = NO_PAYLOAD,
-               .payload_length = NONCE_PAYLOAD_HEADER_LENGTH,
+               .payload_length = get_header_length(this),
                .type = type,
        );
        return &this->public;