Coverage Report

Created: 2026-05-16 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/strongswan/src/libcharon/encoding/payloads/ke_payload.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2005-2010 Martin Willi
3
 * Copyright (C) 2005 Jan Hutter
4
 *
5
 * Copyright (C) secunet Security Networks AG
6
 *
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 *
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 */
17
18
#include <stddef.h>
19
20
#include "ke_payload.h"
21
22
#include <encoding/payloads/encodings.h>
23
24
typedef struct private_ke_payload_t private_ke_payload_t;
25
26
/**
27
 * Private data of an ke_payload_t object.
28
 */
29
struct private_ke_payload_t {
30
31
  /**
32
   * Public ke_payload_t interface.
33
   */
34
  ke_payload_t public;
35
36
  /**
37
   * Next payload type.
38
   */
39
  uint8_t  next_payload;
40
41
  /**
42
   * Critical flag.
43
   */
44
  bool critical;
45
46
  /**
47
   * Reserved bits
48
   */
49
  bool reserved_bit[7];
50
51
  /**
52
   * Reserved bytes
53
   */
54
  uint8_t reserved_byte[2];
55
56
  /**
57
   * Length of this payload.
58
   */
59
  uint16_t payload_length;
60
61
  /**
62
   * Key exchange method number.
63
   */
64
  uint16_t ke_method;
65
66
  /**
67
   * Key Exchange Data of this KE payload.
68
   */
69
  chunk_t key_exchange_data;
70
71
  /**
72
   * Payload type, PLV2_KEY_EXCHANGE or PLV1_KEY_EXCHANGE
73
   */
74
  payload_type_t type;
75
};
76
77
/**
78
 * Encoding rules for IKEv2 key exchange payload.
79
 */
80
static encoding_rule_t encodings_v2[] = {
81
  /* 1 Byte next payload type, stored in the field next_payload */
82
  { U_INT_8,        offsetof(private_ke_payload_t, next_payload)  },
83
  /* the critical bit */
84
  { FLAG,         offsetof(private_ke_payload_t, critical)    },
85
  /* 7 Bit reserved bits */
86
  { RESERVED_BIT,     offsetof(private_ke_payload_t, reserved_bit[0]) },
87
  { RESERVED_BIT,     offsetof(private_ke_payload_t, reserved_bit[1]) },
88
  { RESERVED_BIT,     offsetof(private_ke_payload_t, reserved_bit[2]) },
89
  { RESERVED_BIT,     offsetof(private_ke_payload_t, reserved_bit[3]) },
90
  { RESERVED_BIT,     offsetof(private_ke_payload_t, reserved_bit[4]) },
91
  { RESERVED_BIT,     offsetof(private_ke_payload_t, reserved_bit[5]) },
92
  { RESERVED_BIT,     offsetof(private_ke_payload_t, reserved_bit[6]) },
93
  /* Length of the whole payload*/
94
  { PAYLOAD_LENGTH,   offsetof(private_ke_payload_t, payload_length)  },
95
  /* Key exchange method number as 16 bit field*/
96
  { U_INT_16,       offsetof(private_ke_payload_t, ke_method)   },
97
  /* 2 reserved bytes */
98
  { RESERVED_BYTE,    offsetof(private_ke_payload_t, reserved_byte[0])},
99
  { RESERVED_BYTE,    offsetof(private_ke_payload_t, reserved_byte[1])},
100
  /* Key Exchange Data is from variable size */
101
  { CHUNK_DATA,     offsetof(private_ke_payload_t, key_exchange_data)},
102
};
103
104
/*
105
                           1                   2                   3
106
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
107
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
108
      ! Next Payload  !C!  RESERVED   !         Payload Length        !
109
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
110
      !          KE method #          !           RESERVED            !
111
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
112
      !                                                               !
113
      ~                       Key Exchange Data                       ~
114
      !                                                               !
115
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116
*/
117
118
static encoding_rule_t encodings_v1[] = {
119
  /* 1 Byte next payload type, stored in the field next_payload */
120
  { U_INT_8,        offsetof(private_ke_payload_t, next_payload)  },
121
  /* Reserved Byte */
122
  { RESERVED_BYTE,    offsetof(private_ke_payload_t, reserved_byte[0])},
123
  /* Length of the whole payload*/
124
  { PAYLOAD_LENGTH,   offsetof(private_ke_payload_t, payload_length)  },
125
  /* Key Exchange Data is from variable size */
126
  { CHUNK_DATA,     offsetof(private_ke_payload_t, key_exchange_data)},
127
};
128
129
/*
130
                           1                   2                   3
131
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
132
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
133
      ! Next Payload  !    RESERVED   !         Payload Length        !
134
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
135
      !                                                               !
136
      ~                       Key Exchange Data                       ~
137
      !                                                               !
138
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
139
*/
140
141
142
METHOD(payload_t, verify, status_t,
143
  private_ke_payload_t *this)
