2 * Copyright (C) 2005-2010 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 #include "proposal_substructure.h"
21 #include <encoding/payloads/encodings.h>
22 #include <encoding/payloads/transform_substructure.h>
24 #include <utils/linked_list.h>
28 * IKEv2 Value for a proposal payload.
30 #define PROPOSAL_TYPE_VALUE 2
32 typedef struct private_proposal_substructure_t private_proposal_substructure_t
;
35 * Private data of an proposal_substructure_t object.
37 struct private_proposal_substructure_t
{
40 * Public proposal_substructure_t interface.
42 proposal_substructure_t
public;
47 u_int8_t next_payload
;
55 * Length of this payload.
57 u_int16_t proposal_length
;
62 u_int8_t proposal_number
;
70 * SPI size of the following SPI.
75 * Number of transforms.
77 u_int8_t transforms_count
;
80 * SPI is stored as chunk.
85 * Transforms are stored in a linked_list_t.
87 linked_list_t
*transforms
;
90 * Type of this payload, PROPOSAL_SUBSTRUCTURE or PROPOSAL_SUBSTRUCTURE_V1
96 * Encoding rules for a IKEv1 Proposal substructure.
98 static encoding_rule_t encodings_v1
[] = {
99 /* 1 Byte next payload type, stored in the field next_payload */
100 { U_INT_8
, offsetof(private_proposal_substructure_t
, next_payload
) },
101 /* 1 Reserved Byte */
102 { RESERVED_BYTE
, offsetof(private_proposal_substructure_t
, reserved
) },
103 /* Length of the whole proposal substructure payload*/
104 { PAYLOAD_LENGTH
, offsetof(private_proposal_substructure_t
, proposal_length
) },
105 /* proposal number is a number of 8 bit */
106 { U_INT_8
, offsetof(private_proposal_substructure_t
, proposal_number
) },
107 /* protocol ID is a number of 8 bit */
108 { U_INT_8
, offsetof(private_proposal_substructure_t
, protocol_id
) },
109 /* SPI Size has its own type */
110 { SPI_SIZE
, offsetof(private_proposal_substructure_t
, spi_size
) },
111 /* Number of transforms is a number of 8 bit */
112 { U_INT_8
, offsetof(private_proposal_substructure_t
, transforms_count
) },
113 /* SPI is a chunk of variable size*/
114 { SPI
, offsetof(private_proposal_substructure_t
, spi
) },
115 /* Transforms are stored in a transform substructure list */
116 { PAYLOAD_LIST
+ TRANSFORM_SUBSTRUCTURE_V1
,
117 offsetof(private_proposal_substructure_t
, transforms
) },
121 * Encoding rules for a IKEv2 Proposal substructure.
123 static encoding_rule_t encodings_v2
[] = {
124 /* 1 Byte next payload type, stored in the field next_payload */
125 { U_INT_8
, offsetof(private_proposal_substructure_t
, next_payload
) },
126 /* 1 Reserved Byte */
127 { RESERVED_BYTE
, offsetof(private_proposal_substructure_t
, reserved
) },
128 /* Length of the whole proposal substructure payload*/
129 { PAYLOAD_LENGTH
, offsetof(private_proposal_substructure_t
, proposal_length
) },
130 /* proposal number is a number of 8 bit */
131 { U_INT_8
, offsetof(private_proposal_substructure_t
, proposal_number
) },
132 /* protocol ID is a number of 8 bit */
133 { U_INT_8
, offsetof(private_proposal_substructure_t
, protocol_id
) },
134 /* SPI Size has its own type */
135 { SPI_SIZE
, offsetof(private_proposal_substructure_t
, spi_size
) },
136 /* Number of transforms is a number of 8 bit */
137 { U_INT_8
, offsetof(private_proposal_substructure_t
, transforms_count
) },
138 /* SPI is a chunk of variable size*/
139 { SPI
, offsetof(private_proposal_substructure_t
, spi
) },
140 /* Transforms are stored in a transform substructure list */
141 { PAYLOAD_LIST
+ TRANSFORM_SUBSTRUCTURE
,
142 offsetof(private_proposal_substructure_t
, transforms
) },
147 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
148 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
149 ! 0 (last) or 2 ! RESERVED ! Proposal Length !
150 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
151 ! Proposal # ! Protocol ID ! SPI Size !# of Transforms!
152 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
154 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165 IKEV1_ENCR_DES_CBC
= 1,
166 IKEV1_ENCR_IDEA_CBC
= 2,
167 IKEV1_ENCR_BLOWFISH_CBC
= 3,
168 IKEV1_ENCR_RC5_R16_B64_CBC
= 4,
169 IKEV1_ENCR_3DES_CBC
= 5,
170 IKEV1_ENCR_CAST_CBC
= 6,
171 IKEV1_ENCR_AES_CBC
= 7,
172 IKEV1_ENCR_CAMELLIA_CBC
= 8,
174 } ikev1_encryption_t
;
182 IKEV1_HASH_TIGER
= 3,
183 IKEV1_HASH_SHA2_256
= 4,
184 IKEV1_HASH_SHA2_384
= 5,
185 IKEV1_HASH_SHA2_512
= 6,
189 * IKEv1 Transform ID IKE.
192 IKEV1_TRANSID_KEY_IKE
= 1,
193 } ikev1_ike_transid_t
;
196 * IKEv1 Transform ID ESP.
199 IKEV1_TRANSID_ESP_DES_IV64
= 1,
200 IKEV1_TRANSID_ESP_DES
= 2,
201 IKEV1_TRANSID_ESP_3DES
= 3,
202 IKEV1_TRANSID_ESP_RC5
= 4,
203 IKEV1_TRANSID_ESP_IDEA
= 5,
204 IKEV1_TRANSID_ESP_CAST
= 6,
205 IKEV1_TRANSID_ESP_BLOWFISH
= 7,
206 IKEV1_TRANSID_ESP_3IDEA
= 8,
207 IKEV1_TRANSID_ESP_DES_IV32
= 9,
208 IKEV1_TRANSID_ESP_RC4
= 10,
209 IKEV1_TRANSID_ESP_NULL
= 11,
210 IKEV1_TRANSID_ESP_AES_CBC
= 12,
211 } ikev1_esp_transid_t
;
214 * IKEv1 ESP Encapsulation mode.
217 IKEV1_ENCAP_TUNNEL
= 1,
218 IKEV1_ENCAP_TRANSPORT
= 2,
219 IKEV1_ENCAP_UDP_TUNNEL
= 3,
220 IKEV1_ENCAP_UDP_TRANSPORT
= 4,
224 * IKEv1 Life duration types.
227 IKEV1_LIFE_TYPE_SECONDS
= 1,
228 IKEV1_LIFE_TYPE_KILOBYTES
= 2,
232 * IKEv1 authenticaiton methods
236 IKEV1_AUTH_DSS_SIG
= 2,
237 IKEV1_AUTH_RSA_SIG
= 3,
238 IKEV1_AUTH_RSA_ENC
= 4,
239 IKEV1_AUTH_RSA_ENC_REV
= 5,
240 IKEV1_AUTH_XAUTH_INIT_PSK
= 65001,
241 IKEV1_AUTH_XAUTH_RESP_PSK
= 65002,
242 IKEV1_AUTH_XAUTH_INIT_DSS
= 65003,
243 IKEV1_AUTH_XAUTH_RESP_DSS
= 65004,
244 IKEV1_AUTH_XAUTH_INIT_RSA
= 65005,
245 IKEV1_AUTH_XAUTH_RESP_RSA
= 65006,
246 IKEV1_AUTH_XAUTH_INIT_RSA_ENC
= 65007,
247 IKEV1_AUTH_XAUTH_RESP_RSA_ENC
= 65008,
248 IKEV1_AUTH_XAUTH_INIT_RSA_ENC_REV
= 65009,
249 IKEV1_AUTH_XAUTH_RESP_RSA_ENC_REV
= 65010,
250 IKEV1_AUTH_HYBRID_INIT_RSA
= 64221,
251 IKEV1_AUTH_HYBRID_RESP_RSA
= 64222,
252 IKEV1_AUTH_HYBRID_INIT_DSS
= 64223,
253 IKEV1_AUTH_HYBRID_RESP_DSS
= 64224,
255 } ikev1_auth_method_t
;
257 METHOD(payload_t
, verify
, status_t
,
258 private_proposal_substructure_t
*this)
260 status_t status
= SUCCESS
;
261 enumerator_t
*enumerator
;
264 if (this->next_payload
!= NO_PAYLOAD
&& this->next_payload
!= 2)
267 DBG1(DBG_ENC
, "inconsistent next payload");
270 if (this->transforms_count
!= this->transforms
->get_count(this->transforms
))
272 /* must be the same! */
273 DBG1(DBG_ENC
, "transform count invalid");
277 switch (this->protocol_id
)
281 if (this->spi
.len
!= 4)
283 DBG1(DBG_ENC
, "invalid SPI length in %N proposal",
284 protocol_id_names
, this->protocol_id
);
289 if (this->spi
.len
!= 0 && this->spi
.len
!= 8)
291 DBG1(DBG_ENC
, "invalid SPI length in IKE proposal");
298 enumerator
= this->transforms
->create_enumerator(this->transforms
);
299 while (enumerator
->enumerate(enumerator
, ¤t
))
301 status
= current
->verify(current
);
302 if (status
!= SUCCESS
)
304 DBG1(DBG_ENC
, "TRANSFORM_SUBSTRUCTURE verification failed");
308 enumerator
->destroy(enumerator
);
310 /* proposal number is checked in SA payload */
314 METHOD(payload_t
, get_encoding_rules
, int,
315 private_proposal_substructure_t
*this, encoding_rule_t
**rules
)
317 if (this->type
== PROPOSAL_SUBSTRUCTURE
)
319 *rules
= encodings_v2
;
320 return countof(encodings_v2
);
322 *rules
= encodings_v1
;
323 return countof(encodings_v1
);
326 METHOD(payload_t
, get_header_length
, int,
327 private_proposal_substructure_t
*this)
329 return 8 + this->spi_size
;
332 METHOD(payload_t
, get_type
, payload_type_t
,
333 private_proposal_substructure_t
*this)
338 METHOD(payload_t
, get_next_type
, payload_type_t
,
339 private_proposal_substructure_t
*this)
341 return this->next_payload
;
344 METHOD(payload_t
, set_next_type
, void,
345 private_proposal_substructure_t
*this, payload_type_t type
)
350 * (re-)compute the length of the payload.
352 static void compute_length(private_proposal_substructure_t
*this)
354 enumerator_t
*enumerator
;
355 payload_t
*transform
;
357 this->transforms_count
= 0;
358 this->proposal_length
= get_header_length(this);
359 enumerator
= this->transforms
->create_enumerator(this->transforms
);
360 while (enumerator
->enumerate(enumerator
, &transform
))
362 this->proposal_length
+= transform
->get_length(transform
);
363 this->transforms_count
++;
365 enumerator
->destroy(enumerator
);
368 METHOD(payload_t
, get_length
, size_t,
369 private_proposal_substructure_t
*this)
371 return this->proposal_length
;
375 * Add a transform substructure to the proposal
377 static void add_transform_substructure(private_proposal_substructure_t
*this,
378 transform_substructure_t
*transform
)
380 if (this->transforms
->get_count(this->transforms
) > 0)
382 transform_substructure_t
*last
;
384 this->transforms
->get_last(this->transforms
, (void **)&last
);
385 last
->set_is_last_transform(last
, FALSE
);
387 transform
->set_is_last_transform(transform
,TRUE
);
388 this->transforms
->insert_last(this->transforms
, transform
);
389 compute_length(this);
392 METHOD(proposal_substructure_t
, set_is_last_proposal
, void,
393 private_proposal_substructure_t
*this, bool is_last
)
395 this->next_payload
= is_last
? 0 : PROPOSAL_TYPE_VALUE
;
398 METHOD(proposal_substructure_t
, set_proposal_number
, void,
399 private_proposal_substructure_t
*this,u_int8_t proposal_number
)
401 this->proposal_number
= proposal_number
;
404 METHOD(proposal_substructure_t
, get_proposal_number
, u_int8_t
,
405 private_proposal_substructure_t
*this)
407 return this->proposal_number
;
410 METHOD(proposal_substructure_t
, set_protocol_id
, void,
411 private_proposal_substructure_t
*this,u_int8_t protocol_id
)
413 this->protocol_id
= protocol_id
;
416 METHOD(proposal_substructure_t
, get_protocol_id
, u_int8_t
,
417 private_proposal_substructure_t
*this)
419 return this->protocol_id
;
422 METHOD(proposal_substructure_t
, set_spi
, void,
423 private_proposal_substructure_t
*this, chunk_t spi
)
426 this->spi
= chunk_clone(spi
);
427 this->spi_size
= spi
.len
;
428 compute_length(this);
431 METHOD(proposal_substructure_t
, get_spi
, chunk_t
,
432 private_proposal_substructure_t
*this)
438 * Add a transform to a proposal for IKEv2
440 static void add_to_proposal_v2(proposal_t
*proposal
,
441 transform_substructure_t
*transform
)
443 transform_attribute_t
*tattr
;
444 enumerator_t
*enumerator
;
445 u_int16_t key_length
= 0;
447 enumerator
= transform
->create_attribute_enumerator(transform
);
448 while (enumerator
->enumerate(enumerator
, &tattr
))
450 if (tattr
->get_attribute_type(tattr
) == TATTR_IKEV2_KEY_LENGTH
)
452 key_length
= tattr
->get_value(tattr
);
456 enumerator
->destroy(enumerator
);
458 proposal
->add_algorithm(proposal
,
459 transform
->get_transform_type_or_number(transform
),
460 transform
->get_transform_id(transform
), key_length
);
464 * Map IKEv1 to IKEv2 algorithms
472 * Encryption algorithm mapping
474 static algo_map_t map_encr
[] = {
475 { IKEV1_ENCR_DES_CBC
, ENCR_DES
},
476 { IKEV1_ENCR_IDEA_CBC
, ENCR_IDEA
},
477 { IKEV1_ENCR_BLOWFISH_CBC
, ENCR_BLOWFISH
},
478 { IKEV1_ENCR_3DES_CBC
, ENCR_3DES
},
479 { IKEV1_ENCR_CAST_CBC
, ENCR_CAST
},
480 { IKEV1_ENCR_AES_CBC
, ENCR_AES_CBC
},
481 { IKEV1_ENCR_CAMELLIA_CBC
, ENCR_CAMELLIA_CBC
},
485 * Integrity algorithm mapping
487 static algo_map_t map_integ
[] = {
488 { IKEV1_HASH_MD5
, AUTH_HMAC_MD5_96
},
489 { IKEV1_HASH_SHA1
, AUTH_HMAC_SHA1_96
},
490 { IKEV1_HASH_SHA2_256
, AUTH_HMAC_SHA2_256_128
},
491 { IKEV1_HASH_SHA2_384
, AUTH_HMAC_SHA2_384_192
},
492 { IKEV1_HASH_SHA2_512
, AUTH_HMAC_SHA2_512_256
},
496 * PRF algorithm mapping
498 static algo_map_t map_prf
[] = {
499 { IKEV1_HASH_MD5
, PRF_HMAC_MD5
},
500 { IKEV1_HASH_SHA1
, PRF_HMAC_SHA1
},
501 { IKEV1_HASH_SHA2_256
, PRF_HMAC_SHA2_256
},
502 { IKEV1_HASH_SHA2_384
, PRF_HMAC_SHA2_384
},
503 { IKEV1_HASH_SHA2_512
, PRF_HMAC_SHA2_512
},
507 * Get IKEv2 algorithm from IKEv1 identifier
509 static u_int16_t
get_alg_from_ikev1(transform_type_t type
, u_int16_t value
)
517 case ENCRYPTION_ALGORITHM
:
519 count
= countof(map_encr
);
520 def
= ENCR_UNDEFINED
;
522 case INTEGRITY_ALGORITHM
:
524 count
= countof(map_integ
);
525 def
= AUTH_UNDEFINED
;
527 case PSEUDO_RANDOM_FUNCTION
:
529 count
= countof(map_prf
);
535 for (i
= 0; i
< count
; i
++)
537 if (map
[i
].ikev1
== value
)
546 * Get IKEv1 algorithm from IKEv2 identifier
548 static u_int16_t
get_ikev1_from_alg(transform_type_t type
, u_int16_t value
)
555 case ENCRYPTION_ALGORITHM
:
557 count
= countof(map_encr
);
559 case INTEGRITY_ALGORITHM
:
561 count
= countof(map_integ
);
563 case PSEUDO_RANDOM_FUNCTION
:
565 count
= countof(map_prf
);
570 for (i
= 0; i
< count
; i
++)
572 if (map
[i
].ikev2
== value
)
581 * Get IKEv1 authentication attribute from auth_method_t
583 static u_int16_t
get_ikev1_auth(auth_method_t method
)
588 return IKEV1_AUTH_RSA_SIG
;
590 return IKEV1_AUTH_DSS_SIG
;
591 case AUTH_XAUTH_INIT_PSK
:
592 return IKEV1_AUTH_XAUTH_INIT_PSK
;
593 case AUTH_XAUTH_INIT_RSA
:
594 return IKEV1_AUTH_XAUTH_INIT_RSA
;
595 case AUTH_HYBRID_INIT_RSA
:
596 return IKEV1_AUTH_HYBRID_INIT_RSA
;
598 /* TODO-IKEv1: Handle other XAUTH methods */
599 /* TODO-IKEv1: Handle ECDSA methods */
601 return IKEV1_AUTH_PSK
;
606 * Get IKEv1 encapsulation mode
608 static u_int16_t
get_ikev1_mode(ipsec_mode_t mode
, bool udp
)
613 return udp
? IKEV1_ENCAP_UDP_TUNNEL
: IKEV1_ENCAP_TUNNEL
;
615 return udp
? IKEV1_ENCAP_UDP_TRANSPORT
: IKEV1_ENCAP_TRANSPORT
;
617 return IKEV1_ENCAP_TUNNEL
;
622 * Add an IKE transform to a proposal for IKEv1
624 static void add_to_proposal_v1_ike(proposal_t
*proposal
,
625 transform_substructure_t
*transform
)
627 transform_attribute_type_t type
;
628 transform_attribute_t
*tattr
;
629 enumerator_t
*enumerator
;
630 u_int16_t value
, key_length
= 0;
631 u_int16_t encr
= ENCR_UNDEFINED
;
633 enumerator
= transform
->create_attribute_enumerator(transform
);
634 while (enumerator
->enumerate(enumerator
, &tattr
))
636 type
= tattr
->get_attribute_type(tattr
);
637 value
= tattr
->get_value(tattr
);
640 case TATTR_PH1_ENCRYPTION_ALGORITHM
:
641 encr
= get_alg_from_ikev1(ENCRYPTION_ALGORITHM
, value
);
643 case TATTR_PH1_KEY_LENGTH
:
646 case TATTR_PH1_HASH_ALGORITHM
:
647 proposal
->add_algorithm(proposal
, INTEGRITY_ALGORITHM
,
648 get_alg_from_ikev1(INTEGRITY_ALGORITHM
, value
), 0);
649 proposal
->add_algorithm(proposal
, PSEUDO_RANDOM_FUNCTION
,
650 get_alg_from_ikev1(PSEUDO_RANDOM_FUNCTION
, value
), 0);
652 case TATTR_PH1_GROUP
:
653 proposal
->add_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
,
657 /* TODO-IKEv1: lifetimes, authentication and other attributes */
661 enumerator
->destroy(enumerator
);
663 if (encr
!= ENCR_UNDEFINED
)
665 proposal
->add_algorithm(proposal
, ENCRYPTION_ALGORITHM
, encr
, key_length
);
670 * Add an ESP transform to a proposal for IKEv1
672 static void add_to_proposal_v1_esp(proposal_t
*proposal
,
673 transform_substructure_t
*transform
)
675 transform_attribute_type_t type
;
676 transform_attribute_t
*tattr
;
677 enumerator_t
*enumerator
;
678 u_int16_t value
, key_length
= 0;
680 enumerator
= transform
->create_attribute_enumerator(transform
);
681 while (enumerator
->enumerate(enumerator
, &tattr
))
683 type
= tattr
->get_attribute_type(tattr
);
684 value
= tattr
->get_value(tattr
);
687 case TATTR_PH2_KEY_LENGTH
:
690 case TATTR_PH2_AUTH_ALGORITHM
:
691 proposal
->add_algorithm(proposal
, INTEGRITY_ALGORITHM
,
692 get_alg_from_ikev1(INTEGRITY_ALGORITHM
, value
), 0);
694 case TATTR_PH2_GROUP
:
695 proposal
->add_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
,
699 /* TODO-IKEv1: lifetimes other attributes */
703 enumerator
->destroy(enumerator
);
705 /* TODO-IKEv1: handle ESN attribute */
706 proposal
->add_algorithm(proposal
, EXTENDED_SEQUENCE_NUMBERS
,
707 NO_EXT_SEQ_NUMBERS
, 0);
709 proposal
->add_algorithm(proposal
, ENCRYPTION_ALGORITHM
,
710 transform
->get_transform_id(transform
), key_length
);
713 METHOD(proposal_substructure_t
, get_proposals
, void,
714 private_proposal_substructure_t
*this, linked_list_t
*proposals
)
716 transform_substructure_t
*transform
;
717 enumerator_t
*enumerator
;
718 proposal_t
*proposal
= NULL
;
721 switch (this->spi
.len
)
724 spi
= *((u_int32_t
*)this->spi
.ptr
);
727 spi
= *((u_int64_t
*)this->spi
.ptr
);
733 enumerator
= this->transforms
->create_enumerator(this->transforms
);
734 while (enumerator
->enumerate(enumerator
, &transform
))
738 proposal
= proposal_create(this->protocol_id
, this->proposal_number
);
739 proposal
->set_spi(proposal
, spi
);
740 proposals
->insert_last(proposals
, proposal
);
742 if (this->type
== PROPOSAL_SUBSTRUCTURE
)
744 add_to_proposal_v2(proposal
, transform
);
748 switch (this->protocol_id
)
751 add_to_proposal_v1_ike(proposal
, transform
);
754 add_to_proposal_v1_esp(proposal
, transform
);
759 /* create a new proposal for each transform in IKEv1 */
763 enumerator
->destroy(enumerator
);
766 METHOD(proposal_substructure_t
, create_substructure_enumerator
, enumerator_t
*,
767 private_proposal_substructure_t
*this)
769 return this->transforms
->create_enumerator(this->transforms
);
773 * Get an attribute from any transform, 0 if not found
775 static u_int64_t
get_attr(private_proposal_substructure_t
*this,
776 transform_attribute_type_t type
)
778 enumerator_t
*transforms
, *attributes
;
779 transform_substructure_t
*transform
;
780 transform_attribute_t
*attr
;
782 transforms
= this->transforms
->create_enumerator(this->transforms
);
783 while (transforms
->enumerate(transforms
, &transform
))
785 attributes
= transform
->create_attribute_enumerator(transform
);
786 while (attributes
->enumerate(attributes
, &attr
))
788 if (attr
->get_attribute_type(attr
) == type
)
790 attributes
->destroy(attributes
);
791 transforms
->destroy(transforms
);
792 return attr
->get_value(attr
);
795 attributes
->destroy(attributes
);
797 transforms
->destroy(transforms
);
802 * Look up a lifetime duration of a given kind in all transforms
804 static u_int64_t
get_life_duration(private_proposal_substructure_t
*this,
805 transform_attribute_type_t type_attr
, ikev1_life_type_t type
,
806 transform_attribute_type_t dur_attr
)
808 enumerator_t
*transforms
, *attributes
;
809 transform_substructure_t
*transform
;
810 transform_attribute_t
*attr
;
812 transforms
= this->transforms
->create_enumerator(this->transforms
);
813 while (transforms
->enumerate(transforms
, &transform
))
815 attributes
= transform
->create_attribute_enumerator(transform
);
816 while (attributes
->enumerate(attributes
, &attr
))
818 if (attr
->get_attribute_type(attr
) == type_attr
&&
819 attr
->get_value(attr
) == type
)
820 { /* got type attribute, look for duration following next */
821 while (attributes
->enumerate(attributes
, &attr
))
823 if (attr
->get_attribute_type(attr
) == dur_attr
)
825 attributes
->destroy(attributes
);
826 transforms
->destroy(transforms
);
827 return attr
->get_value(attr
);
832 attributes
->destroy(attributes
);
834 transforms
->destroy(transforms
);
838 METHOD(proposal_substructure_t
, get_lifetime
, u_int32_t
,
839 private_proposal_substructure_t
*this)
843 switch (this->protocol_id
)
846 return get_life_duration(this, TATTR_PH1_LIFE_TYPE
,
847 IKEV1_LIFE_TYPE_SECONDS
, TATTR_PH1_LIFE_DURATION
);
849 duration
= get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE
,
850 IKEV1_LIFE_TYPE_SECONDS
, TATTR_PH2_SA_LIFE_DURATION
);
852 { /* default to 8 hours, RFC 2407 */
861 METHOD(proposal_substructure_t
, get_lifebytes
, u_int64_t
,
862 private_proposal_substructure_t
*this)
864 switch (this->protocol_id
)
867 return 1000 * get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE
,
868 IKEV1_LIFE_TYPE_KILOBYTES
, TATTR_PH2_SA_LIFE_DURATION
);
875 METHOD(proposal_substructure_t
, get_auth_method
, auth_method_t
,
876 private_proposal_substructure_t
*this)
878 switch (get_attr(this, TATTR_PH1_AUTH_METHOD
))
882 case IKEV1_AUTH_RSA_SIG
:
884 case IKEV1_AUTH_DSS_SIG
:
886 case IKEV1_AUTH_XAUTH_INIT_PSK
:
887 return AUTH_XAUTH_INIT_PSK
;
888 case IKEV1_AUTH_XAUTH_INIT_RSA
:
889 return AUTH_XAUTH_INIT_RSA
;
890 case IKEV1_AUTH_HYBRID_INIT_RSA
:
891 return AUTH_HYBRID_INIT_RSA
;
893 /* TODO-IKEv1: other XAUTH, ECDSA sigs */
898 METHOD(proposal_substructure_t
, get_encap_mode
, ipsec_mode_t
,
899 private_proposal_substructure_t
*this, bool *udp
)
902 switch (get_attr(this, TATTR_PH2_ENCAP_MODE
))
904 case IKEV1_ENCAP_TRANSPORT
:
905 return MODE_TRANSPORT
;
906 case IKEV1_ENCAP_TUNNEL
:
907 return MODE_TRANSPORT
;
908 case IKEV1_ENCAP_UDP_TRANSPORT
:
910 return MODE_TRANSPORT
;
911 case IKEV1_ENCAP_UDP_TUNNEL
:
915 /* default to TUNNEL, RFC 2407 says implementation specific */
920 METHOD2(payload_t
, proposal_substructure_t
, destroy
, void,
921 private_proposal_substructure_t
*this)
923 this->transforms
->destroy_offset(this->transforms
,
924 offsetof(payload_t
, destroy
));
925 chunk_free(&this->spi
);
930 * Described in header.
932 proposal_substructure_t
*proposal_substructure_create(payload_type_t type
)
934 private_proposal_substructure_t
*this;
938 .payload_interface
= {
940 .get_encoding_rules
= _get_encoding_rules
,
941 .get_header_length
= _get_header_length
,
942 .get_length
= _get_length
,
943 .get_next_type
= _get_next_type
,
944 .set_next_type
= _set_next_type
,
945 .get_type
= _get_type
,
948 .set_proposal_number
= _set_proposal_number
,
949 .get_proposal_number
= _get_proposal_number
,
950 .set_protocol_id
= _set_protocol_id
,
951 .get_protocol_id
= _get_protocol_id
,
952 .set_is_last_proposal
= _set_is_last_proposal
,
953 .get_proposals
= _get_proposals
,
954 .create_substructure_enumerator
= _create_substructure_enumerator
,
957 .get_lifetime
= _get_lifetime
,
958 .get_lifebytes
= _get_lifebytes
,
959 .get_auth_method
= _get_auth_method
,
960 .get_encap_mode
= _get_encap_mode
,
963 .next_payload
= NO_PAYLOAD
,
964 .transforms
= linked_list_create(),
967 compute_length(this);
969 return &this->public;
973 * Add an IKEv1 IKE proposal to the substructure
975 static void set_from_proposal_v1_ike(private_proposal_substructure_t
*this,
976 proposal_t
*proposal
, u_int32_t lifetime
,
977 auth_method_t method
, int number
)
979 transform_substructure_t
*transform
;
980 u_int16_t alg
, key_size
;
981 enumerator_t
*enumerator
;
983 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1
,
984 number
, IKEV1_TRANSID_KEY_IKE
);
986 enumerator
= proposal
->create_enumerator(proposal
, ENCRYPTION_ALGORITHM
);
987 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
989 alg
= get_ikev1_from_alg(ENCRYPTION_ALGORITHM
, alg
);
992 transform
->add_transform_attribute(transform
,
993 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
994 TATTR_PH1_ENCRYPTION_ALGORITHM
, alg
));
997 transform
->add_transform_attribute(transform
,
998 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
999 TATTR_PH1_KEY_LENGTH
, key_size
));
1003 enumerator
->destroy(enumerator
);
1005 /* encode the integrity algorithm as hash and assume use the same PRF */
1006 enumerator
= proposal
->create_enumerator(proposal
, INTEGRITY_ALGORITHM
);
1007 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1009 alg
= get_ikev1_from_alg(INTEGRITY_ALGORITHM
, alg
);
1012 transform
->add_transform_attribute(transform
,
1013 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1014 TATTR_PH1_HASH_ALGORITHM
, alg
));
1017 enumerator
->destroy(enumerator
);
1019 enumerator
= proposal
->create_enumerator(proposal
, DIFFIE_HELLMAN_GROUP
);
1020 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1022 transform
->add_transform_attribute(transform
,
1023 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1024 TATTR_PH1_GROUP
, alg
));
1026 enumerator
->destroy(enumerator
);
1028 transform
->add_transform_attribute(transform
,
1029 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1030 TATTR_PH1_AUTH_METHOD
, get_ikev1_auth(method
)));
1031 transform
->add_transform_attribute(transform
,
1032 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1033 TATTR_PH1_LIFE_TYPE
, IKEV1_LIFE_TYPE_SECONDS
));
1034 transform
->add_transform_attribute(transform
,
1035 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1036 TATTR_PH1_LIFE_DURATION
, lifetime
));
1038 add_transform_substructure(this, transform
);
1042 * Add an IKEv1 ESP proposal to the substructure
1044 static void set_from_proposal_v1_esp(private_proposal_substructure_t
*this,
1045 proposal_t
*proposal
, u_int32_t lifetime
, u_int64_t lifebytes
,
1046 ipsec_mode_t mode
, bool udp
, int number
)
1048 transform_substructure_t
*transform
= NULL
;
1049 u_int16_t alg
, key_size
;
1050 enumerator_t
*enumerator
;
1052 enumerator
= proposal
->create_enumerator(proposal
, ENCRYPTION_ALGORITHM
);
1053 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1055 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1
,
1059 transform
->add_transform_attribute(transform
,
1060 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1061 TATTR_PH2_KEY_LENGTH
, key_size
));
1064 enumerator
->destroy(enumerator
);
1070 enumerator
= proposal
->create_enumerator(proposal
, INTEGRITY_ALGORITHM
);
1071 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1073 alg
= get_ikev1_from_alg(INTEGRITY_ALGORITHM
, alg
);
1076 transform
->add_transform_attribute(transform
,
1077 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1078 TATTR_PH2_AUTH_ALGORITHM
, alg
));
1081 enumerator
->destroy(enumerator
);
1083 enumerator
= proposal
->create_enumerator(proposal
, DIFFIE_HELLMAN_GROUP
);
1084 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1086 transform
->add_transform_attribute(transform
,
1087 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1088 TATTR_PH2_GROUP
, alg
));
1090 enumerator
->destroy(enumerator
);
1092 transform
->add_transform_attribute(transform
,
1093 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1094 TATTR_PH2_ENCAP_MODE
, get_ikev1_mode(mode
, udp
)));
1097 transform
->add_transform_attribute(transform
,
1098 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1099 TATTR_PH2_SA_LIFE_TYPE
, IKEV1_LIFE_TYPE_SECONDS
));
1100 transform
->add_transform_attribute(transform
,
1101 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1102 TATTR_PH2_SA_LIFE_DURATION
, lifetime
));
1106 transform
->add_transform_attribute(transform
,
1107 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1108 TATTR_PH2_SA_LIFE_TYPE
, IKEV1_LIFE_TYPE_KILOBYTES
));
1109 transform
->add_transform_attribute(transform
,
1110 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1111 TATTR_PH2_SA_LIFE_DURATION
, lifebytes
/ 1000));
1114 add_transform_substructure(this, transform
);
1118 * Add an IKEv2 proposal to the substructure
1120 static void set_from_proposal_v2(private_proposal_substructure_t
*this,
1121 proposal_t
*proposal
)
1123 transform_substructure_t
*transform
;
1124 u_int16_t alg
, key_size
;
1125 enumerator_t
*enumerator
;
1127 /* encryption algorithm is only available in ESP */
1128 enumerator
= proposal
->create_enumerator(proposal
, ENCRYPTION_ALGORITHM
);
1129 while (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1131 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1132 ENCRYPTION_ALGORITHM
, alg
);
1135 transform
->add_transform_attribute(transform
,
1136 transform_attribute_create_value(TRANSFORM_ATTRIBUTE
,
1137 TATTR_IKEV2_KEY_LENGTH
, key_size
));
1139 add_transform_substructure(this, transform
);
1141 enumerator
->destroy(enumerator
);
1143 /* integrity algorithms */
1144 enumerator
= proposal
->create_enumerator(proposal
, INTEGRITY_ALGORITHM
);
1145 while (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1147 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1148 INTEGRITY_ALGORITHM
, alg
);
1149 add_transform_substructure(this, transform
);
1151 enumerator
->destroy(enumerator
);
1153 /* prf algorithms */
1154 enumerator
= proposal
->create_enumerator(proposal
, PSEUDO_RANDOM_FUNCTION
);
1155 while (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1157 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1158 PSEUDO_RANDOM_FUNCTION
, alg
);
1159 add_transform_substructure(this, transform
);
1161 enumerator
->destroy(enumerator
);
1164 enumerator
= proposal
->create_enumerator(proposal
, DIFFIE_HELLMAN_GROUP
);
1165 while (enumerator
->enumerate(enumerator
, &alg
, NULL
))
1167 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1168 DIFFIE_HELLMAN_GROUP
, alg
);
1169 add_transform_substructure(this, transform
);
1171 enumerator
->destroy(enumerator
);
1173 /* extended sequence numbers */
1174 enumerator
= proposal
->create_enumerator(proposal
, EXTENDED_SEQUENCE_NUMBERS
);
1175 while (enumerator
->enumerate(enumerator
, &alg
, NULL
))
1177 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1178 EXTENDED_SEQUENCE_NUMBERS
, alg
);
1179 add_transform_substructure(this, transform
);
1181 enumerator
->destroy(enumerator
);
1185 * Set SPI and other data from proposal, compute length
1187 static void set_data(private_proposal_substructure_t
*this, proposal_t
*proposal
)
1192 /* add SPI, if necessary */
1193 switch (proposal
->get_protocol(proposal
))
1197 spi32
= proposal
->get_spi(proposal
);
1198 this->spi
= chunk_clone(chunk_from_thing(spi32
));
1199 this->spi_size
= this->spi
.len
;
1202 spi64
= proposal
->get_spi(proposal
);
1204 { /* IKE only uses SPIS when rekeying, but on initial setup */
1205 this->spi
= chunk_clone(chunk_from_thing(spi64
));
1206 this->spi_size
= this->spi
.len
;
1212 this->proposal_number
= proposal
->get_number(proposal
);
1213 this->protocol_id
= proposal
->get_protocol(proposal
);
1214 compute_length(this);
1218 * Described in header.
1220 proposal_substructure_t
*proposal_substructure_create_from_proposal_v2(
1221 proposal_t
*proposal
)
1223 private_proposal_substructure_t
*this;
1225 this = (private_proposal_substructure_t
*)
1226 proposal_substructure_create(SECURITY_ASSOCIATION
);
1227 set_from_proposal_v2(this, proposal
);
1228 set_data(this, proposal
);
1230 return &this->public;
1236 proposal_substructure_t
*proposal_substructure_create_from_proposal_v1(
1237 proposal_t
*proposal
, u_int32_t lifetime
, u_int64_t lifebytes
,
1238 auth_method_t auth
, ipsec_mode_t mode
, bool udp
)
1240 private_proposal_substructure_t
*this;
1242 this = (private_proposal_substructure_t
*)
1243 proposal_substructure_create(PROPOSAL_SUBSTRUCTURE_V1
);
1244 switch (proposal
->get_protocol(proposal
))
1247 set_from_proposal_v1_ike(this, proposal
, lifetime
, auth
, 1);
1250 set_from_proposal_v1_esp(this, proposal
, lifetime
,
1251 lifebytes
, mode
, udp
, 1);
1256 set_data(this, proposal
);
1258 return &this->public;
1264 proposal_substructure_t
*proposal_substructure_create_from_proposals_v1(
1265 linked_list_t
*proposals
, u_int32_t lifetime
, u_int64_t lifebytes
,
1266 auth_method_t auth
, ipsec_mode_t mode
, bool udp
)
1268 private_proposal_substructure_t
*this = NULL
;
1269 enumerator_t
*enumerator
;
1270 proposal_t
*proposal
;
1273 enumerator
= proposals
->create_enumerator(proposals
);
1274 while (enumerator
->enumerate(enumerator
, &proposal
))
1278 this = (private_proposal_substructure_t
*)
1279 proposal_substructure_create_from_proposal_v1(
1280 proposal
, lifetime
, lifebytes
, auth
, mode
, udp
);
1284 switch (proposal
->get_protocol(proposal
))
1287 set_from_proposal_v1_ike(this, proposal
, lifetime
,
1291 set_from_proposal_v1_esp(this, proposal
, lifetime
,
1292 lifebytes
, mode
, udp
, ++number
);
1299 enumerator
->destroy(enumerator
);
1301 return &this->public;