2 * Copyright (C) 2008 Tobias Brunner
3 * Copyright (C) 2006 Martin Willi
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
24 #include <utils/linked_list.h>
25 #include <utils/identification.h>
26 #include <utils/lexparser.h>
27 #include <crypto/prfs/prf.h>
28 #include <crypto/crypters/crypter.h>
29 #include <crypto/signers/signer.h>
32 ENUM(protocol_id_names
, PROTO_NONE
, PROTO_ESP
,
39 ENUM_BEGIN(transform_type_names
, UNDEFINED_TRANSFORM_TYPE
, UNDEFINED_TRANSFORM_TYPE
,
40 "UNDEFINED_TRANSFORM_TYPE");
41 ENUM_NEXT(transform_type_names
, ENCRYPTION_ALGORITHM
, EXTENDED_SEQUENCE_NUMBERS
, UNDEFINED_TRANSFORM_TYPE
,
42 "ENCRYPTION_ALGORITHM",
43 "PSEUDO_RANDOM_FUNCTION",
44 "INTEGRITY_ALGORITHM",
45 "DIFFIE_HELLMAN_GROUP",
46 "EXTENDED_SEQUENCE_NUMBERS");
47 ENUM_END(transform_type_names
, EXTENDED_SEQUENCE_NUMBERS
);
49 ENUM(extended_sequence_numbers_names
, NO_EXT_SEQ_NUMBERS
, EXT_SEQ_NUMBERS
,
54 typedef struct private_proposal_t private_proposal_t
;
55 typedef struct algorithm_t algorithm_t
;
58 * Private data of an proposal_t object
60 struct private_proposal_t
{
68 * protocol (ESP or AH)
70 protocol_id_t protocol
;
73 * priority ordered list of encryption algorithms
75 linked_list_t
*encryption_algos
;
78 * priority ordered list of integrity algorithms
80 linked_list_t
*integrity_algos
;
83 * priority ordered list of pseudo random functions
85 linked_list_t
*prf_algos
;
88 * priority ordered list of dh groups
90 linked_list_t
*dh_groups
;
93 * priority ordered list of extended sequence number flags
104 * Struct used to store different kinds of algorithms.
108 * Value from an encryption_algorithm_t/integrity_algorithm_t/...
113 * the associated key size in bits, or zero if not needed
119 * Add algorithm/keysize to a algorithm list
121 static void add_algo(linked_list_t
*list
, u_int16_t algo
, u_int16_t key_size
)
123 algorithm_t
*algo_key
;
125 algo_key
= malloc_thing(algorithm_t
);
126 algo_key
->algorithm
= algo
;
127 algo_key
->key_size
= key_size
;
128 list
->insert_last(list
, (void*)algo_key
);
132 * Implements proposal_t.add_algorithm
134 static void add_algorithm(private_proposal_t
*this, transform_type_t type
,
135 u_int16_t algo
, u_int16_t key_size
)
139 case ENCRYPTION_ALGORITHM
:
140 add_algo(this->encryption_algos
, algo
, key_size
);
142 case INTEGRITY_ALGORITHM
:
143 add_algo(this->integrity_algos
, algo
, key_size
);
145 case PSEUDO_RANDOM_FUNCTION
:
146 add_algo(this->prf_algos
, algo
, key_size
);
148 case DIFFIE_HELLMAN_GROUP
:
149 add_algo(this->dh_groups
, algo
, 0);
151 case EXTENDED_SEQUENCE_NUMBERS
:
152 add_algo(this->esns
, algo
, 0);
160 * filter function for peer configs
162 static bool alg_filter(void *null
, algorithm_t
**in
, u_int16_t
*alg
,
163 void **unused
, u_int16_t
*key_size
)
165 algorithm_t
*algo
= *in
;
166 *alg
= algo
->algorithm
;
169 *key_size
= algo
->key_size
;
175 * Implements proposal_t.create_enumerator.
177 static enumerator_t
*create_enumerator(private_proposal_t
*this,
178 transform_type_t type
)
184 case ENCRYPTION_ALGORITHM
:
185 list
= this->encryption_algos
;
187 case INTEGRITY_ALGORITHM
:
188 list
= this->integrity_algos
;
190 case PSEUDO_RANDOM_FUNCTION
:
191 list
= this->prf_algos
;
193 case DIFFIE_HELLMAN_GROUP
:
194 list
= this->dh_groups
;
196 case EXTENDED_SEQUENCE_NUMBERS
:
202 return enumerator_create_filter(list
->create_enumerator(list
),
203 (void*)alg_filter
, NULL
, NULL
);
207 * Implements proposal_t.get_algorithm.
209 static bool get_algorithm(private_proposal_t
*this, transform_type_t type
,
210 u_int16_t
*alg
, u_int16_t
*key_size
)
212 enumerator_t
*enumerator
;
215 enumerator
= create_enumerator(this, type
);
216 if (enumerator
->enumerate(enumerator
, alg
, key_size
))
220 enumerator
->destroy(enumerator
);
225 * Implements proposal_t.has_dh_group
227 static bool has_dh_group(private_proposal_t
*this, diffie_hellman_group_t group
)
231 if (this->dh_groups
->get_count(this->dh_groups
))
233 algorithm_t
*current
;
234 enumerator_t
*enumerator
;
236 enumerator
= this->dh_groups
->create_enumerator(this->dh_groups
);
237 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
239 if (current
->algorithm
== group
)
245 enumerator
->destroy(enumerator
);
247 else if (group
== MODP_NONE
)
255 * Implementation of proposal_t.strip_dh.
257 static void strip_dh(private_proposal_t
*this)
261 while (this->dh_groups
->remove_last(this->dh_groups
, (void**)&alg
) == SUCCESS
)
268 * Returns true if the given alg is an authenticated encryption algorithm
270 static bool is_authenticated_encryption(u_int16_t alg
)
274 case ENCR_AES_CCM_ICV8
:
275 case ENCR_AES_CCM_ICV12
:
276 case ENCR_AES_CCM_ICV16
:
277 case ENCR_AES_GCM_ICV8
:
278 case ENCR_AES_GCM_ICV12
:
279 case ENCR_AES_GCM_ICV16
:
286 * Find a matching alg/keysize in two linked lists
288 static bool select_algo(linked_list_t
*first
, linked_list_t
*second
, bool *add
,
289 u_int16_t
*alg
, size_t *key_size
)
291 enumerator_t
*e1
, *e2
;
292 algorithm_t
*alg1
, *alg2
;
294 /* if in both are zero algorithms specified, we HAVE a match */
295 if (first
->get_count(first
) == 0 && second
->get_count(second
) == 0)
301 e1
= first
->create_enumerator(first
);
302 e2
= second
->create_enumerator(second
);
303 /* compare algs, order of algs in "first" is preferred */
304 while (e1
->enumerate(e1
, &alg1
))
307 e2
= second
->create_enumerator(second
);
308 while (e2
->enumerate(e2
, &alg2
))
310 if (alg1
->algorithm
== alg2
->algorithm
&&
311 alg1
->key_size
== alg2
->key_size
)
313 /* ok, we have an algorithm */
314 *alg
= alg1
->algorithm
;
315 *key_size
= alg1
->key_size
;
323 /* no match in all comparisons */
330 * Implements proposal_t.select.
332 static proposal_t
*select_proposal(private_proposal_t
*this, private_proposal_t
*other
)
334 proposal_t
*selected
;
339 DBG2(DBG_CFG
, "selecting proposal:");
342 if (this->protocol
!= other
->protocol
)
344 DBG2(DBG_CFG
, " protocol mismatch, skipping");
348 selected
= proposal_create(this->protocol
);
350 /* select encryption algorithm */
351 if (select_algo(this->encryption_algos
, other
->encryption_algos
, &add
, &algo
, &key_size
))
355 selected
->add_algorithm(selected
, ENCRYPTION_ALGORITHM
, algo
, key_size
);
363 selected
->destroy(selected
);
364 DBG2(DBG_CFG
, " no acceptable ENCRYPTION_ALGORITHM found");
365 DBG2(DBG_CFG
, " list of received ENCRYPTION_ALGORITHM proposals:");
366 e
= other
->encryption_algos
->create_enumerator(other
->encryption_algos
);
367 while (e
->enumerate(e
, &alg
))
369 DBG2(DBG_CFG
, " %N-%d", encryption_algorithm_names
,
370 alg
->algorithm
, alg
->key_size
);
375 /* select integrity algorithm */
376 if (!is_authenticated_encryption(algo
))
378 if (select_algo(this->integrity_algos
, other
->integrity_algos
, &add
, &algo
, &key_size
))
382 selected
->add_algorithm(selected
, INTEGRITY_ALGORITHM
, algo
, key_size
);
390 selected
->destroy(selected
);
391 DBG2(DBG_CFG
, " no acceptable INTEGRITY_ALGORITHM found");
392 DBG2(DBG_CFG
, " list of received INTEGRITY_ALGORITHM proposals:");
393 e
= other
->integrity_algos
->create_enumerator(other
->integrity_algos
);
394 while (e
->enumerate(e
, &alg
))
396 DBG2(DBG_CFG
, " %N", integrity_algorithm_names
, alg
->algorithm
);
402 /* select prf algorithm */
403 if (select_algo(this->prf_algos
, other
->prf_algos
, &add
, &algo
, &key_size
))
407 selected
->add_algorithm(selected
, PSEUDO_RANDOM_FUNCTION
, algo
, key_size
);
415 selected
->destroy(selected
);
416 DBG2(DBG_CFG
, " no acceptable PSEUDO_RANDOM_FUNCTION found");
417 DBG2(DBG_CFG
, " list of received PSEUDO_RANDOM_FUNCTION proposals:");
418 e
= other
->prf_algos
->create_enumerator(other
->prf_algos
);
419 while (e
->enumerate(e
, &alg
))
421 DBG2(DBG_CFG
, " %N", pseudo_random_function_names
, alg
->algorithm
);
426 /* select a DH-group */
427 if (select_algo(this->dh_groups
, other
->dh_groups
, &add
, &algo
, &key_size
))
431 selected
->add_algorithm(selected
, DIFFIE_HELLMAN_GROUP
, algo
, 0);
439 selected
->destroy(selected
);
440 DBG2(DBG_CFG
, " no acceptable DIFFIE_HELLMAN_GROUP found");
441 DBG2(DBG_CFG
, " list of received DIFFIE_HELLMAN_GROUP proposals:");
442 e
= other
->dh_groups
->create_enumerator(other
->dh_groups
);
443 while (e
->enumerate(e
, &alg
))
445 DBG2(DBG_CFG
, " %N", diffie_hellman_group_names
, alg
->algorithm
);
450 /* select if we use ESNs */
451 if (select_algo(this->esns
, other
->esns
, &add
, &algo
, &key_size
))
455 selected
->add_algorithm(selected
, EXTENDED_SEQUENCE_NUMBERS
, algo
, 0);
460 selected
->destroy(selected
);
461 DBG2(DBG_CFG
, " no acceptable EXTENDED_SEQUENCE_NUMBERS found");
464 DBG2(DBG_CFG
, " proposal matches");
466 /* apply SPI from "other" */
467 selected
->set_spi(selected
, other
->spi
);
469 /* everything matched, return new proposal */
474 * Implements proposal_t.get_protocols.
476 static protocol_id_t
get_protocol(private_proposal_t
*this)
478 return this->protocol
;
482 * Implements proposal_t.set_spi.
484 static void set_spi(private_proposal_t
*this, u_int64_t spi
)
490 * Implements proposal_t.get_spi.
492 static u_int64_t
get_spi(private_proposal_t
*this)
498 * Clone a algorithm list
500 static void clone_algo_list(linked_list_t
*list
, linked_list_t
*clone_list
)
502 algorithm_t
*algo
, *clone_algo
;
503 enumerator_t
*enumerator
;
505 enumerator
= list
->create_enumerator(list
);
506 while (enumerator
->enumerate(enumerator
, &algo
))
508 clone_algo
= malloc_thing(algorithm_t
);
509 memcpy(clone_algo
, algo
, sizeof(algorithm_t
));
510 clone_list
->insert_last(clone_list
, (void*)clone_algo
);
512 enumerator
->destroy(enumerator
);
516 * check if an algorithm list equals
518 static bool algo_list_equals(linked_list_t
*l1
, linked_list_t
*l2
)
520 enumerator_t
*e1
, *e2
;
521 algorithm_t
*alg1
, *alg2
;
524 if (l1
->get_count(l1
) != l2
->get_count(l2
))
529 e1
= l1
->create_enumerator(l1
);
530 e2
= l2
->create_enumerator(l2
);
531 while (e1
->enumerate(e1
, &alg1
) && e2
->enumerate(e2
, &alg2
))
533 if (alg1
->algorithm
!= alg2
->algorithm
||
534 alg1
->key_size
!= alg2
->key_size
)
546 * Implementation of proposal_t.equals.
548 static bool equals(private_proposal_t
*this, private_proposal_t
*other
)
554 if (this->public.equals
!= other
->public.equals
)
559 algo_list_equals(this->encryption_algos
, other
->encryption_algos
) &&
560 algo_list_equals(this->integrity_algos
, other
->integrity_algos
) &&
561 algo_list_equals(this->prf_algos
, other
->prf_algos
) &&
562 algo_list_equals(this->dh_groups
, other
->dh_groups
) &&
563 algo_list_equals(this->esns
, other
->esns
));
567 * Implements proposal_t.clone
569 static proposal_t
*clone_(private_proposal_t
*this)
571 private_proposal_t
*clone
= (private_proposal_t
*)proposal_create(this->protocol
);
573 clone_algo_list(this->encryption_algos
, clone
->encryption_algos
);
574 clone_algo_list(this->integrity_algos
, clone
->integrity_algos
);
575 clone_algo_list(this->prf_algos
, clone
->prf_algos
);
576 clone_algo_list(this->dh_groups
, clone
->dh_groups
);
577 clone_algo_list(this->esns
, clone
->esns
);
579 clone
->spi
= this->spi
;
581 return &clone
->public;
585 * Checks the proposal read from a string.
587 static void check_proposal(private_proposal_t
*this)
591 bool all_aead
= TRUE
;
593 e
= this->encryption_algos
->create_enumerator(this->encryption_algos
);
594 while (e
->enumerate(e
, &alg
))
596 if (!is_authenticated_encryption(alg
->algorithm
))
606 /* if all encryption algorithms in the proposal are authenticated encryption
607 * algorithms we MUST NOT propose any integrity algorithms */
608 while (this->integrity_algos
->remove_last(this->integrity_algos
, (void**)&alg
) == SUCCESS
)
616 * add a algorithm identified by a string to the proposal.
617 * TODO: we could use gperf here.
619 static status_t
add_string_algo(private_proposal_t
*this, chunk_t alg
)
621 if (strncmp(alg
.ptr
, "null", alg
.len
) == 0)
623 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_NULL
, 0);
625 else if (strncmp(alg
.ptr
, "aes128", alg
.len
) == 0)
627 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 128);
629 else if (strncmp(alg
.ptr
, "aes192", alg
.len
) == 0)
631 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 192);
633 else if (strncmp(alg
.ptr
, "aes256", alg
.len
) == 0)
635 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 256);
637 else if (strstr(alg
.ptr
, "ccm"))
639 u_int16_t key_size
, icv_size
;
641 if (sscanf(alg
.ptr
, "aes%huccm%hu", &key_size
, &icv_size
) == 2)
643 if (key_size
== 128 || key_size
== 192 || key_size
== 256)
649 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CCM_ICV8
, key_size
);
651 case 12: /* octets */
653 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CCM_ICV12
, key_size
);
655 case 16: /* octets */
657 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CCM_ICV16
, key_size
);
660 /* invalid ICV size */
666 else if (strstr(alg
.ptr
, "gcm"))
668 u_int16_t key_size
, icv_size
;
670 if (sscanf(alg
.ptr
, "aes%hugcm%hu", &key_size
, &icv_size
) == 2)
672 if (key_size
== 128 || key_size
== 192 || key_size
== 256)
678 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_GCM_ICV8
, key_size
);
680 case 12: /* octets */
682 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_GCM_ICV12
, key_size
);
684 case 16: /* octets */
686 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_GCM_ICV16
, key_size
);
689 /* invalid ICV size */
695 else if (strncmp(alg
.ptr
, "3des", alg
.len
) == 0)
697 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_3DES
, 0);
699 /* blowfish only uses some predefined key sizes yet */
700 else if (strncmp(alg
.ptr
, "blowfish128", alg
.len
) == 0)
702 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_BLOWFISH
, 128);
704 else if (strncmp(alg
.ptr
, "blowfish192", alg
.len
) == 0)
706 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_BLOWFISH
, 192);
708 else if (strncmp(alg
.ptr
, "blowfish256", alg
.len
) == 0)
710 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_BLOWFISH
, 256);
712 else if (strncmp(alg
.ptr
, "sha", alg
.len
) == 0 ||
713 strncmp(alg
.ptr
, "sha1", alg
.len
) == 0)
715 /* sha means we use SHA for both, PRF and AUTH */
716 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
717 if (this->protocol
== PROTO_IKE
)
719 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA1
, 0);
722 else if (strncmp(alg
.ptr
, "sha256", alg
.len
) == 0 ||
723 strncmp(alg
.ptr
, "sha2_256", alg
.len
) == 0)
725 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_256_128
, 0);
726 if (this->protocol
== PROTO_IKE
)
728 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_256
, 0);
731 else if (strncmp(alg
.ptr
, "sha384", alg
.len
) == 0 ||
732 strncmp(alg
.ptr
, "sha2_384", alg
.len
) == 0)
734 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_384_192
, 0);
735 if (this->protocol
== PROTO_IKE
)
737 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_384
, 0);
740 else if (strncmp(alg
.ptr
, "sha512", alg
.len
) == 0 ||
741 strncmp(alg
.ptr
, "sha2_512", alg
.len
) == 0)
743 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_512_256
, 0);
744 if (this->protocol
== PROTO_IKE
)
746 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_512
, 0);
749 else if (strncmp(alg
.ptr
, "md5", alg
.len
) == 0)
751 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_MD5_96
, 0);
752 if (this->protocol
== PROTO_IKE
)
754 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_MD5
, 0);
757 else if (strncmp(alg
.ptr
, "aesxcbc", alg
.len
) == 0)
759 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
760 if (this->protocol
== PROTO_IKE
)
762 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_AES128_XCBC
, 0);
765 else if (strncmp(alg
.ptr
, "modp768", alg
.len
) == 0)
767 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_768_BIT
, 0);
769 else if (strncmp(alg
.ptr
, "modp1024", alg
.len
) == 0)
771 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_1024_BIT
, 0);
773 else if (strncmp(alg
.ptr
, "modp1536", alg
.len
) == 0)
775 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_1536_BIT
, 0);
777 else if (strncmp(alg
.ptr
, "modp2048", alg
.len
) == 0)
779 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_2048_BIT
, 0);
781 else if (strncmp(alg
.ptr
, "modp4096", alg
.len
) == 0)
783 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_4096_BIT
, 0);
785 else if (strncmp(alg
.ptr
, "modp8192", alg
.len
) == 0)
787 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_8192_BIT
, 0);
789 else if (strncmp(alg
.ptr
, "ecp192", alg
.len
) == 0)
791 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, ECP_192_BIT
, 0);
793 else if (strncmp(alg
.ptr
, "ecp224", alg
.len
) == 0)
795 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, ECP_224_BIT
, 0);
797 else if (strncmp(alg
.ptr
, "ecp256", alg
.len
) == 0)
799 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, ECP_256_BIT
, 0);
801 else if (strncmp(alg
.ptr
, "ecp384", alg
.len
) == 0)
803 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, ECP_384_BIT
, 0);
805 else if (strncmp(alg
.ptr
, "ecp521", alg
.len
) == 0)
807 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, ECP_521_BIT
, 0);
817 * Implements proposal_t.destroy.
819 static void destroy(private_proposal_t
*this)
821 this->encryption_algos
->destroy_function(this->encryption_algos
, free
);
822 this->integrity_algos
->destroy_function(this->integrity_algos
, free
);
823 this->prf_algos
->destroy_function(this->prf_algos
, free
);
824 this->dh_groups
->destroy_function(this->dh_groups
, free
);
825 this->esns
->destroy_function(this->esns
, free
);
830 * Describtion in header-file
832 proposal_t
*proposal_create(protocol_id_t protocol
)
834 private_proposal_t
*this = malloc_thing(private_proposal_t
);
836 this->public.add_algorithm
= (void (*)(proposal_t
*,transform_type_t
,u_int16_t
,u_int16_t
))add_algorithm
;
837 this->public.create_enumerator
= (enumerator_t
* (*)(proposal_t
*,transform_type_t
))create_enumerator
;
838 this->public.get_algorithm
= (bool (*)(proposal_t
*,transform_type_t
,u_int16_t
*,u_int16_t
*))get_algorithm
;
839 this->public.has_dh_group
= (bool (*)(proposal_t
*,diffie_hellman_group_t
))has_dh_group
;
840 this->public.strip_dh
= (void(*)(proposal_t
*))strip_dh
;
841 this->public.select
= (proposal_t
* (*)(proposal_t
*,proposal_t
*))select_proposal
;
842 this->public.get_protocol
= (protocol_id_t(*)(proposal_t
*))get_protocol
;
843 this->public.set_spi
= (void(*)(proposal_t
*,u_int64_t
))set_spi
;
844 this->public.get_spi
= (u_int64_t(*)(proposal_t
*))get_spi
;
845 this->public.equals
= (bool(*)(proposal_t
*, proposal_t
*other
))equals
;
846 this->public.clone
= (proposal_t
*(*)(proposal_t
*))clone_
;
847 this->public.destroy
= (void(*)(proposal_t
*))destroy
;
850 this->protocol
= protocol
;
852 this->encryption_algos
= linked_list_create();
853 this->integrity_algos
= linked_list_create();
854 this->prf_algos
= linked_list_create();
855 this->dh_groups
= linked_list_create();
856 this->esns
= linked_list_create();
858 return &this->public;
862 * Describtion in header-file
864 proposal_t
*proposal_create_default(protocol_id_t protocol
)
866 private_proposal_t
*this = (private_proposal_t
*)proposal_create(protocol
);
871 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 128);
872 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 192);
873 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 256);
874 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_3DES
, 0);
875 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
876 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_256_128
, 0);
877 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
878 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_MD5_96
, 0);
879 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_384_192
, 0);
880 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA2_512_256
, 0);
881 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_AES128_XCBC
, 0);
882 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_256
, 0);
883 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA1
, 0);
884 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_MD5
, 0);
885 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_384
, 0);
886 add_algorithm(this, PSEUDO_RANDOM_FUNCTION
, PRF_HMAC_SHA2_512
, 0);
887 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_2048_BIT
, 0);
888 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_1536_BIT
, 0);
889 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_1024_BIT
, 0);
890 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_4096_BIT
, 0);
891 add_algorithm(this, DIFFIE_HELLMAN_GROUP
, MODP_8192_BIT
, 0);
894 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 128);
895 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 192);
896 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_AES_CBC
, 256);
897 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_3DES
, 0);
898 add_algorithm(this, ENCRYPTION_ALGORITHM
, ENCR_BLOWFISH
, 256);
899 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
900 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
901 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_MD5_96
, 0);
902 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
905 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_SHA1_96
, 0);
906 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_AES_XCBC_96
, 0);
907 add_algorithm(this, INTEGRITY_ALGORITHM
, AUTH_HMAC_MD5_96
, 0);
908 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
914 return &this->public;
918 * Describtion in header-file
920 proposal_t
*proposal_create_from_string(protocol_id_t protocol
, const char *algs
)
922 private_proposal_t
*this = (private_proposal_t
*)proposal_create(protocol
);
923 chunk_t string
= {(void*)algs
, strlen(algs
)};
925 status_t status
= SUCCESS
;
927 eat_whitespace(&string
);
934 /* get all tokens, separated by '-' */
935 while (extract_token(&alg
, '-', &string
))
937 status
|= add_string_algo(this, alg
);
941 status
|= add_string_algo(this, string
);
943 if (status
!= SUCCESS
)
949 check_proposal(this);
951 if (protocol
== PROTO_AH
|| protocol
== PROTO_ESP
)
953 add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS
, NO_EXT_SEQ_NUMBERS
, 0);
955 return &this->public;