2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2005-2010 Martin Willi
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
20 #include "proposal_substructure.h"
22 #include <encoding/payloads/encodings.h>
23 #include <encoding/payloads/transform_substructure.h>
25 #include <collections/linked_list.h>
29 * IKEv2 Value for a proposal payload.
31 #define PROPOSAL_TYPE_VALUE 2
33 typedef struct private_proposal_substructure_t private_proposal_substructure_t
;
36 * Private data of an proposal_substructure_t object.
38 struct private_proposal_substructure_t
{
41 * Public proposal_substructure_t interface.
43 proposal_substructure_t
public;
48 u_int8_t next_payload
;
56 * Length of this payload.
58 u_int16_t proposal_length
;
63 u_int8_t proposal_number
;
71 * SPI size of the following SPI.
76 * Number of transforms.
78 u_int8_t transforms_count
;
81 * SPI is stored as chunk.
86 * Transforms are stored in a linked_list_t.
88 linked_list_t
*transforms
;
91 * Type of this payload, PROPOSAL_SUBSTRUCTURE or PROPOSAL_SUBSTRUCTURE_V1
97 * Encoding rules for a IKEv1 Proposal substructure.
99 static encoding_rule_t encodings_v1
[] = {
100 /* 1 Byte next payload type, stored in the field next_payload */
101 { U_INT_8
, offsetof(private_proposal_substructure_t
, next_payload
) },
102 /* 1 Reserved Byte */
103 { RESERVED_BYTE
, offsetof(private_proposal_substructure_t
, reserved
) },
104 /* Length of the whole proposal substructure payload*/
105 { PAYLOAD_LENGTH
, offsetof(private_proposal_substructure_t
, proposal_length
) },
106 /* proposal number is a number of 8 bit */
107 { U_INT_8
, offsetof(private_proposal_substructure_t
, proposal_number
) },
108 /* protocol ID is a number of 8 bit */
109 { U_INT_8
, offsetof(private_proposal_substructure_t
, protocol_id
) },
110 /* SPI Size has its own type */
111 { SPI_SIZE
, offsetof(private_proposal_substructure_t
, spi_size
) },
112 /* Number of transforms is a number of 8 bit */
113 { U_INT_8
, offsetof(private_proposal_substructure_t
, transforms_count
) },
114 /* SPI is a chunk of variable size*/
115 { SPI
, offsetof(private_proposal_substructure_t
, spi
) },
116 /* Transforms are stored in a transform substructure list */
117 { PAYLOAD_LIST
+ TRANSFORM_SUBSTRUCTURE_V1
,
118 offsetof(private_proposal_substructure_t
, transforms
) },
122 * Encoding rules for a IKEv2 Proposal substructure.
124 static encoding_rule_t encodings_v2
[] = {
125 /* 1 Byte next payload type, stored in the field next_payload */
126 { U_INT_8
, offsetof(private_proposal_substructure_t
, next_payload
) },
127 /* 1 Reserved Byte */
128 { RESERVED_BYTE
, offsetof(private_proposal_substructure_t
, reserved
) },
129 /* Length of the whole proposal substructure payload*/
130 { PAYLOAD_LENGTH
, offsetof(private_proposal_substructure_t
, proposal_length
) },
131 /* proposal number is a number of 8 bit */
132 { U_INT_8
, offsetof(private_proposal_substructure_t
, proposal_number
) },
133 /* protocol ID is a number of 8 bit */
134 { U_INT_8
, offsetof(private_proposal_substructure_t
, protocol_id
) },
135 /* SPI Size has its own type */
136 { SPI_SIZE
, offsetof(private_proposal_substructure_t
, spi_size
) },
137 /* Number of transforms is a number of 8 bit */
138 { U_INT_8
, offsetof(private_proposal_substructure_t
, transforms_count
) },
139 /* SPI is a chunk of variable size*/
140 { SPI
, offsetof(private_proposal_substructure_t
, spi
) },
141 /* Transforms are stored in a transform substructure list */
142 { PAYLOAD_LIST
+ TRANSFORM_SUBSTRUCTURE
,
143 offsetof(private_proposal_substructure_t
, transforms
) },
148 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
149 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
150 ! 0 (last) or 2 ! RESERVED ! Proposal Length !
151 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
152 ! Proposal # ! Protocol ID ! SPI Size !# of Transforms!
153 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
155 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
166 IKEV1_ENCR_DES_CBC
= 1,
167 IKEV1_ENCR_IDEA_CBC
= 2,
168 IKEV1_ENCR_BLOWFISH_CBC
= 3,
169 IKEV1_ENCR_RC5_R16_B64_CBC
= 4,
170 IKEV1_ENCR_3DES_CBC
= 5,
171 IKEV1_ENCR_CAST_CBC
= 6,
172 IKEV1_ENCR_AES_CBC
= 7,
173 IKEV1_ENCR_CAMELLIA_CBC
= 8,
174 /* FreeS/WAN proprietary */
175 IKEV1_ENCR_SERPENT_CBC
= 65004,
176 IKEV1_ENCR_TWOFISH_CBC
= 65005,
177 } ikev1_encryption_t
;
185 IKEV1_HASH_TIGER
= 3,
186 IKEV1_HASH_SHA2_256
= 4,
187 IKEV1_HASH_SHA2_384
= 5,
188 IKEV1_HASH_SHA2_512
= 6,
192 * IKEv1 Transform ID IKE.
195 IKEV1_TRANSID_KEY_IKE
= 1,
196 } ikev1_ike_transid_t
;
199 * IKEv1 Transform ID ESP encryption algorithm.
202 IKEV1_ESP_ENCR_DES_IV64
= 1,
203 IKEV1_ESP_ENCR_DES
= 2,
204 IKEV1_ESP_ENCR_3DES
= 3,
205 IKEV1_ESP_ENCR_RC5
= 4,
206 IKEV1_ESP_ENCR_IDEA
= 5,
207 IKEV1_ESP_ENCR_CAST
= 6,
208 IKEV1_ESP_ENCR_BLOWFISH
= 7,
209 IKEV1_ESP_ENCR_3IDEA
= 8,
210 IKEV1_ESP_ENCR_DES_IV32
= 9,
211 IKEV1_ESP_ENCR_RC4
= 10,
212 IKEV1_ESP_ENCR_NULL
= 11,
213 IKEV1_ESP_ENCR_AES_CBC
= 12,
214 IKEV1_ESP_ENCR_AES_CTR
= 13,
215 IKEV1_ESP_ENCR_AES_CCM_8
= 14,
216 IKEV1_ESP_ENCR_AES_CCM_12
= 15,
217 IKEV1_ESP_ENCR_AES_CCM_16
= 16,
218 IKEV1_ESP_ENCR_AES_GCM_8
= 18,
219 IKEV1_ESP_ENCR_AES_GCM_12
= 19,
220 IKEV1_ESP_ENCR_AES_GCM_16
= 20,
221 IKEV1_ESP_ENCR_SEED_CBC
= 21,
222 IKEV1_ESP_ENCR_CAMELLIA
= 22,
223 IKEV1_ESP_ENCR_NULL_AUTH_AES_GMAC
= 23,
224 /* FreeS/WAN proprietary */
225 IKEV1_ESP_ENCR_SERPENT
= 252,
226 IKEV1_ESP_ENCR_TWOFISH
= 253,
227 } ikev1_esp_encr_transid_t
;
230 * IKEv1 Transform ID ESP authentication algorithm.
233 IKEV1_ESP_AUTH_HMAC_MD5
= 1,
234 IKEV1_ESP_AUTH_HMAC_SHA
= 2,
235 IKEV1_ESP_AUTH_DES_MAC
= 3,
236 IKEV1_ESP_AUTH_KPDK
= 4,
237 IKEV1_ESP_AUTH_HMAC_SHA2_256
= 5,
238 IKEV1_ESP_AUTH_HMAC_SHA2_384
= 6,
239 IKEV1_ESP_AUTH_HMAC_SHA2_512
= 7,
240 IKEV1_ESP_AUTH_HMAC_RIPEMD
= 8,
241 IKEV1_ESP_AUTH_AES_XCBC_MAC
= 9,
242 IKEV1_ESP_AUTH_SIG_RSA
= 10,
243 IKEV1_ESP_AUTH_AES_128_GMAC
= 11,
244 IKEV1_ESP_AUTH_AES_192_GMAC
= 12,
245 IKEV1_ESP_AUTH_AES_256_GMAC
= 13,
246 } ikev1_esp_auth_transid_it
;
249 * IKEv1 ESP Encapsulation mode.
252 IKEV1_ENCAP_TUNNEL
= 1,
253 IKEV1_ENCAP_TRANSPORT
= 2,
254 IKEV1_ENCAP_UDP_TUNNEL
= 3,
255 IKEV1_ENCAP_UDP_TRANSPORT
= 4,
256 IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03
= 61443,
257 IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03
= 61444,
261 * IKEv1 Life duration types.
264 IKEV1_LIFE_TYPE_SECONDS
= 1,
265 IKEV1_LIFE_TYPE_KILOBYTES
= 2,
269 * IKEv1 authentication methods
273 IKEV1_AUTH_DSS_SIG
= 2,
274 IKEV1_AUTH_RSA_SIG
= 3,
275 IKEV1_AUTH_RSA_ENC
= 4,
276 IKEV1_AUTH_RSA_ENC_REV
= 5,
277 IKEV1_AUTH_ECDSA_256
= 9,
278 IKEV1_AUTH_ECDSA_384
= 10,
279 IKEV1_AUTH_ECDSA_521
= 11,
281 IKEV1_AUTH_XAUTH_INIT_PSK
= 65001,
282 IKEV1_AUTH_XAUTH_RESP_PSK
= 65002,
283 IKEV1_AUTH_XAUTH_INIT_DSS
= 65003,
284 IKEV1_AUTH_XAUTH_RESP_DSS
= 65004,
285 IKEV1_AUTH_XAUTH_INIT_RSA
= 65005,
286 IKEV1_AUTH_XAUTH_RESP_RSA
= 65006,
287 IKEV1_AUTH_XAUTH_INIT_RSA_ENC
= 65007,
288 IKEV1_AUTH_XAUTH_RESP_RSA_ENC
= 65008,
289 IKEV1_AUTH_XAUTH_INIT_RSA_ENC_REV
= 65009,
290 IKEV1_AUTH_XAUTH_RESP_RSA_ENC_REV
= 65010,
292 IKEV1_AUTH_HYBRID_INIT_RSA
= 64221,
293 IKEV1_AUTH_HYBRID_RESP_RSA
= 64222,
294 IKEV1_AUTH_HYBRID_INIT_DSS
= 64223,
295 IKEV1_AUTH_HYBRID_RESP_DSS
= 64224,
296 } ikev1_auth_method_t
;
299 * IKEv1 IPComp transform IDs
302 IKEV1_IPCOMP_OUI
= 1,
303 IKEV1_IPCOMP_DEFLATE
= 2,
304 IKEV1_IPCOMP_LZS
= 3,
305 } ikev1_ipcomp_transform_t
;
307 METHOD(payload_t
, verify
, status_t
,
308 private_proposal_substructure_t
*this)
310 status_t status
= SUCCESS
;
311 enumerator_t
*enumerator
;
314 if (this->next_payload
!= NO_PAYLOAD
&& this->next_payload
!= 2)
317 DBG1(DBG_ENC
, "inconsistent next payload");
320 if (this->transforms_count
!= this->transforms
->get_count(this->transforms
))
322 /* must be the same! */
323 DBG1(DBG_ENC
, "transform count invalid");
327 switch (this->protocol_id
)
330 if (this->spi
.len
!= 2)
332 DBG1(DBG_ENC
, "invalid CPI length in IPCOMP proposal");
338 if (this->spi
.len
!= 4)
340 DBG1(DBG_ENC
, "invalid SPI length in %N proposal",
341 protocol_id_names
, this->protocol_id
);
346 if (this->spi
.len
!= 0 && this->spi
.len
!= 8)
348 DBG1(DBG_ENC
, "invalid SPI length in IKE proposal");
355 enumerator
= this->transforms
->create_enumerator(this->transforms
);
356 while (enumerator
->enumerate(enumerator
, ¤t
))
358 status
= current
->verify(current
);
359 if (status
!= SUCCESS
)
361 DBG1(DBG_ENC
, "TRANSFORM_SUBSTRUCTURE verification failed");
365 enumerator
->destroy(enumerator
);
367 /* proposal number is checked in SA payload */
371 METHOD(payload_t
, get_encoding_rules
, int,
372 private_proposal_substructure_t
*this, encoding_rule_t
**rules
)
374 if (this->type
== PROPOSAL_SUBSTRUCTURE
)
376 *rules
= encodings_v2
;
377 return countof(encodings_v2
);
379 *rules
= encodings_v1
;
380 return countof(encodings_v1
);
383 METHOD(payload_t
, get_header_length
, int,
384 private_proposal_substructure_t
*this)
386 return 8 + this->spi_size
;
389 METHOD(payload_t
, get_type
, payload_type_t
,
390 private_proposal_substructure_t
*this)
395 METHOD(payload_t
, get_next_type
, payload_type_t
,
396 private_proposal_substructure_t
*this)
398 return this->next_payload
;
401 METHOD(payload_t
, set_next_type
, void,
402 private_proposal_substructure_t
*this, payload_type_t type
)
407 * (re-)compute the length of the payload.
409 static void compute_length(private_proposal_substructure_t
*this)
411 enumerator_t
*enumerator
;
412 payload_t
*transform
;
414 this->transforms_count
= 0;
415 this->proposal_length
= get_header_length(this);
416 enumerator
= this->transforms
->create_enumerator(this->transforms
);
417 while (enumerator
->enumerate(enumerator
, &transform
))
419 this->proposal_length
+= transform
->get_length(transform
);
420 this->transforms_count
++;
422 enumerator
->destroy(enumerator
);
425 METHOD(payload_t
, get_length
, size_t,
426 private_proposal_substructure_t
*this)
428 return this->proposal_length
;
432 * Add a transform substructure to the proposal
434 static void add_transform_substructure(private_proposal_substructure_t
*this,
435 transform_substructure_t
*transform
)
437 if (this->transforms
->get_count(this->transforms
) > 0)
439 transform_substructure_t
*last
;
441 this->transforms
->get_last(this->transforms
, (void **)&last
);
442 last
->set_is_last_transform(last
, FALSE
);
444 transform
->set_is_last_transform(transform
,TRUE
);
445 this->transforms
->insert_last(this->transforms
, transform
);
446 compute_length(this);
449 METHOD(proposal_substructure_t
, set_is_last_proposal
, void,
450 private_proposal_substructure_t
*this, bool is_last
)
452 this->next_payload
= is_last
? 0 : PROPOSAL_TYPE_VALUE
;
455 METHOD(proposal_substructure_t
, set_proposal_number
, void,
456 private_proposal_substructure_t
*this,u_int8_t proposal_number
)
458 this->proposal_number
= proposal_number
;
461 METHOD(proposal_substructure_t
, get_proposal_number
, u_int8_t
,
462 private_proposal_substructure_t
*this)
464 return this->proposal_number
;
467 METHOD(proposal_substructure_t
, set_protocol_id
, void,
468 private_proposal_substructure_t
*this,u_int8_t protocol_id
)
470 this->protocol_id
= protocol_id
;
473 METHOD(proposal_substructure_t
, get_protocol_id
, u_int8_t
,
474 private_proposal_substructure_t
*this)
476 return this->protocol_id
;
479 METHOD(proposal_substructure_t
, set_spi
, void,
480 private_proposal_substructure_t
*this, chunk_t spi
)
483 this->spi
= chunk_clone(spi
);
484 this->spi_size
= spi
.len
;
485 compute_length(this);
488 METHOD(proposal_substructure_t
, get_spi
, chunk_t
,
489 private_proposal_substructure_t
*this)
494 METHOD(proposal_substructure_t
, get_cpi
, bool,
495 private_proposal_substructure_t
*this, u_int16_t
*cpi
)
498 transform_substructure_t
*transform
;
499 enumerator_t
*enumerator
;
501 if (this->protocol_id
!= PROTO_IPCOMP
)
506 enumerator
= this->transforms
->create_enumerator(this->transforms
);
507 while (enumerator
->enumerate(enumerator
, &transform
))
509 if (transform
->get_transform_id(transform
) == IKEV1_IPCOMP_DEFLATE
)
513 *cpi
= *((u_int16_t
*)this->spi
.ptr
);
515 enumerator
->destroy(enumerator
);
519 enumerator
->destroy(enumerator
);
524 * Add a transform to a proposal for IKEv2
526 static void add_to_proposal_v2(proposal_t
*proposal
,
527 transform_substructure_t
*transform
)
529 transform_attribute_t
*tattr
;
530 enumerator_t
*enumerator
;
531 u_int16_t key_length
= 0;
533 enumerator
= transform
->create_attribute_enumerator(transform
);
534 while (enumerator
->enumerate(enumerator
, &tattr
))
536 if (tattr
->get_attribute_type(tattr
) == TATTR_IKEV2_KEY_LENGTH
)
538 key_length
= tattr
->get_value(tattr
);
542 enumerator
->destroy(enumerator
);
544 proposal
->add_algorithm(proposal
,
545 transform
->get_transform_type_or_number(transform
),
546 transform
->get_transform_id(transform
), key_length
);
550 * Map IKEv1 to IKEv2 algorithms
558 * Encryption algorithm mapping
560 static algo_map_t map_encr
[] = {
561 { IKEV1_ENCR_DES_CBC
, ENCR_DES
},
562 { IKEV1_ENCR_IDEA_CBC
, ENCR_IDEA
},
563 { IKEV1_ENCR_BLOWFISH_CBC
, ENCR_BLOWFISH
},
564 { IKEV1_ENCR_3DES_CBC
, ENCR_3DES
},
565 { IKEV1_ENCR_CAST_CBC
, ENCR_CAST
},
566 { IKEV1_ENCR_AES_CBC
, ENCR_AES_CBC
},
567 { IKEV1_ENCR_CAMELLIA_CBC
, ENCR_CAMELLIA_CBC
},
568 { IKEV1_ENCR_SERPENT_CBC
, ENCR_SERPENT_CBC
},
569 { IKEV1_ENCR_TWOFISH_CBC
, ENCR_TWOFISH_CBC
},
573 * Integrity algorithm mapping
575 static algo_map_t map_integ
[] = {
576 { IKEV1_HASH_MD5
, AUTH_HMAC_MD5_96
},
577 { IKEV1_HASH_SHA1
, AUTH_HMAC_SHA1_96
},
578 { IKEV1_HASH_SHA2_256
, AUTH_HMAC_SHA2_256_128
},
579 { IKEV1_HASH_SHA2_384
, AUTH_HMAC_SHA2_384_192
},
580 { IKEV1_HASH_SHA2_512
, AUTH_HMAC_SHA2_512_256
},
584 * PRF algorithm mapping
586 static algo_map_t map_prf
[] = {
587 { IKEV1_HASH_MD5
, PRF_HMAC_MD5
},
588 { IKEV1_HASH_SHA1
, PRF_HMAC_SHA1
},
589 { IKEV1_HASH_SHA2_256
, PRF_HMAC_SHA2_256
},
590 { IKEV1_HASH_SHA2_384
, PRF_HMAC_SHA2_384
},
591 { IKEV1_HASH_SHA2_512
, PRF_HMAC_SHA2_512
},
595 * ESP encryption algorithm mapping
597 static algo_map_t map_esp_encr
[] = {
598 { IKEV1_ESP_ENCR_DES_IV64
, ENCR_DES_IV64
},
599 { IKEV1_ESP_ENCR_DES
, ENCR_DES
},
600 { IKEV1_ESP_ENCR_3DES
, ENCR_3DES
},
601 { IKEV1_ESP_ENCR_RC5
, ENCR_RC5
},
602 { IKEV1_ESP_ENCR_IDEA
, ENCR_IDEA
},
603 { IKEV1_ESP_ENCR_CAST
, ENCR_CAST
},
604 { IKEV1_ESP_ENCR_BLOWFISH
, ENCR_BLOWFISH
},
605 { IKEV1_ESP_ENCR_3IDEA
, ENCR_3IDEA
},
606 { IKEV1_ESP_ENCR_DES_IV32
, ENCR_DES_IV32
},
607 { IKEV1_ESP_ENCR_NULL
, ENCR_NULL
},
608 { IKEV1_ESP_ENCR_AES_CBC
, ENCR_AES_CBC
},
609 { IKEV1_ESP_ENCR_AES_CTR
, ENCR_AES_CTR
},
610 { IKEV1_ESP_ENCR_AES_CCM_8
, ENCR_AES_CCM_ICV8
},
611 { IKEV1_ESP_ENCR_AES_CCM_12
, ENCR_AES_CCM_ICV12
},
612 { IKEV1_ESP_ENCR_AES_CCM_16
, ENCR_AES_CCM_ICV16
},
613 { IKEV1_ESP_ENCR_AES_GCM_8
, ENCR_AES_GCM_ICV8
},
614 { IKEV1_ESP_ENCR_AES_GCM_12
, ENCR_AES_GCM_ICV12
},
615 { IKEV1_ESP_ENCR_AES_GCM_16
, ENCR_AES_GCM_ICV16
},
616 { IKEV1_ESP_ENCR_CAMELLIA
, ENCR_CAMELLIA_CBC
},
617 { IKEV1_ESP_ENCR_NULL_AUTH_AES_GMAC
, ENCR_NULL_AUTH_AES_GMAC
},
618 { IKEV1_ESP_ENCR_SERPENT
, ENCR_SERPENT_CBC
},
619 { IKEV1_ESP_ENCR_TWOFISH
, ENCR_TWOFISH_CBC
},
623 * ESP authentication algorithm mapping
625 static algo_map_t map_esp_auth
[] = {
626 { IKEV1_ESP_AUTH_HMAC_MD5
, AUTH_HMAC_MD5_96
},
627 { IKEV1_ESP_AUTH_HMAC_SHA
, AUTH_HMAC_SHA1_96
},
628 { IKEV1_ESP_AUTH_DES_MAC
, AUTH_DES_MAC
},
629 { IKEV1_ESP_AUTH_KPDK
, AUTH_KPDK_MD5
},
630 { IKEV1_ESP_AUTH_HMAC_SHA2_256
, AUTH_HMAC_SHA2_256_128
},
631 { IKEV1_ESP_AUTH_HMAC_SHA2_384
, AUTH_HMAC_SHA2_384_192
},
632 { IKEV1_ESP_AUTH_HMAC_SHA2_512
, AUTH_HMAC_SHA2_512_256
},
633 { IKEV1_ESP_AUTH_AES_XCBC_MAC
, AUTH_AES_XCBC_96
},
634 { IKEV1_ESP_AUTH_AES_128_GMAC
, AUTH_AES_128_GMAC
},
635 { IKEV1_ESP_AUTH_AES_192_GMAC
, AUTH_AES_192_GMAC
},
636 { IKEV1_ESP_AUTH_AES_256_GMAC
, AUTH_AES_256_GMAC
},
640 * Get IKEv2 algorithm from IKEv1 identifier
642 static u_int16_t
get_alg_from_ikev1(transform_type_t type
, u_int16_t value
)
650 case ENCRYPTION_ALGORITHM
:
652 count
= countof(map_encr
);
653 def
= ENCR_UNDEFINED
;
655 case INTEGRITY_ALGORITHM
:
657 count
= countof(map_integ
);
658 def
= AUTH_UNDEFINED
;
660 case PSEUDO_RANDOM_FUNCTION
:
662 count
= countof(map_prf
);
668 for (i
= 0; i
< count
; i
++)
670 if (map
[i
].ikev1
== value
)
679 * Get IKEv1 algorithm from IKEv2 identifier
681 static u_int16_t
get_ikev1_from_alg(transform_type_t type
, u_int16_t value
)
688 case ENCRYPTION_ALGORITHM
:
690 count
= countof(map_encr
);
692 case INTEGRITY_ALGORITHM
:
694 count
= countof(map_integ
);
696 case PSEUDO_RANDOM_FUNCTION
:
698 count
= countof(map_prf
);
703 for (i
= 0; i
< count
; i
++)
705 if (map
[i
].ikev2
== value
)
714 * Get IKEv2 algorithm from IKEv1 ESP transaction ID
716 static u_int16_t
get_alg_from_ikev1_transid(transform_type_t type
, u_int16_t value
)
724 case ENCRYPTION_ALGORITHM
:
726 count
= countof(map_esp_encr
);
727 def
= ENCR_UNDEFINED
;
729 case INTEGRITY_ALGORITHM
:
731 count
= countof(map_esp_auth
);
732 def
= AUTH_UNDEFINED
;
737 for (i
= 0; i
< count
; i
++)
739 if (map
[i
].ikev1
== value
)
748 * Get IKEv1 ESP transaction ID from IKEv2 identifier
750 static u_int16_t
get_ikev1_transid_from_alg(transform_type_t type
, u_int16_t value
)
757 case ENCRYPTION_ALGORITHM
:
759 count
= countof(map_esp_encr
);
761 case INTEGRITY_ALGORITHM
:
763 count
= countof(map_esp_auth
);
768 for (i
= 0; i
< count
; i
++)
770 if (map
[i
].ikev2
== value
)
778 * Get IKEv1 authentication attribute from auth_method_t
780 static u_int16_t
get_ikev1_auth(auth_method_t method
)
785 return IKEV1_AUTH_RSA_SIG
;
787 return IKEV1_AUTH_DSS_SIG
;
788 case AUTH_XAUTH_INIT_PSK
:
789 return IKEV1_AUTH_XAUTH_INIT_PSK
;
790 case AUTH_XAUTH_RESP_PSK
:
791 return IKEV1_AUTH_XAUTH_RESP_PSK
;
792 case AUTH_XAUTH_INIT_RSA
:
793 return IKEV1_AUTH_XAUTH_INIT_RSA
;
794 case AUTH_XAUTH_RESP_RSA
:
795 return IKEV1_AUTH_XAUTH_RESP_RSA
;
796 case AUTH_HYBRID_INIT_RSA
:
797 return IKEV1_AUTH_HYBRID_INIT_RSA
;
798 case AUTH_HYBRID_RESP_RSA
:
799 return IKEV1_AUTH_HYBRID_RESP_RSA
;
801 return IKEV1_AUTH_ECDSA_256
;
803 return IKEV1_AUTH_ECDSA_384
;
805 return IKEV1_AUTH_ECDSA_521
;
808 return IKEV1_AUTH_PSK
;
813 * Get IKEv1 encapsulation mode
815 static u_int16_t
get_ikev1_mode(ipsec_mode_t mode
, encap_t udp
)
823 return IKEV1_ENCAP_UDP_TUNNEL
;
824 case ENCAP_UDP_DRAFT_00_03
:
825 return IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03
;
827 return IKEV1_ENCAP_TUNNEL
;
833 return IKEV1_ENCAP_UDP_TRANSPORT
;
834 case ENCAP_UDP_DRAFT_00_03
:
835 return IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03
;
837 return IKEV1_ENCAP_TRANSPORT
;
840 return IKEV1_ENCAP_TUNNEL
;
845 * Add an IKE transform to a proposal for IKEv1
847 static void add_to_proposal_v1_ike(proposal_t
*proposal
,
848 transform_substructure_t
*transform
)
850 transform_attribute_type_t type
;
851 transform_attribute_t
*tattr
;
852 enumerator_t
*enumerator
;
853 u_int16_t value
, key_length
= 0;
854 u_int16_t encr
= ENCR_UNDEFINED
;
856 enumerator
= transform
->create_attribute_enumerator(transform
);
857 while (enumerator
->enumerate(enumerator
, &tattr
))
859 type
= tattr
->get_attribute_type(tattr
);
860 value
= tattr
->get_value(tattr
);
863 case TATTR_PH1_ENCRYPTION_ALGORITHM
:
864 encr
= get_alg_from_ikev1(ENCRYPTION_ALGORITHM
, value
);
866 case TATTR_PH1_KEY_LENGTH
:
869 case TATTR_PH1_HASH_ALGORITHM
:
870 proposal
->add_algorithm(proposal
, INTEGRITY_ALGORITHM
,
871 get_alg_from_ikev1(INTEGRITY_ALGORITHM
, value
), 0);
872 proposal
->add_algorithm(proposal
, PSEUDO_RANDOM_FUNCTION
,
873 get_alg_from_ikev1(PSEUDO_RANDOM_FUNCTION
, value
), 0);
875 case TATTR_PH1_GROUP
:
876 proposal
->add_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
,
883 enumerator
->destroy(enumerator
);
885 if (encr
!= ENCR_UNDEFINED
)
887 proposal
->add_algorithm(proposal
, ENCRYPTION_ALGORITHM
, encr
, key_length
);
892 * Add an ESP transform to a proposal for IKEv1
894 static void add_to_proposal_v1_esp(proposal_t
*proposal
,
895 transform_substructure_t
*transform
)
897 transform_attribute_type_t type
;
898 transform_attribute_t
*tattr
;
899 enumerator_t
*enumerator
;
900 u_int16_t encr
, value
, key_length
= 0;
902 enumerator
= transform
->create_attribute_enumerator(transform
);
903 while (enumerator
->enumerate(enumerator
, &tattr
))
905 type
= tattr
->get_attribute_type(tattr
);
906 value
= tattr
->get_value(tattr
);
909 case TATTR_PH2_KEY_LENGTH
:
912 case TATTR_PH2_AUTH_ALGORITHM
:
913 proposal
->add_algorithm(proposal
, INTEGRITY_ALGORITHM
,
914 get_alg_from_ikev1_transid(INTEGRITY_ALGORITHM
,
917 case TATTR_PH2_GROUP
:
918 proposal
->add_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
,
925 enumerator
->destroy(enumerator
);
927 /* TODO-IKEv1: handle ESN attribute */
928 proposal
->add_algorithm(proposal
, EXTENDED_SEQUENCE_NUMBERS
,
929 NO_EXT_SEQ_NUMBERS
, 0);
930 encr
= get_alg_from_ikev1_transid(ENCRYPTION_ALGORITHM
,
931 transform
->get_transform_id(transform
));
934 proposal
->add_algorithm(proposal
, ENCRYPTION_ALGORITHM
, encr
,
939 METHOD(proposal_substructure_t
, get_proposals
, void,
940 private_proposal_substructure_t
*this, linked_list_t
*proposals
)
942 transform_substructure_t
*transform
;
943 enumerator_t
*enumerator
;
944 proposal_t
*proposal
= NULL
;
947 switch (this->spi
.len
)
950 spi
= *((u_int32_t
*)this->spi
.ptr
);
953 spi
= *((u_int64_t
*)this->spi
.ptr
);
959 enumerator
= this->transforms
->create_enumerator(this->transforms
);
960 while (enumerator
->enumerate(enumerator
, &transform
))
964 proposal
= proposal_create(this->protocol_id
, this->proposal_number
);
965 proposal
->set_spi(proposal
, spi
);
966 proposals
->insert_last(proposals
, proposal
);
968 if (this->type
== PROPOSAL_SUBSTRUCTURE
)
970 add_to_proposal_v2(proposal
, transform
);
974 switch (this->protocol_id
)
977 add_to_proposal_v1_ike(proposal
, transform
);
980 add_to_proposal_v1_esp(proposal
, transform
);
985 /* create a new proposal for each transform in IKEv1 */
989 enumerator
->destroy(enumerator
);
992 METHOD(proposal_substructure_t
, create_substructure_enumerator
, enumerator_t
*,
993 private_proposal_substructure_t
*this)
995 return this->transforms
->create_enumerator(this->transforms
);
999 * Get an attribute from any transform, 0 if not found
1001 static u_int64_t
get_attr(private_proposal_substructure_t
*this,
1002 transform_attribute_type_t type
)
1004 enumerator_t
*transforms
, *attributes
;
1005 transform_substructure_t
*transform
;
1006 transform_attribute_t
*attr
;
1008 transforms
= this->transforms
->create_enumerator(this->transforms
);
1009 while (transforms
->enumerate(transforms
, &transform
))
1011 attributes
= transform
->create_attribute_enumerator(transform
);
1012 while (attributes
->enumerate(attributes
, &attr
))
1014 if (attr
->get_attribute_type(attr
) == type
)
1016 attributes
->destroy(attributes
);
1017 transforms
->destroy(transforms
);
1018 return attr
->get_value(attr
);
1021 attributes
->destroy(attributes
);
1023 transforms
->destroy(transforms
);
1028 * Look up a lifetime duration of a given kind in all transforms
1030 static u_int64_t
get_life_duration(private_proposal_substructure_t
*this,
1031 transform_attribute_type_t type_attr
, ikev1_life_type_t type
,
1032 transform_attribute_type_t dur_attr
)
1034 enumerator_t
*transforms
, *attributes
;
1035 transform_substructure_t
*transform
;
1036 transform_attribute_t
*attr
;
1038 transforms
= this->transforms
->create_enumerator(this->transforms
);
1039 while (transforms
->enumerate(transforms
, &transform
))
1041 attributes
= transform
->create_attribute_enumerator(transform
);
1042 while (attributes
->enumerate(attributes
, &attr
))
1044 if (attr
->get_attribute_type(attr
) == type_attr
&&
1045 attr
->get_value(attr
) == type
)
1046 { /* got type attribute, look for duration following next */
1047 while (attributes
->enumerate(attributes
, &attr
))
1049 if (attr
->get_attribute_type(attr
) == dur_attr
)
1051 attributes
->destroy(attributes
);
1052 transforms
->destroy(transforms
);
1053 return attr
->get_value(attr
);
1058 attributes
->destroy(attributes
);
1060 transforms
->destroy(transforms
);
1064 METHOD(proposal_substructure_t
, get_lifetime
, u_int32_t
,
1065 private_proposal_substructure_t
*this)
1069 switch (this->protocol_id
)
1072 return get_life_duration(this, TATTR_PH1_LIFE_TYPE
,
1073 IKEV1_LIFE_TYPE_SECONDS
, TATTR_PH1_LIFE_DURATION
);
1075 duration
= get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE
,
1076 IKEV1_LIFE_TYPE_SECONDS
, TATTR_PH2_SA_LIFE_DURATION
);
1078 { /* default to 8 hours, RFC 2407 */
1087 METHOD(proposal_substructure_t
, get_lifebytes
, u_int64_t
,
1088 private_proposal_substructure_t
*this)
1090 switch (this->protocol_id
)
1093 return 1000 * get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE
,
1094 IKEV1_LIFE_TYPE_KILOBYTES
, TATTR_PH2_SA_LIFE_DURATION
);
1101 METHOD(proposal_substructure_t
, get_auth_method
, auth_method_t
,
1102 private_proposal_substructure_t
*this)
1104 switch (get_attr(this, TATTR_PH1_AUTH_METHOD
))
1106 case IKEV1_AUTH_PSK
:
1108 case IKEV1_AUTH_RSA_SIG
:
1110 case IKEV1_AUTH_DSS_SIG
:
1112 case IKEV1_AUTH_XAUTH_INIT_PSK
:
1113 return AUTH_XAUTH_INIT_PSK
;
1114 case IKEV1_AUTH_XAUTH_RESP_PSK
:
1115 return AUTH_XAUTH_RESP_PSK
;
1116 case IKEV1_AUTH_XAUTH_INIT_RSA
:
1117 return AUTH_XAUTH_INIT_RSA
;
1118 case IKEV1_AUTH_XAUTH_RESP_RSA
:
1119 return AUTH_XAUTH_RESP_RSA
;
1120 case IKEV1_AUTH_HYBRID_INIT_RSA
:
1121 return AUTH_HYBRID_INIT_RSA
;
1122 case IKEV1_AUTH_HYBRID_RESP_RSA
:
1123 return AUTH_HYBRID_RESP_RSA
;
1124 case IKEV1_AUTH_ECDSA_256
:
1125 return AUTH_ECDSA_256
;
1126 case IKEV1_AUTH_ECDSA_384
:
1127 return AUTH_ECDSA_384
;
1128 case IKEV1_AUTH_ECDSA_521
:
1129 return AUTH_ECDSA_521
;
1135 METHOD(proposal_substructure_t
, get_encap_mode
, ipsec_mode_t
,
1136 private_proposal_substructure_t
*this, bool *udp
)
1139 switch (get_attr(this, TATTR_PH2_ENCAP_MODE
))
1141 case IKEV1_ENCAP_TRANSPORT
:
1142 return MODE_TRANSPORT
;
1143 case IKEV1_ENCAP_TUNNEL
:
1145 case IKEV1_ENCAP_UDP_TRANSPORT
:
1146 case IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03
:
1148 return MODE_TRANSPORT
;
1149 case IKEV1_ENCAP_UDP_TUNNEL
:
1150 case IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03
:
1154 /* default to TUNNEL, RFC 2407 says implementation specific */
1159 METHOD2(payload_t
, proposal_substructure_t
, destroy
, void,
1160 private_proposal_substructure_t
*this)
1162 this->transforms
->destroy_offset(this->transforms
,
1163 offsetof(payload_t
, destroy
));
1164 chunk_free(&this->spi
);
1169 * Described in header.
1171 proposal_substructure_t
*proposal_substructure_create(payload_type_t type
)
1173 private_proposal_substructure_t
*this;
1177 .payload_interface
= {
1179 .get_encoding_rules
= _get_encoding_rules
,
1180 .get_header_length
= _get_header_length
,
1181 .get_length
= _get_length
,
1182 .get_next_type
= _get_next_type
,
1183 .set_next_type
= _set_next_type
,
1184 .get_type
= _get_type
,
1185 .destroy
= _destroy
,
1187 .set_proposal_number
= _set_proposal_number
,
1188 .get_proposal_number
= _get_proposal_number
,
1189 .set_protocol_id
= _set_protocol_id
,
1190 .get_protocol_id
= _get_protocol_id
,
1191 .set_is_last_proposal
= _set_is_last_proposal
,
1192 .get_proposals
= _get_proposals
,
1193 .create_substructure_enumerator
= _create_substructure_enumerator
,
1194 .set_spi
= _set_spi
,
1195 .get_spi
= _get_spi
,
1196 .get_cpi
= _get_cpi
,
1197 .get_lifetime
= _get_lifetime
,
1198 .get_lifebytes
= _get_lifebytes
,
1199 .get_auth_method
= _get_auth_method
,
1200 .get_encap_mode
= _get_encap_mode
,
1201 .destroy
= _destroy
,
1203 .next_payload
= NO_PAYLOAD
,
1204 .transforms
= linked_list_create(),
1207 compute_length(this);
1209 return &this->public;
1213 * Add an IKEv1 IKE proposal to the substructure
1215 static void set_from_proposal_v1_ike(private_proposal_substructure_t
*this,
1216 proposal_t
*proposal
, u_int32_t lifetime
,
1217 auth_method_t method
, int number
)
1219 transform_substructure_t
*transform
;
1220 u_int16_t alg
, key_size
;
1221 enumerator_t
*enumerator
;
1223 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1
,
1224 number
, IKEV1_TRANSID_KEY_IKE
);
1226 enumerator
= proposal
->create_enumerator(proposal
, ENCRYPTION_ALGORITHM
);
1227 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1229 alg
= get_ikev1_from_alg(ENCRYPTION_ALGORITHM
, alg
);
1232 transform
->add_transform_attribute(transform
,
1233 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1234 TATTR_PH1_ENCRYPTION_ALGORITHM
, alg
));
1237 transform
->add_transform_attribute(transform
,
1238 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1239 TATTR_PH1_KEY_LENGTH
, key_size
));
1243 enumerator
->destroy(enumerator
);
1245 /* encode the integrity algorithm as hash and assume use the same PRF */
1246 enumerator
= proposal
->create_enumerator(proposal
, INTEGRITY_ALGORITHM
);
1247 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1249 alg
= get_ikev1_from_alg(INTEGRITY_ALGORITHM
, alg
);
1252 transform
->add_transform_attribute(transform
,
1253 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1254 TATTR_PH1_HASH_ALGORITHM
, alg
));
1257 enumerator
->destroy(enumerator
);
1259 enumerator
= proposal
->create_enumerator(proposal
, DIFFIE_HELLMAN_GROUP
);
1260 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1262 transform
->add_transform_attribute(transform
,
1263 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1264 TATTR_PH1_GROUP
, alg
));
1266 enumerator
->destroy(enumerator
);
1268 transform
->add_transform_attribute(transform
,
1269 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1270 TATTR_PH1_AUTH_METHOD
, get_ikev1_auth(method
)));
1271 transform
->add_transform_attribute(transform
,
1272 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1273 TATTR_PH1_LIFE_TYPE
, IKEV1_LIFE_TYPE_SECONDS
));
1274 transform
->add_transform_attribute(transform
,
1275 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1276 TATTR_PH1_LIFE_DURATION
, lifetime
));
1278 add_transform_substructure(this, transform
);
1282 * Add an IKEv1 ESP proposal to the substructure
1284 static void set_from_proposal_v1_esp(private_proposal_substructure_t
*this,
1285 proposal_t
*proposal
, u_int32_t lifetime
, u_int64_t lifebytes
,
1286 ipsec_mode_t mode
, encap_t udp
, int number
)
1288 transform_substructure_t
*transform
= NULL
;
1289 u_int16_t alg
, key_size
;
1290 enumerator_t
*enumerator
;
1292 enumerator
= proposal
->create_enumerator(proposal
, ENCRYPTION_ALGORITHM
);
1293 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1295 alg
= get_ikev1_transid_from_alg(ENCRYPTION_ALGORITHM
, alg
);
1298 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1
,
1302 transform
->add_transform_attribute(transform
,
1303 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1304 TATTR_PH2_KEY_LENGTH
, key_size
));
1308 enumerator
->destroy(enumerator
);
1314 enumerator
= proposal
->create_enumerator(proposal
, INTEGRITY_ALGORITHM
);
1315 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1317 alg
= get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM
, alg
);
1320 transform
->add_transform_attribute(transform
,
1321 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1322 TATTR_PH2_AUTH_ALGORITHM
, alg
));
1325 enumerator
->destroy(enumerator
);
1327 enumerator
= proposal
->create_enumerator(proposal
, DIFFIE_HELLMAN_GROUP
);
1328 if (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1330 transform
->add_transform_attribute(transform
,
1331 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1332 TATTR_PH2_GROUP
, alg
));
1334 enumerator
->destroy(enumerator
);
1336 transform
->add_transform_attribute(transform
,
1337 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1338 TATTR_PH2_ENCAP_MODE
, get_ikev1_mode(mode
, udp
)));
1341 transform
->add_transform_attribute(transform
,
1342 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1343 TATTR_PH2_SA_LIFE_TYPE
, IKEV1_LIFE_TYPE_SECONDS
));
1344 transform
->add_transform_attribute(transform
,
1345 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1346 TATTR_PH2_SA_LIFE_DURATION
, lifetime
));
1350 transform
->add_transform_attribute(transform
,
1351 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1352 TATTR_PH2_SA_LIFE_TYPE
, IKEV1_LIFE_TYPE_KILOBYTES
));
1353 transform
->add_transform_attribute(transform
,
1354 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1355 TATTR_PH2_SA_LIFE_DURATION
, lifebytes
/ 1000));
1358 add_transform_substructure(this, transform
);
1362 * Add an IKEv2 proposal to the substructure
1364 static void set_from_proposal_v2(private_proposal_substructure_t
*this,
1365 proposal_t
*proposal
)
1367 transform_substructure_t
*transform
;
1368 u_int16_t alg
, key_size
;
1369 enumerator_t
*enumerator
;
1371 /* encryption algorithm is only available in ESP */
1372 enumerator
= proposal
->create_enumerator(proposal
, ENCRYPTION_ALGORITHM
);
1373 while (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1375 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1376 ENCRYPTION_ALGORITHM
, alg
);
1379 transform
->add_transform_attribute(transform
,
1380 transform_attribute_create_value(TRANSFORM_ATTRIBUTE
,
1381 TATTR_IKEV2_KEY_LENGTH
, key_size
));
1383 add_transform_substructure(this, transform
);
1385 enumerator
->destroy(enumerator
);
1387 /* integrity algorithms */
1388 enumerator
= proposal
->create_enumerator(proposal
, INTEGRITY_ALGORITHM
);
1389 while (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1391 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1392 INTEGRITY_ALGORITHM
, alg
);
1393 add_transform_substructure(this, transform
);
1395 enumerator
->destroy(enumerator
);
1397 /* prf algorithms */
1398 enumerator
= proposal
->create_enumerator(proposal
, PSEUDO_RANDOM_FUNCTION
);
1399 while (enumerator
->enumerate(enumerator
, &alg
, &key_size
))
1401 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1402 PSEUDO_RANDOM_FUNCTION
, alg
);
1403 add_transform_substructure(this, transform
);
1405 enumerator
->destroy(enumerator
);
1408 enumerator
= proposal
->create_enumerator(proposal
, DIFFIE_HELLMAN_GROUP
);
1409 while (enumerator
->enumerate(enumerator
, &alg
, NULL
))
1411 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1412 DIFFIE_HELLMAN_GROUP
, alg
);
1413 add_transform_substructure(this, transform
);
1415 enumerator
->destroy(enumerator
);
1417 /* extended sequence numbers */
1418 enumerator
= proposal
->create_enumerator(proposal
, EXTENDED_SEQUENCE_NUMBERS
);
1419 while (enumerator
->enumerate(enumerator
, &alg
, NULL
))
1421 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE
,
1422 EXTENDED_SEQUENCE_NUMBERS
, alg
);
1423 add_transform_substructure(this, transform
);
1425 enumerator
->destroy(enumerator
);
1429 * Set SPI and other data from proposal, compute length
1431 static void set_data(private_proposal_substructure_t
*this, proposal_t
*proposal
)
1436 /* add SPI, if necessary */
1437 switch (proposal
->get_protocol(proposal
))
1441 spi32
= proposal
->get_spi(proposal
);
1442 this->spi
= chunk_clone(chunk_from_thing(spi32
));
1443 this->spi_size
= this->spi
.len
;
1446 spi64
= proposal
->get_spi(proposal
);
1448 { /* IKE only uses SPIS when rekeying, but on initial setup */
1449 this->spi
= chunk_clone(chunk_from_thing(spi64
));
1450 this->spi_size
= this->spi
.len
;
1456 this->proposal_number
= proposal
->get_number(proposal
);
1457 this->protocol_id
= proposal
->get_protocol(proposal
);
1458 compute_length(this);
1462 * Described in header.
1464 proposal_substructure_t
*proposal_substructure_create_from_proposal_v2(
1465 proposal_t
*proposal
)
1467 private_proposal_substructure_t
*this;
1469 this = (private_proposal_substructure_t
*)
1470 proposal_substructure_create(SECURITY_ASSOCIATION
);
1471 set_from_proposal_v2(this, proposal
);
1472 set_data(this, proposal
);
1474 return &this->public;
1480 proposal_substructure_t
*proposal_substructure_create_from_proposal_v1(
1481 proposal_t
*proposal
, u_int32_t lifetime
, u_int64_t lifebytes
,
1482 auth_method_t auth
, ipsec_mode_t mode
, encap_t udp
)
1484 private_proposal_substructure_t
*this;
1486 this = (private_proposal_substructure_t
*)
1487 proposal_substructure_create(PROPOSAL_SUBSTRUCTURE_V1
);
1488 switch (proposal
->get_protocol(proposal
))
1491 set_from_proposal_v1_ike(this, proposal
, lifetime
, auth
, 1);
1494 set_from_proposal_v1_esp(this, proposal
, lifetime
,
1495 lifebytes
, mode
, udp
, 1);
1500 set_data(this, proposal
);
1502 return &this->public;
1508 proposal_substructure_t
*proposal_substructure_create_from_proposals_v1(
1509 linked_list_t
*proposals
, u_int32_t lifetime
, u_int64_t lifebytes
,
1510 auth_method_t auth
, ipsec_mode_t mode
, encap_t udp
)
1512 private_proposal_substructure_t
*this = NULL
;
1513 enumerator_t
*enumerator
;
1514 proposal_t
*proposal
;
1517 enumerator
= proposals
->create_enumerator(proposals
);
1518 while (enumerator
->enumerate(enumerator
, &proposal
))
1522 this = (private_proposal_substructure_t
*)
1523 proposal_substructure_create_from_proposal_v1(
1524 proposal
, lifetime
, lifebytes
, auth
, mode
, udp
);
1529 switch (proposal
->get_protocol(proposal
))
1532 set_from_proposal_v1_ike(this, proposal
, lifetime
,
1536 set_from_proposal_v1_esp(this, proposal
, lifetime
,
1537 lifebytes
, mode
, udp
, ++number
);
1544 enumerator
->destroy(enumerator
);
1546 return &this->public;
1552 proposal_substructure_t
*proposal_substructure_create_for_ipcomp_v1(
1553 u_int32_t lifetime
, u_int64_t lifebytes
, u_int16_t cpi
,
1554 ipsec_mode_t mode
, encap_t udp
, u_int8_t proposal_number
)
1556 private_proposal_substructure_t
*this;
1557 transform_substructure_t
*transform
;
1560 this = (private_proposal_substructure_t
*)
1561 proposal_substructure_create(PROPOSAL_SUBSTRUCTURE_V1
);
1563 /* we currently support DEFLATE only */
1564 transform
= transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1
,
1565 1, IKEV1_IPCOMP_DEFLATE
);
1567 transform
->add_transform_attribute(transform
,
1568 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1569 TATTR_PH2_ENCAP_MODE
, get_ikev1_mode(mode
, udp
)));
1572 transform
->add_transform_attribute(transform
,
1573 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1574 TATTR_PH2_SA_LIFE_TYPE
, IKEV1_LIFE_TYPE_SECONDS
));
1575 transform
->add_transform_attribute(transform
,
1576 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1577 TATTR_PH2_SA_LIFE_DURATION
, lifetime
));
1581 transform
->add_transform_attribute(transform
,
1582 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1583 TATTR_PH2_SA_LIFE_TYPE
, IKEV1_LIFE_TYPE_KILOBYTES
));
1584 transform
->add_transform_attribute(transform
,
1585 transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1
,
1586 TATTR_PH2_SA_LIFE_DURATION
, lifebytes
/ 1000));
1589 add_transform_substructure(this, transform
);
1591 this->spi
= chunk_clone(chunk_from_thing(cpi
));
1592 this->spi_size
= this->spi
.len
;
1593 this->protocol_id
= PROTO_IPCOMP
;
1594 this->proposal_number
= proposal_number
;
1596 compute_length(this);
1598 return &this->public;