2 * @file transform_substructure.h
4 * @brief Declaration of the class transform_substructure_t.
6 * An object of this type represents an IKEv2 TRANSFORM Substructure and contains Attributes.
11 * Copyright (C) 2005 Jan Hutter, Martin Willi
12 * Hochschule fuer Technik Rapperswil
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28 #include "transform_substructure.h"
30 #include "transform_attribute.h"
31 #include "encodings.h"
33 #include "../utils/allocator.h"
34 #include "../utils/linked_list.h"
37 * Private data of an transform_substructure_t' Object
40 typedef struct private_transform_substructure_s private_transform_substructure_t
;
42 struct private_transform_substructure_s
{
44 * public transform_substructure_t interface
46 transform_substructure_t
public;
51 u_int8_t next_payload
;
55 * Length of this payload
57 u_int16_t transform_length
;
61 * Type of the transform
63 u_int8_t transform_type
;
68 u_int16_t transform_id
;
71 * Transforms Attributes are stored in a linked_list_t
73 linked_list_t
*attributes
;
76 * @brief Computes the length of this substructure.
78 * @param this calling private_transform_substructure_t object
82 status_t (*compute_length
) (private_transform_substructure_t
*this);
87 * string mappings for transform_type_t
89 mapping_t transform_type_m
[] = {
90 {UNDEFINED_TRANSFORM_TYPE
, "UNDEFINED_TRANSFORM_TYPE"},
91 {ENCRYPTION_ALGORITHM
, "ENCRYPTION_ALGORITHM"},
92 {PSEUDO_RANDOM_FUNCTION
, "PSEUDO_RANDOM_FUNCTION"},
93 {INTEGRITIY_ALGORITHM
, "INTEGRITIY_ALGORITHM"},
94 {DIFFIE_HELLMAN_GROUP
, "DIFFIE_HELLMAN_GROUP"},
95 {EXTENDED_SEQUENCE_NUNBERS
, "EXTENDED_SEQUENCE_NUNBERS"},
101 * string mappings for encryption_algorithm_t
103 mapping_t encryption_algorithm_m
[] = {
104 {ENCR_UNDEFINED
, "ENCR_UNDEFINED"},
105 {ENCR_DES_IV64
, "ENCR_DES_IV64"},
106 {ENCR_DES
, "ENCR_DES"},
107 {ENCR_3DES
, "ENCR_3DES"},
108 {ENCR_RC5
, "ENCR_RC5"},
109 {ENCR_IDEA
, "ENCR_IDEA"},
110 {ENCR_CAST
, "ENCR_CAST"},
111 {ENCR_BLOWFISH
, "ENCR_BLOWFISH"},
112 {ENCR_3IDEA
, "ENCR_3IDEA"},
113 {ENCR_DES_IV32
, "ENCR_DES_IV32"},
114 {ENCR_NULL
, "ENCR_NULL"},
115 {ENCR_AES_CBC
, "ENCR_AES_CBC"},
116 {ENCR_AES_CTR
, "ENCR_AES_CTR"},
121 * string mappings for encryption_algorithm_t
123 mapping_t pseudo_random_function_m
[] = {
124 {PRF_UNDEFINED
, "PRF_UNDEFINED"},
125 {PRF_HMAC_MD5
, "PRF_HMAC_SHA1"},
126 {PRF_HMAC_SHA1
, "PRF_HMAC_SHA1"},
127 {PRF_HMAC_TIGER
, "PRF_HMAC_TIGER"},
128 {PRF_AES128_CBC
, "PRF_AES128_CBC"},
133 * string mappings for integrity_algorithm_t
135 mapping_t integrity_algorithm_m
[] = {
136 {AUTH_UNDEFINED
, "AUTH_UNDEFINED"},
137 {AUTH_HMAC_MD5_96
, "AUTH_HMAC_MD5_96"},
138 {AUTH_HMAC_SHA1_96
, "AUTH_HMAC_SHA1_96"},
139 {AUTH_DES_MAC
, "AUTH_DES_MAC"},
140 {AUTH_KPDK_MD5
, "AUTH_KPDK_MD5"},
141 {AUTH_AES_XCBC_96
, "AUTH_AES_XCBC_96"},
146 * string mappings for diffie_hellman_group_t
148 mapping_t diffie_hellman_group_m
[] = {
149 {MODP_UNDEFINED
, "MODP_UNDEFINED"},
150 {MODP_768_BIT
, "MODP_768_BIT"},
151 {MODP_1024_BIT
, "MODP_1024_BIT"},
152 {MODP_1536_BIT
, "MODP_1536_BIT"},
153 {MODP_2048_BIT
, "MODP_2048_BIT"},
154 {MODP_3072_BIT
, "MODP_3072_BIT"},
155 {MODP_4096_BIT
, "MODP_4096_BIT"},
156 {MODP_6144_BIT
, "MODP_6144_BIT"},
157 {MODP_8192_BIT
, "MODP_8192_BIT"},
162 * string mappings for extended_sequence_numbers_t
164 mapping_t extended_sequence_numbers_m
[] = {
165 {NO_EXT_SEQ_NUMBERS
, "NO_EXT_SEQ_NUMBERS"},
166 {EXT_SEQ_NUMBERS
, "EXT_SEQ_NUMBERS"},
171 * Encoding rules to parse or generate a Transform substructure
173 * The defined offsets are the positions in a object of type
174 * private_transform_substructure_t.
177 encoding_rule_t transform_substructure_encodings
[] = {
178 /* 1 Byte next payload type, stored in the field next_payload */
179 { U_INT_8
, offsetof(private_transform_substructure_t
, next_payload
) },
180 /* Reserved Byte is skipped */
181 { RESERVED_BYTE
, 0 },
182 /* Length of the whole transform substructure*/
183 { PAYLOAD_LENGTH
, offsetof(private_transform_substructure_t
, transform_length
) },
184 /* transform type is a number of 8 bit */
185 { U_INT_8
, offsetof(private_transform_substructure_t
, transform_type
) },
186 /* Reserved Byte is skipped */
187 { RESERVED_BYTE
, 0 },
188 /* tranform ID is a number of 8 bit */
189 { U_INT_16
, offsetof(private_transform_substructure_t
, transform_id
) },
190 /* Attributes are stored in a transform attribute,
191 offset points to a linked_list_t pointer */
192 { TRANSFORM_ATTRIBUTES
, offsetof(private_transform_substructure_t
, attributes
) }
196 * Implements payload_t's and transform_substructure_t's destroy function.
197 * See #payload_s.destroy or transform_substructure_s.destroy for description.
199 static status_t
destroy(private_transform_substructure_t
*this)
201 /* all proposals are getting destroyed */
202 while (this->attributes
->get_count(this->attributes
) > 0)
204 transform_attribute_t
*current_attribute
;
205 if (this->attributes
->remove_last(this->attributes
,(void **)¤t_attribute
) != SUCCESS
)
209 current_attribute
->destroy(current_attribute
);
211 this->attributes
->destroy(this->attributes
);
213 allocator_free(this);
219 * Implements payload_t's get_encoding_rules function.
220 * See #payload_s.get_encoding_rules for description.
222 static status_t
get_encoding_rules(private_transform_substructure_t
*this, encoding_rule_t
**rules
, size_t *rule_count
)
224 *rules
= transform_substructure_encodings
;
225 *rule_count
= sizeof(transform_substructure_encodings
) / sizeof(encoding_rule_t
);
231 * Implements payload_t's get_type function.
232 * See #payload_s.get_type for description.
234 static payload_type_t
get_type(private_transform_substructure_t
*this)
236 return TRANSFORM_SUBSTRUCTURE
;
240 * Implements payload_t's get_next_type function.
241 * See #payload_s.get_next_type for description.
243 static payload_type_t
get_next_type(private_transform_substructure_t
*this)
245 return (this->next_payload
);
249 * Implements payload_t's get_length function.
250 * See #payload_s.get_length for description.
252 static size_t get_length(private_transform_substructure_t
*this)
254 this->compute_length(this);
256 return this->transform_length
;
260 * Implements transform_substructure_t's create_transform_attribute_iterator function.
261 * See #transform_substructure_s.create_transform_attribute_iterator for description.
263 static status_t
create_transform_attribute_iterator (private_transform_substructure_t
*this,linked_list_iterator_t
**iterator
,bool forward
)
265 return (this->attributes
->create_iterator(this->attributes
,iterator
,forward
));
269 * Implements transform_substructure_t's add_transform_attribute function.
270 * See #transform_substructure_s.add_transform_attribute for description.
272 static status_t
add_transform_attribute (private_transform_substructure_t
*this,transform_attribute_t
*attribute
)
275 status
= this->attributes
->insert_last(this->attributes
,(void *) attribute
);
276 this->compute_length(this);
281 * Implements transform_substructure_t's set_is_last_transform function.
282 * See #transform_substructure_s.set_is_last_transform for description.
284 static status_t
set_is_last_transform (private_transform_substructure_t
*this, bool is_last
)
286 this->next_payload
= (is_last
) ?
0: TRANSFORM_TYPE_VALUE
;
291 * Implements transform_substructure_t's get_is_last_transform function.
292 * See #transform_substructure_s.get_is_last_transform for description.
294 static bool get_is_last_transform (private_transform_substructure_t
*this)
296 return ((this->next_payload
== TRANSFORM_TYPE_VALUE
) ? FALSE
: TRUE
);
300 * Implements payload_t's set_next_type function.
301 * See #payload_s.set_next_type for description.
303 static status_t
set_next_type(private_transform_substructure_t
*this,payload_type_t type
)
309 * Implements transform_substructure_t's set_transform_type function.
310 * See #transform_substructure_s.set_transform_type for description.
312 static status_t
set_transform_type (private_transform_substructure_t
*this,u_int8_t type
)
314 this->transform_type
= type
;
319 * Implements transform_substructure_t's get_transform_type function.
320 * See #transform_substructure_s.get_transform_type for description.
322 static u_int8_t
get_transform_type (private_transform_substructure_t
*this)
324 return this->transform_type
;
328 * Implements transform_substructure_t's set_transform_id function.
329 * See #transform_substructure_s.set_transform_id for description.
331 static status_t
set_transform_id (private_transform_substructure_t
*this,u_int16_t id
)
333 this->transform_id
= id
;
338 * Implements transform_substructure_t's get_transform_id function.
339 * See #transform_substructure_s.get_transform_id for description.
341 static u_int16_t
get_transform_id (private_transform_substructure_t
*this)
343 return this->transform_id
;
347 * Implements private_transform_substructure_t's compute_length function.
348 * See #private_transform_substructure_s.compute_length for description.
350 static status_t
compute_length (private_transform_substructure_t
*this)
352 linked_list_iterator_t
*iterator
;
354 size_t length
= TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH
;
355 status
= this->attributes
->create_iterator(this->attributes
,&iterator
,TRUE
);
356 if (status
!= SUCCESS
)
360 while (iterator
->has_next(iterator
))
362 payload_t
* current_attribute
;
363 iterator
->current(iterator
,(void **) ¤t_attribute
);
364 length
+= current_attribute
->get_length(current_attribute
);
366 iterator
->destroy(iterator
);
368 this->transform_length
= length
;
374 * Described in header
376 transform_substructure_t
*transform_substructure_create()
378 private_transform_substructure_t
*this = allocator_alloc_thing(private_transform_substructure_t
);
384 this->public.payload_interface
.get_encoding_rules
= (status_t (*) (payload_t
*, encoding_rule_t
**, size_t *) ) get_encoding_rules
;
385 this->public.payload_interface
.get_length
= (size_t (*) (payload_t
*)) get_length
;
386 this->public.payload_interface
.get_next_type
= (payload_type_t (*) (payload_t
*)) get_next_type
;
387 this->public.payload_interface
.set_next_type
= (status_t (*) (payload_t
*,payload_type_t
)) set_next_type
;
388 this->public.payload_interface
.get_type
= (payload_type_t (*) (payload_t
*)) get_type
;
389 this->public.payload_interface
.destroy
= (status_t (*) (payload_t
*))destroy
;
390 this->public.create_transform_attribute_iterator
= (status_t (*) (transform_substructure_t
*,linked_list_iterator_t
**,bool)) create_transform_attribute_iterator
;
391 this->public.add_transform_attribute
= (status_t (*) (transform_substructure_t
*,transform_attribute_t
*)) add_transform_attribute
;
392 this->public.set_is_last_transform
= (status_t (*) (transform_substructure_t
*,bool)) set_is_last_transform
;
393 this->public.get_is_last_transform
= (bool (*) (transform_substructure_t
*)) get_is_last_transform
;
394 this->public.set_transform_type
= (status_t (*) (transform_substructure_t
*,u_int8_t
)) set_transform_type
;
395 this->public.get_transform_type
= (u_int8_t (*) (transform_substructure_t
*)) get_transform_type
;
396 this->public.set_transform_id
= (status_t (*) (transform_substructure_t
*,u_int16_t
)) set_transform_id
;
397 this->public.get_transform_id
= (u_int16_t (*) (transform_substructure_t
*)) get_transform_id
;
398 this->public.destroy
= (status_t (*) (transform_substructure_t
*)) destroy
;
400 /* private functions */
401 this->compute_length
= compute_length
;
403 /* set default values of the fields */
404 this->next_payload
= NO_PAYLOAD
;
405 this->transform_length
= TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH
;
406 this->transform_id
= 0;
407 this->transform_type
= 0;
409 this->attributes
= linked_list_create();
411 if (this->attributes
== NULL
)
413 allocator_free(this);
416 return (&(this->public));