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
, void,
138 private_transform_attribute_t
*this, encoding_rule_t
**rules
,
142 *rule_count
= countof(encodings
);
145 METHOD(payload_t
, get_type
, payload_type_t
,
146 private_transform_attribute_t
*this)
151 METHOD(payload_t
, get_next_type
, payload_type_t
,
152 private_transform_attribute_t
*this)
157 METHOD(payload_t
, set_next_type
, void,
158 private_transform_attribute_t
*this, payload_type_t type
)
162 METHOD(payload_t
, get_length
, size_t,
163 private_transform_attribute_t
*this)
165 if (this->attribute_format
)
169 return this->attribute_length_or_value
+ 4;
172 METHOD(transform_attribute_t
, set_value_chunk
, void,
173 private_transform_attribute_t
*this, chunk_t value
)
175 chunk_free(&this->attribute_value
);
179 this->attribute_value
= chunk_clone(value
);
180 this->attribute_length_or_value
= value
.len
;
181 this->attribute_format
= FALSE
;
185 memcpy(&this->attribute_length_or_value
, value
.ptr
, value
.len
);
189 METHOD(transform_attribute_t
, set_value
, void,
190 private_transform_attribute_t
*this, u_int16_t value
)
192 chunk_free(&this->attribute_value
);
193 this->attribute_length_or_value
= value
;
194 this->attribute_format
= TRUE
;
197 METHOD(transform_attribute_t
, get_value_chunk
, chunk_t
,
198 private_transform_attribute_t
*this)
200 if (this->attribute_format
)
202 return chunk_from_thing(this->attribute_length_or_value
);
204 return this->attribute_value
;
207 METHOD(transform_attribute_t
, get_value
, u_int16_t
,
208 private_transform_attribute_t
*this)
210 return this->attribute_length_or_value
;
213 METHOD(transform_attribute_t
, set_attribute_type
, void,
214 private_transform_attribute_t
*this, u_int16_t type
)
216 this->attribute_type
= type
& 0x7FFF;
219 METHOD(transform_attribute_t
, get_attribute_type
, u_int16_t
,
220 private_transform_attribute_t
*this)
222 return this->attribute_type
;
225 METHOD(transform_attribute_t
, clone_
, transform_attribute_t
*,
226 private_transform_attribute_t
*this)
228 private_transform_attribute_t
*new;
230 new = (private_transform_attribute_t
*)transform_attribute_create(this->type
);
232 new->attribute_format
= this->attribute_format
;
233 new->attribute_type
= this->attribute_type
;
234 new->attribute_length_or_value
= this->attribute_length_or_value
;
236 if (!new->attribute_format
)
238 new->attribute_value
= chunk_clone(this->attribute_value
);
243 METHOD2(payload_t
, transform_attribute_t
, destroy
, void,
244 private_transform_attribute_t
*this)
246 free(this->attribute_value
.ptr
);
251 * Described in header.
253 transform_attribute_t
*transform_attribute_create(payload_type_t type
)
255 private_transform_attribute_t
*this;
259 .payload_interface
= {
261 .get_encoding_rules
= _get_encoding_rules
,
262 .get_length
= _get_length
,
263 .get_next_type
= _get_next_type
,
264 .set_next_type
= _set_next_type
,
265 .get_type
= _get_type
,
268 .set_value_chunk
= _set_value_chunk
,
269 .set_value
= _set_value
,
270 .get_value_chunk
= _get_value_chunk
,
271 .get_value
= _get_value
,
272 .set_attribute_type
= _set_attribute_type
,
273 .get_attribute_type
= _get_attribute_type
,
277 .attribute_format
= TRUE
,
280 return &this->public;
284 * Described in header.
286 transform_attribute_t
*transform_attribute_create_key_length(u_int16_t key_length
)
288 transform_attribute_t
*attribute
;
290 attribute
= transform_attribute_create(TRANSFORM_ATTRIBUTE
);
291 attribute
->set_attribute_type(attribute
, TATTR_IKEV2_KEY_LENGTH
);
292 attribute
->set_value(attribute
, key_length
);