144
101k
{
145
101k
  return SUCCESS;
146
101k
}
147
148
METHOD(payload_t, get_encoding_rules, int,
149
  private_ke_payload_t *this, encoding_rule_t **rules)
150
101k
{
151
101k
  if (this->type == PLV2_KEY_EXCHANGE)
152
353
  {
153
353
    *rules = encodings_v2;
154
353
    return countof(encodings_v2);
155
353
  }
156
101k
  *rules = encodings_v1;
157
101k
  return countof(encodings_v1);
158
101k
}
159
160
METHOD(payload_t, get_header_length, int,
161
  private_ke_payload_t *this)
162
511k
{
163
511k
  if (this->type == PLV2_KEY_EXCHANGE)
164
5.06k
  {
165
5.06k
    return 8;
166
5.06k
  }
167
506k
  return 4;
168
511k
}
169
170
METHOD(payload_t, get_type, payload_type_t,
171
  private_ke_payload_t *this)
172
128k
{
173
128k
  return this->type;
174
128k
}
175
176
METHOD(payload_t, get_next_type, payload_type_t,
177
  private_ke_payload_t *this)
178
101k
{
179
101k
  return this->next_payload;
180
101k
}
181
182
METHOD(payload_t, set_next_type, void,
183
  private_ke_payload_t *this,payload_type_t type)
184
0
{
185
0
  this->next_payload = type;
186
0
}
187
188
METHOD(payload_t, get_length, size_t,
189
  private_ke_payload_t *this)
190
0
{
191
0
  return this->payload_length;
192
0
}
193
194
METHOD(ke_payload_t, get_key_exchange_data, chunk_t,
195
  private_ke_payload_t *this)
196
0
{
197
0
  return this->key_exchange_data;
198
0
}
199
200
METHOD(ke_payload_t, get_key_exchange_method, key_exchange_method_t,
201
  private_ke_payload_t *this)
202
0
{
203
0
  return this->ke_method;
204
0
}
205
206
METHOD2(payload_t, ke_payload_t, destroy, void,
207
  private_ke_payload_t *this)
208
101k
{
209
101k
  free(this->key_exchange_data.ptr);
210
101k
  free(this);
211
101k
}
212
213
/*
214
 * Described in header
215
 */
216
ke_payload_t *ke_payload_create(payload_type_t type)
217
101k
{
218
101k
  private_ke_payload_t *this;
219
220
101k
  INIT(this,
221
101k
    .public = {
222
101k
      .payload_interface = {
223
101k
        .verify = _verify,
224
101k
        .get_encoding_rules = _get_encoding_rules,
225
101k
        .get_header_length = _get_header_length,
226
101k
        .get_length = _get_length,
227
101k
        .get_next_type = _get_next_type,
228
101k
        .set_next_type = _set_next_type,
229
101k
        .get_type = _get_type,
230
101k
        .destroy = _destroy,
231
101k
      },
232
101k
      .get_key_exchange_data = _get_key_exchange_data,
233
101k
      .get_key_exchange_method = _get_key_exchange_method,
234
101k
      .destroy = _destroy,
235
101k
    },
236
101k
    .next_payload = PL_NONE,
237
101k
    .ke_method = KE_NONE,
238
101k
    .type = type,
239
101k
  );
240
101k
  this->payload_length = get_header_length(this);
241
101k
  return &this->public;
242
101k
}
243
244
/*
245
 * Described in header
246
 */
247
ke_payload_t *ke_payload_create_from_key_exchange(payload_type_t type,
248
                          key_exchange_t *ke)
249
0
{
250
0
  private_ke_payload_t *this;
251
0
  chunk_t value;
252
253
0
  if (!ke->get_public_key(ke, &value))
254
0
  {
255
0
    return NULL;
256
0
  }
257
0
  this = (private_ke_payload_t*)ke_payload_create(type);
258
0
  this->key_exchange_data = value;
259
0
  this->ke_method = ke->get_method(ke);
260
0
  this->payload_length += this->key_exchange_data.len;
261
262
0
  return &this->public;
263
0
}