2 * Copyright (C) 2005-2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
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>.
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
21 #include "transform_attribute.h"
23 #include <encoding/payloads/encodings.h>
26 ENUM(tattr_ph1_names
, TATTR_PH1_ENCRYPTION_ALGORITHM
, TATTR_PH1_GROUP_ORDER
,
27 "ENCRYPTION_ALGORITHM",
45 ENUM(tattr_ph2_names
, TATTR_PH2_SA_LIFE_TYPE
, TATTR_PH2_EXT_SEQ_NUMBER
,
54 "COMP_PRIV_ALGORITHM",
59 ENUM(tattr_ikev2_names
, TATTR_IKEV2_KEY_LENGTH
, TATTR_IKEV2_KEY_LENGTH
,
64 typedef struct private_transform_attribute_t private_transform_attribute_t
;
67 * Private data of an transform_attribute_t object.
69 struct private_transform_attribute_t
{
72 * Public transform_attribute_t interface.
74 transform_attribute_t
public;
77 * Attribute Format Flag.
79 * - TRUE means value is stored in attribute_length_or_value
80 * - FALSE means value is stored in attribute_value
82 bool attribute_format
;
85 * Type of the attribute.
87 u_int16_t attribute_type
;
90 * Attribute Length if attribute_format is 0, attribute Value otherwise.
92 u_int16_t attribute_length_or_value
;
95 * Attribute value as chunk if attribute_format is 0 (FALSE).
97 chunk_t attribute_value
;
100 * Payload type, TRANSFORM_ATTRIBUTE or TRANSFORM_ATTRIBUTE_V1
106 * Encoding rules for IKEv1/IKEv2 transform attributes
108 static encoding_rule_t encodings
[] = {
109 /* Flag defining the format of this payload */
110 { ATTRIBUTE_FORMAT
, offsetof(private_transform_attribute_t
, attribute_format
) },
111 /* type of the attribute as 15 bit unsigned integer */
112 { ATTRIBUTE_TYPE
, offsetof(private_transform_attribute_t
, attribute_type
) },
113 /* Length or value, depending on the attribute format flag */
114 { ATTRIBUTE_LENGTH_OR_VALUE
,offsetof(private_transform_attribute_t
, attribute_length_or_value
) },
115 /* Value of attribute if attribute format flag is zero */
116 { ATTRIBUTE_VALUE
, offsetof(private_transform_attribute_t
, attribute_value
) }
121 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
122 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123 !A! Attribute Type ! AF=0 Attribute Length !
124 !F! ! AF=1 Attribute Value !
125 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126 ! AF=0 Attribute Value !
127 ! AF=1 Not Transmitted !
128 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
131 METHOD(payload_t
, verify
, status_t
,
132 private_transform_attribute_t
*this)
137 METHOD(payload_t
, get_encoding_rules
, int,
138 private_transform_attribute_t
*this, encoding_rule_t
**rules
)
141 return countof(encodings
);
144 METHOD(payload_t
, get_header_length
, int,
145 private_transform_attribute_t
*this)
150 METHOD(payload_t
, get_type
, payload_type_t
,
151 private_transform_attribute_t
*this)
156 METHOD(payload_t
, get_next_type
, payload_type_t
,
157 private_transform_attribute_t
*this)
162 METHOD(payload_t
, set_next_type
, void,
163 private_transform_attribute_t
*this, payload_type_t type
)
167 METHOD(payload_t
, get_length
, size_t,
168 private_transform_attribute_t
*this)
170 if (this->attribute_format
)
174 return this->attribute_length_or_value
+ 4;
177 METHOD(transform_attribute_t
, set_value_chunk
, void,
178 private_transform_attribute_t
*this, chunk_t value
)
180 chunk_free(&this->attribute_value
);
184 this->attribute_value
= chunk_clone(value
);
185 this->attribute_length_or_value
= value
.len
;
186 this->attribute_format
= FALSE
;
190 memcpy(&this->attribute_length_or_value
, value
.ptr
, value
.len
);
194 METHOD(transform_attribute_t
, set_value
, void,
195 private_transform_attribute_t
*this, u_int16_t value
)
197 chunk_free(&this->attribute_value
);
198 this->attribute_length_or_value
= value
;
199 this->attribute_format
= TRUE
;
202 METHOD(transform_attribute_t
, get_value_chunk
, chunk_t
,
203 private_transform_attribute_t
*this)
205 if (this->attribute_format
)
207 return chunk_from_thing(this->attribute_length_or_value
);
209 return this->attribute_value
;
212 METHOD(transform_attribute_t
, get_value
, u_int16_t
,
213 private_transform_attribute_t
*this)
215 return this->attribute_length_or_value
;
218 METHOD(transform_attribute_t
, set_attribute_type
, void,
219 private_transform_attribute_t
*this, u_int16_t type
)
221 this->attribute_type
= type
& 0x7FFF;
224 METHOD(transform_attribute_t
, get_attribute_type
, u_int16_t
,
225 private_transform_attribute_t
*this)
227 return this->attribute_type
;
230 METHOD(transform_attribute_t
, clone_
, transform_attribute_t
*,
231 private_transform_attribute_t
*this)
233 private_transform_attribute_t
*new;
235 new = (private_transform_attribute_t
*)transform_attribute_create(this->type
);
237 new->attribute_format
= this->attribute_format
;
238 new->attribute_type
= this->attribute_type
;
239 new->attribute_length_or_value
= this->attribute_length_or_value
;
241 if (!new->attribute_format
)
243 new->attribute_value
= chunk_clone(this->attribute_value
);
248 METHOD2(payload_t
, transform_attribute_t
, destroy
, void,
249 private_transform_attribute_t
*this)
251 free(this->attribute_value
.ptr
);
256 * Described in header.
258 transform_attribute_t
*transform_attribute_create(payload_type_t type
)
260 private_transform_attribute_t
*this;
264 .payload_interface
= {
266 .get_encoding_rules
= _get_encoding_rules
,
267 .get_header_length
= _get_header_length
,
268 .get_length
= _get_length
,
269 .get_next_type
= _get_next_type
,
270 .set_next_type
= _set_next_type
,
271 .get_type
= _get_type
,
274 .set_value_chunk
= _set_value_chunk
,
275 .set_value
= _set_value
,
276 .get_value_chunk
= _get_value_chunk
,
277 .get_value
= _get_value
,
278 .set_attribute_type
= _set_attribute_type
,
279 .get_attribute_type
= _get_attribute_type
,
283 .attribute_format
= TRUE
,
286 return &this->public;
290 * Described in header.
292 transform_attribute_t
*transform_attribute_create_value(payload_type_t type
,
293 transform_attribute_type_t kind
, u_int64_t value
)
295 transform_attribute_t
*attribute
;
297 attribute
= transform_attribute_create(type
);
298 attribute
->set_attribute_type(attribute
, kind
);
300 if (value
<= UINT16_MAX
)
302 attribute
->set_value(attribute
, value
);
304 else if (value
<= UINT32_MAX
)
308 val32
= htonl(value
);
309 attribute
->set_value_chunk(attribute
, chunk_from_thing(val32
));
313 value
= htobe64(value
);
314 attribute
->set_value_chunk(attribute
, chunk_from_thing(value
));