ikev2: Add encrypted fragment payload
[strongswan.git] / src / libcharon / encoding / payloads / payload.c
1 /*
2 * Copyright (C) 2007 Tobias Brunner
3 * Copyright (C) 2005-2006 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
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
19 #include "payload.h"
20
21 #include <encoding/payloads/ike_header.h>
22 #include <encoding/payloads/sa_payload.h>
23
24 #include <encoding/payloads/nonce_payload.h>
25 #include <encoding/payloads/id_payload.h>
26 #include <encoding/payloads/ke_payload.h>
27 #include <encoding/payloads/notify_payload.h>
28 #include <encoding/payloads/auth_payload.h>
29 #include <encoding/payloads/cert_payload.h>
30 #include <encoding/payloads/certreq_payload.h>
31 #include <encoding/payloads/encrypted_payload.h>
32 #include <encoding/payloads/encrypted_fragment_payload.h>
33 #include <encoding/payloads/ts_payload.h>
34 #include <encoding/payloads/delete_payload.h>
35 #include <encoding/payloads/vendor_id_payload.h>
36 #include <encoding/payloads/cp_payload.h>
37 #include <encoding/payloads/configuration_attribute.h>
38 #include <encoding/payloads/eap_payload.h>
39 #include <encoding/payloads/hash_payload.h>
40 #include <encoding/payloads/fragment_payload.h>
41 #include <encoding/payloads/unknown_payload.h>
42
43 ENUM_BEGIN(payload_type_names, PL_NONE, PL_NONE,
44 "PL_NONE");
45 ENUM_NEXT(payload_type_names, PLV1_SECURITY_ASSOCIATION, PLV1_CONFIGURATION, PL_NONE,
46 "SECURITY_ASSOCIATION_V1",
47 "PROPOSAL_V1",
48 "TRANSFORM_V1",
49 "KEY_EXCHANGE_V1",
50 "ID_V1",
51 "CERTIFICATE_V1",
52 "CERTREQ_V1",
53 "HASH_V1",
54 "SIGNATURE_V1",
55 "NONCE_V1",
56 "NOTIFY_V1",
57 "DELETE_V1",
58 "VENDOR_ID_V1",
59 "CONFIGURATION_V1");
60 ENUM_NEXT(payload_type_names, PLV1_NAT_D, PLV1_NAT_OA, PLV1_CONFIGURATION,
61 "NAT_D_V1",
62 "NAT_OA_V1");
63 ENUM_NEXT(payload_type_names, PLV2_SECURITY_ASSOCIATION, PLV2_FRAGMENT, PLV1_NAT_OA,
64 "SECURITY_ASSOCIATION",
65 "KEY_EXCHANGE",
66 "ID_INITIATOR",
67 "ID_RESPONDER",
68 "CERTIFICATE",
69 "CERTREQ",
70 "AUTH",
71 "NONCE",
72 "NOTIFY",
73 "DELETE",
74 "VENDOR_ID",
75 "TS_INITIATOR",
76 "TS_RESPONDER",
77 "ENCRYPTED",
78 "CONFIGURATION",
79 "EAP",
80 "GSPM",
81 "GROUP_ID",
82 "GROUP_SECURITY_ASSOCIATION",
83 "KEY_DOWNLOAD",
84 "ENCRYPTED_FRAGMENT");
85 #ifdef ME
86 ENUM_NEXT(payload_type_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_FRAGMENT,
87 "ID_PEER");
88 ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_ID_PEER,
89 "NAT_D_DRAFT_V1",
90 "NAT_OA_DRAFT_V1",
91 "FRAGMENT");
92 #else
93 ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_FRAGMENT,
94 "NAT_D_DRAFT_V1",
95 "NAT_OA_DRAFT_V1",
96 "FRAGMENT");
97 #endif /* ME */
98 ENUM_NEXT(payload_type_names, PL_HEADER, PLV1_ENCRYPTED, PLV1_FRAGMENT,
99 "HEADER",
100 "PROPOSAL_SUBSTRUCTURE",
101 "PROPOSAL_SUBSTRUCTURE_V1",
102 "TRANSFORM_SUBSTRUCTURE",
103 "TRANSFORM_SUBSTRUCTURE_V1",
104 "TRANSFORM_ATTRIBUTE",
105 "TRANSFORM_ATTRIBUTE_V1",
106 "TRAFFIC_SELECTOR_SUBSTRUCTURE",
107 "CONFIGURATION_ATTRIBUTE",
108 "CONFIGURATION_ATTRIBUTE_V1",
109 "ENCRYPTED_V1");
110 ENUM_END(payload_type_names, PLV1_ENCRYPTED);
111
112 /* short forms of payload names */
113 ENUM_BEGIN(payload_type_short_names, PL_NONE, PL_NONE,
114 "--");
115 ENUM_NEXT(payload_type_short_names, PLV1_SECURITY_ASSOCIATION, PLV1_CONFIGURATION, PL_NONE,
116 "SA",
117 "PROP",
118 "TRANS",
119 "KE",
120 "ID",
121 "CERT",
122 "CERTREQ",
123 "HASH",
124 "SIG",
125 "No",
126 "N",
127 "D",
128 "V",
129 "CP");
130 ENUM_NEXT(payload_type_short_names, PLV1_NAT_D, PLV1_NAT_OA, PLV1_CONFIGURATION,
131 "NAT-D",
132 "NAT-OA");
133 ENUM_NEXT(payload_type_short_names, PLV2_SECURITY_ASSOCIATION, PLV2_FRAGMENT, PLV1_NAT_OA,
134 "SA",
135 "KE",
136 "IDi",
137 "IDr",
138 "CERT",
139 "CERTREQ",
140 "AUTH",
141 "No",
142 "N",
143 "D",
144 "V",
145 "TSi",
146 "TSr",
147 "E",
148 "CP",
149 "EAP",
150 "GSPM",
151 "IDg",
152 "GSA",
153 "KD",
154 "EF");
155 #ifdef ME
156 ENUM_NEXT(payload_type_short_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_FRAGMENT,
157 "IDp");
158 ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_ID_PEER,
159 "NAT-D",
160 "NAT-OA",
161 "FRAG");
162 #else
163 ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_FRAGMENT,
164 "NAT-D",
165 "NAT-OA",
166 "FRAG");
167 #endif /* ME */
168 ENUM_NEXT(payload_type_short_names, PL_HEADER, PLV1_ENCRYPTED, PLV1_FRAGMENT,
169 "HDR",
170 "PROP",
171 "PROP",
172 "TRANS",
173 "TRANS",
174 "TRANSATTR",
175 "TRANSATTR",
176 "TSSUB",
177 "CATTR",
178 "CATTR",
179 "E");
180 ENUM_END(payload_type_short_names, PLV1_ENCRYPTED);
181
182 /*
183 * see header
184 */
185 payload_t *payload_create(payload_type_t type)
186 {
187 switch (type)
188 {
189 case PL_HEADER:
190 return (payload_t*)ike_header_create();
191 case PLV2_SECURITY_ASSOCIATION:
192 case PLV1_SECURITY_ASSOCIATION:
193 return (payload_t*)sa_payload_create(type);
194 case PLV2_PROPOSAL_SUBSTRUCTURE:
195 case PLV1_PROPOSAL_SUBSTRUCTURE:
196 return (payload_t*)proposal_substructure_create(type);
197 case PLV2_TRANSFORM_SUBSTRUCTURE:
198 case PLV1_TRANSFORM_SUBSTRUCTURE:
199 return (payload_t*)transform_substructure_create(type);
200 case PLV2_TRANSFORM_ATTRIBUTE:
201 case PLV1_TRANSFORM_ATTRIBUTE:
202 return (payload_t*)transform_attribute_create(type);
203 case PLV2_NONCE:
204 case PLV1_NONCE:
205 return (payload_t*)nonce_payload_create(type);
206 case PLV2_ID_INITIATOR:
207 case PLV2_ID_RESPONDER:
208 case PLV1_ID:
209 case PLV1_NAT_OA:
210 case PLV1_NAT_OA_DRAFT_00_03:
211 #ifdef ME
212 case PLV2_ID_PEER:
213 #endif /* ME */
214 return (payload_t*)id_payload_create(type);
215 case PLV2_AUTH:
216 return (payload_t*)auth_payload_create();
217 case PLV2_CERTIFICATE:
218 case PLV1_CERTIFICATE:
219 return (payload_t*)cert_payload_create(type);
220 case PLV2_CERTREQ:
221 case PLV1_CERTREQ:
222 return (payload_t*)certreq_payload_create(type);
223 case PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE:
224 return (payload_t*)traffic_selector_substructure_create();
225 case PLV2_TS_INITIATOR:
226 return (payload_t*)ts_payload_create(TRUE);
227 case PLV2_TS_RESPONDER:
228 return (payload_t*)ts_payload_create(FALSE);
229 case PLV2_KEY_EXCHANGE:
230 case PLV1_KEY_EXCHANGE:
231 return (payload_t*)ke_payload_create(type);
232 case PLV2_NOTIFY:
233 case PLV1_NOTIFY:
234 return (payload_t*)notify_payload_create(type);
235 case PLV2_DELETE:
236 case PLV1_DELETE:
237 return (payload_t*)delete_payload_create(type, 0);
238 case PLV2_VENDOR_ID:
239 case PLV1_VENDOR_ID:
240 return (payload_t*)vendor_id_payload_create(type);
241 case PLV1_HASH:
242 case PLV1_SIGNATURE:
243 case PLV1_NAT_D:
244 case PLV1_NAT_D_DRAFT_00_03:
245 return (payload_t*)hash_payload_create(type);
246 case PLV2_CONFIGURATION:
247 case PLV1_CONFIGURATION:
248 return (payload_t*)cp_payload_create(type);
249 case PLV2_CONFIGURATION_ATTRIBUTE:
250 case PLV1_CONFIGURATION_ATTRIBUTE:
251 return (payload_t*)configuration_attribute_create(type);
252 case PLV2_EAP:
253 return (payload_t*)eap_payload_create();
254 case PLV2_ENCRYPTED:
255 case PLV1_ENCRYPTED:
256 return (payload_t*)encrypted_payload_create(type);
257 case PLV1_FRAGMENT:
258 return (payload_t*)fragment_payload_create();
259 case PLV2_FRAGMENT:
260 return (payload_t*)encrypted_fragment_payload_create();
261 default:
262 return (payload_t*)unknown_payload_create(type);
263 }
264 }
265
266 /**
267 * See header.
268 */
269 bool payload_is_known(payload_type_t type)
270 {
271 if (type == PL_HEADER)
272 {
273 return TRUE;
274 }
275 if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION)
276 {
277 return TRUE;
278 }
279 if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA)
280 {
281 return TRUE;
282 }
283 if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP)
284 {
285 return TRUE;
286 }
287 if (type == PLV2_FRAGMENT)
288 {
289 return TRUE;
290 }
291 #ifdef ME
292 if (type == PLV2_ID_PEER)
293 {
294 return TRUE;
295 }
296 #endif
297 if (type >= PLV1_NAT_D_DRAFT_00_03 && type <= PLV1_FRAGMENT)
298 {
299 return TRUE;
300 }
301 return FALSE;
302 }
303
304 /**
305 * See header.
306 */
307 void* payload_get_field(payload_t *payload, encoding_type_t type, u_int skip)
308 {
309 encoding_rule_t *rule;
310 int i, count;
311
312 count = payload->get_encoding_rules(payload, &rule);
313 for (i = 0; i < count; i++)
314 {
315 if (rule[i].type == type && skip-- == 0)
316 {
317 return ((char*)payload) + rule[i].offset;
318 }
319 }
320 return NULL;
321 }