- refactored ike proposal
authorMartin Willi <martin@strongswan.org>
Tue, 14 Feb 2006 14:52:00 +0000 (14:52 -0000)
committerMartin Willi <martin@strongswan.org>
Tue, 14 Feb 2006 14:52:00 +0000 (14:52 -0000)
- uses now proposal_t, wich is also used by child proposals
- ike key derivation refactored
- crypter_t api has get_key_size now
- some other improvements here and there

47 files changed:
Source/charon/config/Makefile.config
Source/charon/config/child_proposal.c [deleted file]
Source/charon/config/child_proposal.h [deleted file]
Source/charon/config/configuration_manager.c
Source/charon/config/init_config.c
Source/charon/config/init_config.h
Source/charon/config/proposal.c [new file with mode: 0644]
Source/charon/config/proposal.h [new file with mode: 0644]
Source/charon/config/sa_config.c
Source/charon/config/sa_config.h
Source/charon/daemon.h
Source/charon/encoding/payloads/notify_payload.c
Source/charon/encoding/payloads/proposal_substructure.c
Source/charon/encoding/payloads/proposal_substructure.h
Source/charon/encoding/payloads/sa_payload.c
Source/charon/encoding/payloads/sa_payload.h
Source/charon/encoding/payloads/transform_substructure.h
Source/charon/sa/authenticator.c
Source/charon/sa/child_sa.c
Source/charon/sa/child_sa.h
Source/charon/sa/ike_sa.c
Source/charon/sa/ike_sa.h
Source/charon/sa/states/ike_auth_requested.c
Source/charon/sa/states/ike_sa_init_requested.c
Source/charon/sa/states/ike_sa_init_requested.h
Source/charon/sa/states/ike_sa_init_responded.c
Source/charon/sa/states/initiator_init.c
Source/charon/sa/states/responder_init.c
Source/charon/testcases/Makefile.testcases
Source/charon/testcases/child_proposal_test.c [deleted file]
Source/charon/testcases/child_proposal_test.h [deleted file]
Source/charon/testcases/generator_test.c
Source/charon/testcases/init_config_test.c
Source/charon/testcases/parser_test.c
Source/charon/testcases/proposal_test.c [new file with mode: 0644]
Source/charon/testcases/proposal_test.h [new file with mode: 0644]
Source/charon/testcases/sa_config_test.c
Source/charon/testcases/testcases.c
Source/charon/transforms/crypters/aes_cbc_crypter.c
Source/charon/transforms/crypters/aes_cbc_crypter.h
Source/charon/transforms/crypters/crypter.c
Source/charon/transforms/crypters/crypter.h
Source/charon/transforms/diffie_hellman.c
Source/charon/transforms/diffie_hellman.h
Source/charon/transforms/prfs/hmac_prf.c
Source/charon/transforms/prfs/prf.h
Source/charon/transforms/signers/hmac_signer.c

index 7ca46d1..7189d40 100644 (file)
@@ -31,6 +31,6 @@ OBJS+= $(BUILD_DIR)traffic_selector.o
 $(BUILD_DIR)traffic_selector.o :                       $(CONFIG_DIR)traffic_selector.c $(CONFIG_DIR)traffic_selector.h
                                                                                        $(CC) $(CFLAGS) -c -o $@ $<
 
-OBJS+= $(BUILD_DIR)child_proposal.o
-$(BUILD_DIR)child_proposal.o :                         $(CONFIG_DIR)child_proposal.c $(CONFIG_DIR)child_proposal.h
+OBJS+= $(BUILD_DIR)proposal.o
+$(BUILD_DIR)proposal.o :                                       $(CONFIG_DIR)proposal.c $(CONFIG_DIR)proposal.h
                                                                                        $(CC) $(CFLAGS) -c -o $@ $<
diff --git a/Source/charon/config/child_proposal.c b/Source/charon/config/child_proposal.c
deleted file mode 100644 (file)
index 729102e..0000000
+++ /dev/null
@@ -1,583 +0,0 @@
-/**
- * @file child_proposal.c
- * 
- * @brief Implementation of child_proposal_t.
- * 
- */
-
-/*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "child_proposal.h"
-
-#include <utils/linked_list.h>
-#include <utils/allocator.h>
-#include <utils/identification.h>
-#include <utils/logger.h>
-
-
-/** 
- * String mappings for protocol_id_t.
- */
-mapping_t protocol_id_m[] = {
-       {UNDEFINED_PROTOCOL_ID, "UNDEFINED_PROTOCOL_ID"},
-       {IKE, "IKE"},
-       {AH, "AH"},
-       {ESP, "ESP"},
-       {MAPPING_END, NULL}
-};
-
-/** 
- * String mappings for transform_type_t.
- */
-mapping_t transform_type_m[] = {
-       {UNDEFINED_TRANSFORM_TYPE, "UNDEFINED_TRANSFORM_TYPE"},
-       {ENCRYPTION_ALGORITHM, "ENCRYPTION_ALGORITHM"},
-       {PSEUDO_RANDOM_FUNCTION, "PSEUDO_RANDOM_FUNCTION"},
-       {INTEGRITY_ALGORITHM, "INTEGRITY_ALGORITHM"},
-       {DIFFIE_HELLMAN_GROUP, "DIFFIE_HELLMAN_GROUP"},
-       {EXTENDED_SEQUENCE_NUMBERS, "EXTENDED_SEQUENCE_NUMBERS"},
-       {MAPPING_END, NULL}
-};
-
-/** 
- * String mappings for extended_sequence_numbers_t.
- */
-mapping_t extended_sequence_numbers_m[] = {
-       {NO_EXT_SEQ_NUMBERS, "NO_EXT_SEQ_NUMBERS"},
-       {EXT_SEQ_NUMBERS, "EXT_SEQ_NUMBERS"},
-       {MAPPING_END, NULL}
-};
-
-
-typedef struct protocol_proposal_t protocol_proposal_t;
-
-/**
- * substructure which holds all data algos for a specific protocol
- */
-struct protocol_proposal_t {
-       /**
-        * protocol (ESP or AH)
-        */
-       protocol_id_t protocol;
-       
-       /**
-        * priority ordered list of encryption algorithms
-        */
-       linked_list_t *encryption_algos;
-       
-       /**
-        * priority ordered list of integrity algorithms
-        */
-       linked_list_t *integrity_algos;
-       
-       /**
-        * priority ordered list of pseudo random functions
-        */
-       linked_list_t *prf_algos;
-       
-       /**
-        * priority ordered list of dh groups
-        */
-       linked_list_t *dh_groups;
-       
-       /**
-        * priority ordered list of extended sequence number flags
-       */
-       linked_list_t *esns;
-       
-       /** 
-        * senders SPI
-        */
-       chunk_t spi;
-};
-
-
-typedef struct private_child_proposal_t private_child_proposal_t;
-
-/**
- * Private data of an child_proposal_t object
- */
-struct private_child_proposal_t {
-
-       /**
-        * Public part
-        */
-       child_proposal_t public;
-       
-       /**
-        * number of this proposal, as used in the payload
-        */
-       u_int8_t number;
-       
-       /**
-        * list of protocol_proposal_t's
-        */
-       linked_list_t *protocol_proposals;
-};
-
-/**
- * Look up a protocol_proposal, or create one if necessary...
- */
-static protocol_proposal_t *get_protocol_proposal(private_child_proposal_t *this, protocol_id_t proto, bool create)
-{
-       protocol_proposal_t *proto_proposal = NULL, *current_proto_proposal;;
-       iterator_t *iterator;
-        
-       /* find our protocol in the proposals */
-       iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
-       while (iterator->has_next(iterator))
-       {
-               iterator->current(iterator, (void**)&current_proto_proposal);
-               if (current_proto_proposal->protocol == proto)
-               {
-                       proto_proposal = current_proto_proposal;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-
-       if (!proto_proposal && create)
-       {
-               /* nope, create a new one */
-               proto_proposal = allocator_alloc_thing(protocol_proposal_t);
-               proto_proposal->protocol = proto;
-               proto_proposal->encryption_algos = linked_list_create();
-               proto_proposal->integrity_algos = linked_list_create();
-               proto_proposal->prf_algos = linked_list_create();
-               proto_proposal->dh_groups = linked_list_create();
-               proto_proposal->esns = linked_list_create();
-               if (proto == IKE)
-               {
-                       proto_proposal->spi.len = 8;
-               }
-               else
-               {
-                       proto_proposal->spi.len = 4;
-               }
-               proto_proposal->spi.ptr = allocator_alloc(proto_proposal->spi.len);
-               /* add to the list */
-               this->protocol_proposals->insert_last(this->protocol_proposals, (void*)proto_proposal);
-       }
-       return proto_proposal;
-}
-
-/**
- * Add algorithm/keysize to a algorithm list
- */
-static void add_algo(linked_list_t *list, u_int8_t algo, size_t key_size)
-{
-       algorithm_t *algo_key = allocator_alloc_thing(algorithm_t);
-       
-       algo_key->algorithm = algo;
-       algo_key->key_size = key_size;
-       list->insert_last(list, (void*)algo_key);
-}
-
-/**
- * Implements child_proposal_t.add_algorithm
- */
-static void add_algorithm(private_child_proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t algo, size_t key_size)
-{
-       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, TRUE);
-       
-       switch (type)
-       {
-               case ENCRYPTION_ALGORITHM:
-                       add_algo(proto_proposal->encryption_algos, algo, key_size);
-                       break;
-               case INTEGRITY_ALGORITHM:
-                       add_algo(proto_proposal->integrity_algos, algo, key_size);
-                       break;
-               case PSEUDO_RANDOM_FUNCTION:
-                       add_algo(proto_proposal->prf_algos, algo, key_size);
-                       break;
-               case DIFFIE_HELLMAN_GROUP:
-                       add_algo(proto_proposal->dh_groups, algo, 0);
-                       break;
-               case EXTENDED_SEQUENCE_NUMBERS:
-                       add_algo(proto_proposal->esns, algo, 0);
-                       break;
-               default:
-                       break;
-       }
-}
-
-/**
- * Implements child_proposal_t.get_algorithm.
- */
-static bool get_algorithm(private_child_proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo)
-{
-       linked_list_t * list;
-       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
-       
-       if (proto_proposal == NULL)
-       {
-               return FALSE;
-       }
-       switch (type)
-       {
-               case ENCRYPTION_ALGORITHM:
-                       list = proto_proposal->encryption_algos;
-                       break;
-               case INTEGRITY_ALGORITHM:
-                       list = proto_proposal->integrity_algos;
-                       break;
-               case PSEUDO_RANDOM_FUNCTION:
-                       list = proto_proposal->prf_algos;
-                       break;
-               case DIFFIE_HELLMAN_GROUP:
-                       list = proto_proposal->dh_groups;
-                       break;
-               case EXTENDED_SEQUENCE_NUMBERS:
-                       list = proto_proposal->esns;
-                       break;
-               default:
-                       return FALSE;
-       }
-       if (list->get_first(list, (void**)algo) != SUCCESS)
-       {
-               return FALSE;
-       }
-       return TRUE;
-}
-
-/**
- * Implements child_proposal_t.create_algorithm_iterator.
- */
-static iterator_t *create_algorithm_iterator(private_child_proposal_t *this, protocol_id_t proto, transform_type_t type)
-{
-       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
-       if (proto_proposal == NULL)
-       {
-               return NULL;
-       }
-       
-       switch (type)
-       {
-               case ENCRYPTION_ALGORITHM:
-                       return proto_proposal->encryption_algos->create_iterator(proto_proposal->encryption_algos, TRUE);
-               case INTEGRITY_ALGORITHM:
-                       return proto_proposal->integrity_algos->create_iterator(proto_proposal->integrity_algos, TRUE);
-               case PSEUDO_RANDOM_FUNCTION:
-                       return proto_proposal->prf_algos->create_iterator(proto_proposal->prf_algos, TRUE);
-               case DIFFIE_HELLMAN_GROUP:
-                       return proto_proposal->dh_groups->create_iterator(proto_proposal->dh_groups, TRUE);
-               case EXTENDED_SEQUENCE_NUMBERS:
-                       return proto_proposal->esns->create_iterator(proto_proposal->esns, TRUE);
-               default:
-                       break;
-       }
-       return NULL;
-}
-
-/**
- * Find a matching alg/keysize in two linked lists
- */
-static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add, u_int16_t *alg, size_t *key_size)
-{
-       iterator_t *first_iter, *second_iter;
-       algorithm_t *first_alg, *second_alg;
-       
-       /* if in both are zero algorithms specified, we HAVE a match */
-       if (first->get_count(first) == 0 && second->get_count(second) == 0)
-       {
-               *add = FALSE;
-               return TRUE;
-       }
-       
-       first_iter = first->create_iterator(first, TRUE);
-       second_iter = second->create_iterator(second, TRUE);
-       /* compare algs, order of algs in "first" is preferred */
-       while (first_iter->has_next(first_iter))
-       {
-               first_iter->current(first_iter, (void**)&first_alg);
-               second_iter->reset(second_iter);
-               while (second_iter->has_next(second_iter))
-               {
-                       second_iter->current(second_iter, (void**)&second_alg);
-                       if (first_alg->algorithm == second_alg->algorithm &&
-                               first_alg->key_size == second_alg->key_size)
-                       {
-                               /* ok, we have an algorithm */
-                               *alg = first_alg->algorithm;
-                               *key_size = first_alg->key_size;
-                               *add = TRUE;
-                               first_iter->destroy(first_iter);
-                               second_iter->destroy(second_iter);
-                               return TRUE;
-                       }
-               }
-       }
-       /* no match in all comparisons */
-       first_iter->destroy(first_iter);
-       second_iter->destroy(second_iter);
-       return FALSE;
-}
-
-/**
- * Implements child_proposal_t.select.
- */
-static child_proposal_t *select_proposal(private_child_proposal_t *this, private_child_proposal_t *other)
-{
-       child_proposal_t *selected;
-       u_int16_t algo;
-       size_t key_size;
-       iterator_t *iterator;
-       protocol_proposal_t *this_prop, *other_prop;
-       protocol_id_t proto;
-       bool add;
-       
-       /* empty proposal? no match */
-       if (this->protocol_proposals->get_count(this->protocol_proposals) == 0 ||
-               other->protocol_proposals->get_count(other->protocol_proposals) == 0)
-       {
-               return NULL;
-       }
-       /* they MUST have the same amount of protocols */
-       if (this->protocol_proposals->get_count(this->protocol_proposals) !=
-               other->protocol_proposals->get_count(other->protocol_proposals))
-       {
-               return NULL;
-       }
-       
-       selected = child_proposal_create(this->number);
-       
-       /* iterate over supplied proposals */
-       iterator = other->protocol_proposals->create_iterator(other->protocol_proposals, TRUE);
-       while (iterator->has_next(iterator))
-       {
-               iterator->current(iterator, (void**)&other_prop);
-               /* get the proposal with the same protocol */
-               proto = other_prop->protocol;
-               this_prop = get_protocol_proposal(this, proto, FALSE);
-               
-               if (this_prop == NULL)
-               {
-                       iterator->destroy(iterator);
-                       selected->destroy(selected);
-                       return NULL;
-               }
-               
-               /* select encryption algorithm */
-               if (select_algo(this_prop->encryption_algos, other_prop->encryption_algos, &add, &algo, &key_size))
-               {
-                       if (add)
-                       {
-                               selected->add_algorithm(selected, proto, ENCRYPTION_ALGORITHM, algo, key_size);
-                       }
-               }
-               else
-               {
-                       iterator->destroy(iterator);
-                       selected->destroy(selected);
-                       return NULL;
-               }
-               /* select integrity algorithm */
-               if (select_algo(this_prop->integrity_algos, other_prop->integrity_algos, &add, &algo, &key_size))
-               {
-                       if (add)
-                       {
-                               selected->add_algorithm(selected, proto, INTEGRITY_ALGORITHM, algo, key_size);
-                       }
-               }
-               else
-               {
-                       iterator->destroy(iterator);
-                       selected->destroy(selected);
-                       return NULL;
-               }
-               /* select prf algorithm */
-               if (select_algo(this_prop->prf_algos, other_prop->prf_algos, &add, &algo, &key_size))
-               {
-                       if (add)
-                       {
-                               selected->add_algorithm(selected, proto, PSEUDO_RANDOM_FUNCTION, algo, key_size);
-                       }
-               }
-               else
-               {
-                       iterator->destroy(iterator);
-                       selected->destroy(selected);
-                       return NULL;
-               }
-               /* select a DH-group */
-               if (select_algo(this_prop->dh_groups, other_prop->dh_groups, &add, &algo, &key_size))
-               {
-                       if (add)
-                       {
-                               selected->add_algorithm(selected, proto, DIFFIE_HELLMAN_GROUP, algo, 0);
-                       }
-               }
-               else
-               {
-                       iterator->destroy(iterator);
-                       selected->destroy(selected);
-                       return NULL;
-               }
-               /* select if we use ESNs */
-               if (select_algo(this_prop->esns, other_prop->esns, &add, &algo, &key_size))
-               {
-                       if (add)
-                       {
-                               selected->add_algorithm(selected, proto, EXTENDED_SEQUENCE_NUMBERS, algo, 0);
-                       }
-               }
-               else
-               {
-                       iterator->destroy(iterator);
-                       selected->destroy(selected);
-                       return NULL;
-               }
-       }
-       iterator->destroy(iterator);
-       /* everything matched, return new proposal */
-       return selected;
-}
-
-/**
- * Implements child_proposal_t.get_number.
- */
-static u_int8_t get_number(private_child_proposal_t *this)
-{
-       return this->number;
-}
-
-/**
- * Implements child_proposal_t.get_protocols.
- */
-static void get_protocols(private_child_proposal_t *this, protocol_id_t ids[2])
-{
-       iterator_t *iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
-       u_int i = 0;
-       
-       ids[0] = UNDEFINED_PROTOCOL_ID;
-       ids[1] = UNDEFINED_PROTOCOL_ID;
-       while (iterator->has_next(iterator))
-       {
-               protocol_proposal_t *proto_prop;
-               iterator->current(iterator, (void**)&proto_prop);
-               ids[i++] = proto_prop->protocol;
-               if (i>1)
-               {
-                       /* should not happen, but who knows */
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-}
-
-/**
- * Implements child_proposal_t.set_spi.
- */
-static void set_spi(private_child_proposal_t *this, protocol_id_t proto, u_int64_t spi)
-{
-       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
-       if (proto_proposal)
-       {
-               if (proto == IKE)
-               {
-                       *((u_int32_t*)proto_proposal->spi.ptr) = (u_int32_t)spi;
-               }
-               else
-               {
-                       *((u_int64_t*)proto_proposal->spi.ptr) = spi;
-               }
-               
-       }
-}
-
-/**
- * Implements child_proposal_t.get_spi.
- */
-static u_int64_t get_spi(private_child_proposal_t *this, protocol_id_t proto)
-{
-       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
-       if (proto_proposal)
-       {
-               if (proto == IKE)
-               {
-                       return (u_int64_t)*((u_int32_t*)proto_proposal->spi.ptr);
-               }
-               else
-               {
-                       return *((u_int64_t*)proto_proposal->spi.ptr);
-               }
-       }
-       return 0;
-}
-
-/**
- * Frees all list items and destroys the list
- */
-static void free_algo_list(linked_list_t *list)
-{
-       algorithm_t *algo;
-       
-       while(list->get_count(list) > 0)
-       {
-               list->remove_last(list, (void**)&algo);
-               allocator_free(algo);
-       }
-       list->destroy(list);
-}
-
-/**
- * Implements child_proposal_t.destroy.
- */
-static void destroy(private_child_proposal_t *this)
-{
-       while(this->protocol_proposals->get_count(this->protocol_proposals) > 0)
-       {
-               protocol_proposal_t *proto_prop;
-               this->protocol_proposals->remove_last(this->protocol_proposals, (void**)&proto_prop);
-               
-               free_algo_list(proto_prop->encryption_algos);
-               free_algo_list(proto_prop->integrity_algos);
-               free_algo_list(proto_prop->prf_algos);
-               free_algo_list(proto_prop->dh_groups);
-               free_algo_list(proto_prop->esns);
-               
-               allocator_free(proto_prop->spi.ptr);
-               allocator_free(proto_prop);
-       }
-       this->protocol_proposals->destroy(this->protocol_proposals);
-       
-       allocator_free(this);
-}
-
-/*
- * Describtion in header-file
- */
-child_proposal_t *child_proposal_create(u_int8_t number)
-{
-       private_child_proposal_t *this = allocator_alloc_thing(private_child_proposal_t);
-       
-       this->public.add_algorithm = (void (*)(child_proposal_t*,protocol_id_t,transform_type_t,u_int16_t,size_t))add_algorithm;
-       this->public.create_algorithm_iterator = (iterator_t* (*)(child_proposal_t*,protocol_id_t,transform_type_t))create_algorithm_iterator;
-       this->public.get_algorithm = (bool (*)(child_proposal_t*,protocol_id_t,transform_type_t,algorithm_t**))get_algorithm;
-       this->public.select = (child_proposal_t* (*)(child_proposal_t*,child_proposal_t*))select_proposal;
-       this->public.get_number = (u_int8_t (*)(child_proposal_t*))get_number;
-       this->public.get_protocols = (void(*)(child_proposal_t *this, protocol_id_t ids[2]))get_protocols;
-       this->public.set_spi = (void(*)(child_proposal_t*,protocol_id_t,u_int64_t spi))set_spi;
-       this->public.get_spi = (u_int64_t(*)(child_proposal_t*,protocol_id_t))get_spi;
-       this->public.destroy = (void(*)(child_proposal_t*))destroy;
-       
-       /* init private members*/
-       this->number = number;
-       this->protocol_proposals = linked_list_create();
-       
-       return (&this->public);
-}
diff --git a/Source/charon/config/child_proposal.h b/Source/charon/config/child_proposal.h
deleted file mode 100644 (file)
index 69bd7f3..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * @file child_proposal.h
- * 
- * @brief Interface of child_proposal_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef _CHILD_PROPOSAL_H_
-#define _CHILD_PROPOSAL_H_
-
-#include <types.h>
-#include <utils/identification.h>
-#include <utils/linked_list.h>
-#include <network/host.h>
-#include <transforms/crypters/crypter.h>
-#include <transforms/signers/signer.h>
-#include <transforms/diffie_hellman.h>
-#include <config/traffic_selector.h>
-
-
-typedef enum protocol_id_t protocol_id_t;
-
-/**
- * Protocol ID of a proposal.
- * 
- * @ingroup config
- */
-enum protocol_id_t {
-       UNDEFINED_PROTOCOL_ID = 201,
-       IKE = 1,
-       AH = 2,
-       ESP = 3,
-};
-
-/** 
- * String mappings for protocol_id_t.
- * 
- * @ingroup config
- */
-extern mapping_t protocol_id_m[];
-
-
-typedef enum transform_type_t transform_type_t;
-
-/**
- * Type of a transform, as in IKEv2 draft 3.3.2.
- * 
- * @ingroup payloads
- */
-enum transform_type_t {
-       UNDEFINED_TRANSFORM_TYPE = 241,
-       ENCRYPTION_ALGORITHM = 1,
-       PSEUDO_RANDOM_FUNCTION = 2,
-       INTEGRITY_ALGORITHM = 3,
-       DIFFIE_HELLMAN_GROUP = 4,
-       EXTENDED_SEQUENCE_NUMBERS = 5
-};
-
-/** 
- * String mappings for transform_type_t.
- * 
- * @ingroup payloads
- */
-extern mapping_t transform_type_m[];
-
-
-typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
-
-/** 
- * Extended sequence numbers, as in IKEv2 draft 3.3.2.
- * 
- * @ingroup payloads
- */
-enum extended_sequence_numbers_t {
-       NO_EXT_SEQ_NUMBERS = 0,
-       EXT_SEQ_NUMBERS = 1
-};
-
-/** 
- * String mappings for extended_sequence_numbers_t.
- * 
- * @ingroup payloads
- */
-extern mapping_t extended_sequence_numbers_m[];
-
-
-typedef struct algorithm_t algorithm_t;
-
-/**
- * Struct used to store different kinds of algorithms. The internal
- * lists of algorithms contain such structures.
- */
-struct algorithm_t {
-       /**
-        * Value from an encryption_algorithm_t/integrity_algorithm_t/...
-        */
-       u_int16_t algorithm;
-       
-       /**
-        * the associated key size, or zero if not needed
-        */
-       u_int16_t key_size;
-};
-
-typedef struct child_proposal_t child_proposal_t;
-
-/**
- * @brief Stores a proposal for a child SA.
- * 
- * A child_proposal may contain more than one algorithm
- * of the same kind. ONE of them can be selected.
- *
- * @warning This class is NOT thread-save!
- * 
- * @b Constructors:
- *   - child_proposal_create()
- * 
- * @ingroup config
- */
-struct child_proposal_t {
-       
-       /**
-        * @brief Add an algorithm to the proposal.
-        * 
-        * The algorithms are stored by priority, first added
-        * is the most preferred.
-        * Key size is only needed for encryption algorithms
-        * with variable key size (such as AES), or integrity
-        * algorithms.
-        * The alg parameter accepts encryption_algorithm_t,
-        * integrity_algorithm_t, dh_group_number_t and
-        * extended_sequence_numbers_t.
-        * 
-        * @warning Do not add while other threads are reading.
-        * 
-        * @param this                                  calling object
-        * @param proto                                 desired protocol
-        * @param type                                  kind of algorithm
-        * @param alg                                   identifier for algorithm
-        * @param key_size                              key size to use
-        */
-       void (*add_algorithm) (child_proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t alg, size_t key_size);
-       
-       /**
-        * @brief Get an iterator over algorithms for a specifc protocol/algo type.
-        * 
-        * @param this                                  calling object
-        * @param proto                                 desired protocol
-        * @param type                                  kind of algorithm
-        * @return                                              iterator over algorithms
-        */
-       iterator_t *(*create_algorithm_iterator) (child_proposal_t *this, protocol_id_t proto, transform_type_t type);
-       
-       /**
-        * @brief Get the algorithm for a type to use.
-        * 
-        * If there are multiple algorithms, only the first is returned.
-        * Result is still owned by child_proposal, do not modify!
-        * 
-        * @param this                                  calling object
-        * @param proto                                 desired protocol
-        * @param type                                  kind of algorithm
-        * @param[out] algo                             pointer which receives algorithm and key size
-        * @return                                              TRUE if algorithm of this kind available
-        */
-       bool (*get_algorithm) (child_proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo);
-
-       /**
-        * @brief Compare two proposal, and select a matching subset.
-        * 
-        * If the proposals are for the same protocols (AH/ESP), they are
-        * compared. If they have at least one algorithm of each type
-        * in common, a resulting proposal of this kind is created.
-        * 
-        * @param this                                  calling object
-        * @param other                                 proposal to compair agains
-        * @return                                              
-        *                                                              - selected proposal, if possible
-        *                                                              - NULL, if proposals don't match
-        */
-       child_proposal_t *(*select) (child_proposal_t *this, child_proposal_t *other);
-       
-       /**
-        * @brief Get the number set on construction.
-        * 
-        * @param this                          calling object
-        * @return                                      number
-        */
-       u_int8_t (*get_number) (child_proposal_t *this);
-       
-       /**
-        * @brief Get the protocol ids in the proposals.
-        * 
-        * With AH and ESP, there could be two protocols in one
-        * proposal.
-        * 
-        * @param this                          calling object
-        * @param ids                           array of protocol ids, 
-        */
-       void (*get_protocols) (child_proposal_t *this, protocol_id_t ids[2]);
-       
-       /**
-        * @brief Get the spi for a specific protocol.
-        * 
-        * @param this                          calling object
-        * @param proto                         AH/ESP
-        * @return                                      spi for proto
-        */
-       u_int64_t (*get_spi) (child_proposal_t *this, protocol_id_t proto);
-       
-       /**
-        * @brief Set the spi for a specific protocol.
-        * 
-        * @param this                          calling object
-        * @param proto                         AH/ESP
-        * @param spi                           spi to set for proto
-        */
-       void (*set_spi) (child_proposal_t *this, protocol_id_t proto, u_int64_t spi);
-       
-       /**
-        * @brief Destroys the proposal object.
-        * 
-        * @param this                          calling object
-        */
-       void (*destroy) (child_proposal_t *this);
-};
-
-/**
- * @brief Create a child proposal for AH and/or ESP.
- * 
- * @param number                       number of the proposal, as in the payload
- * @return                                     child_proposal_t object
- * 
- * @ingroup config
- */
-child_proposal_t *child_proposal_create(u_int8_t number);
-
-#endif //_CHILD_PROPOSAL_H_
index ed5c33d..adbd0dd 100644 (file)
@@ -275,27 +275,32 @@ u_int8_t private_key_2[];
 static void load_default_config (private_configuration_manager_t *this)
 {
        init_config_t *init_config_a, *init_config_b;
-       ike_proposal_t proposals;
-       child_proposal_t *child_proposal;
+       proposal_t *proposal;
        sa_config_t *sa_config_a, *sa_config_b;
        traffic_selector_t *ts;
        
        init_config_a = init_config_create("0.0.0.0","192.168.0.3",IKEV2_UDP_PORT,IKEV2_UDP_PORT);
        init_config_b = init_config_create("0.0.0.0","192.168.0.2",IKEV2_UDP_PORT,IKEV2_UDP_PORT);
        
-       ts = traffic_selector_create_from_string(1, TS_IPV4_ADDR_RANGE, "0.0.0.0", 0, "255.255.255.255", 65535);
-       
-       proposals.encryption_algorithm = ENCR_AES_CBC;
-       proposals.encryption_algorithm_key_length = 16;
-       proposals.integrity_algorithm = AUTH_HMAC_MD5_96;
-       proposals.integrity_algorithm_key_length = 16;
-       proposals.pseudo_random_function = PRF_HMAC_MD5;
-       proposals.pseudo_random_function_key_length = 16;
-       proposals.diffie_hellman_group = MODP_1024_BIT;
-
-       init_config_a->add_proposal(init_config_a,1,proposals);
-       init_config_b->add_proposal(init_config_b,1,proposals);
-                                                                 
+       /* IKE proposals for alice */
+       proposal = proposal_create(1);
+       proposal->add_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+       POS;
+       proposal->add_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 16);
+       POS;
+       proposal->add_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 16);
+       proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+       proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+       init_config_a->add_proposal(init_config_a, proposal);
+       
+       /* IKE proposals for bob */
+       proposal = proposal_create(1);
+       proposal->add_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+       proposal->add_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 16);
+       proposal->add_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 16);
+       proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+       init_config_b->add_proposal(init_config_b, proposal);
+       
        sa_config_a = sa_config_create(ID_IPV4_ADDR, "192.168.0.2", 
                                                                 ID_IPV4_ADDR, "192.168.0.3",
                                                                 RSA_DIGITAL_SIGNATURE,
@@ -305,46 +310,46 @@ static void load_default_config (private_configuration_manager_t *this)
                                                                 ID_IPV4_ADDR, "192.168.0.2",
                                                                 RSA_DIGITAL_SIGNATURE,
                                                                 30000);
-
+       
+       /* traffic selectors */
+       ts = traffic_selector_create_from_string(1, TS_IPV4_ADDR_RANGE, "0.0.0.0", 0, "255.255.255.255", 65535);
        sa_config_a->add_traffic_selector_initiator(sa_config_a,ts);
        sa_config_a->add_traffic_selector_responder(sa_config_a,ts);
-       
        sa_config_b->add_traffic_selector_initiator(sa_config_b,ts);
        sa_config_b->add_traffic_selector_responder(sa_config_b,ts);
-       
        ts->destroy(ts);
        
        /* child proposal for alice */
-       child_proposal = child_proposal_create(1);
+       proposal = proposal_create(1);
        
-       child_proposal->add_algorithm(child_proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
-       child_proposal->add_algorithm(child_proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
-       child_proposal->add_algorithm(child_proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
-       child_proposal->add_algorithm(child_proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
-       child_proposal->add_algorithm(child_proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+       proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+       proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+       proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+       proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+       proposal->add_algorithm(proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
 
-       child_proposal->add_algorithm(child_proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
-       child_proposal->add_algorithm(child_proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 32);
-       child_proposal->add_algorithm(child_proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
-       child_proposal->add_algorithm(child_proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
-       child_proposal->add_algorithm(child_proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
-       child_proposal->add_algorithm(child_proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+       proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+       proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 32);
+       proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+       proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+       proposal->add_algorithm(proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+       proposal->add_algorithm(proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
        
-       sa_config_a->add_proposal(sa_config_a, child_proposal);
+       sa_config_a->add_proposal(sa_config_a, proposal);
        
        /* child proposal for bob */
-       child_proposal = child_proposal_create(1);
+       proposal = proposal_create(1);
        
-       child_proposal->add_algorithm(child_proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
-       child_proposal->add_algorithm(child_proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
-       child_proposal->add_algorithm(child_proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+       proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+       proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+       proposal->add_algorithm(proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
 
-       child_proposal->add_algorithm(child_proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
-       child_proposal->add_algorithm(child_proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
-       child_proposal->add_algorithm(child_proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
-       child_proposal->add_algorithm(child_proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+       proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+       proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+       proposal->add_algorithm(proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+       proposal->add_algorithm(proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
        
-       sa_config_b->add_proposal(sa_config_b, child_proposal);
+       sa_config_b->add_proposal(sa_config_b, proposal);
        
        
        
index 27f669b..92871dd 100644 (file)
@@ -87,108 +87,111 @@ static host_t * get_other_host_clone (private_init_config_t *this)
 }
 
 /**
- * Implementation of init_config_t.get_dh_group_number.
+ * Implementation of init_config_t.get_proposals.
  */
-static diffie_hellman_group_t get_dh_group_number (private_init_config_t *this,size_t priority)
+static linked_list_t* get_proposals (private_init_config_t *this)
 {
-       ike_proposal_t *ike_proposal;
-       
-       if ((this->proposals->get_count(this->proposals) == 0) || (this->proposals->get_count(this->proposals) < priority))
-       {
-               return MODP_UNDEFINED;
-       }
-       
-       this->proposals->get_at_position(this->proposals,(priority -1),(void **) &ike_proposal);
-       
-       return (ike_proposal->diffie_hellman_group);
+       return this->proposals;
 }
-
+       
 /**
- * Implementation of init_config_t.get_proposals.
+ * Implementation of init_config_t.select_proposal.
  */
-static size_t get_proposals (private_init_config_t *this,ike_proposal_t **proposals)
+static proposal_t *select_proposal(private_init_config_t *this, linked_list_t *proposals)
 {
-       iterator_t *iterator;
-       ike_proposal_t *current_proposal;
-       int i = 0;
-       ike_proposal_t *proposal_array;
+       iterator_t *stored_iter, *supplied_iter;
+       proposal_t *stored, *supplied, *selected;
        
-       proposal_array = allocator_alloc(this->proposals->get_count(this->proposals) * sizeof(ike_proposal_t));
-               
-       iterator = this->proposals->create_iterator(this->proposals,TRUE);
+       stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
+       supplied_iter = proposals->create_iterator(proposals, TRUE);
        
-       while (iterator->has_next(iterator))
+       /* compare all stored proposals with all supplied. Stored ones are preferred. */
+       while (stored_iter->has_next(stored_iter))
        {
-               iterator->current(iterator,(void **) &current_proposal);
-               proposal_array[i] = (*current_proposal);
-               i++;
+               supplied_iter->reset(supplied_iter);
+               stored_iter->current(stored_iter, (void**)&stored);
+
+               while (supplied_iter->has_next(supplied_iter))
+               {
+                       supplied_iter->current(supplied_iter, (void**)&supplied);
+                       selected = stored->select(stored, supplied);
+                       if (selected)
+                       {
+                               /* they match, return */
+                               stored_iter->destroy(stored_iter);
+                               supplied_iter->destroy(supplied_iter);
+                               return selected;
+                       }
+               }
        }
-       iterator->destroy(iterator);
        
-       *proposals = proposal_array;
-       return this->proposals->get_count(this->proposals);
-}
+       /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
+       stored_iter->destroy(stored_iter);
+       supplied_iter->destroy(supplied_iter);
        
+       return NULL;
+}
+
 /**
- * Implementation of init_config_t.select_proposal.
+ * Implementation of init_config_t.add_proposal.
  */
-static status_t select_proposal (private_init_config_t *this, ike_proposal_t *proposals, size_t proposal_count, ike_proposal_t *selected_proposal)
+static void add_proposal (private_init_config_t *this, proposal_t *proposal)
 {
-       iterator_t * my_iterator;
-       int i;
-       ike_proposal_t *my_current_proposal;
-
-       my_iterator = this->proposals->create_iterator(this->proposals,TRUE);
+       this->proposals->insert_last(this->proposals, proposal);
+}
 
+/**
+ * Implementation of init_config_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_init_config_t *this)
+{
+       iterator_t *iterator;
+       proposal_t *proposal;
+       algorithm_t *algo;
        
-       for (i = 0; i < proposal_count; i++)
+       iterator = this->proposals->create_iterator(this->proposals, TRUE);
+       while (iterator->has_next(iterator))
        {
-               my_iterator->reset(my_iterator);
-               while (my_iterator->has_next(my_iterator))
+               iterator->current(iterator, (void**)&proposal);
+               proposal->get_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, &algo);
+               if (algo)
                {
-                       my_iterator->current(my_iterator,(void **) &my_current_proposal);
-               
-                       /* memcmp doesn't work here */
-                       if ((proposals[i].encryption_algorithm == my_current_proposal->encryption_algorithm) &&
-                               (proposals[i].encryption_algorithm_key_length == my_current_proposal->encryption_algorithm_key_length) &&
-                               (proposals[i].integrity_algorithm == my_current_proposal->integrity_algorithm) &&
-                               (proposals[i].integrity_algorithm_key_length == my_current_proposal->integrity_algorithm_key_length) &&
-                               (proposals[i].pseudo_random_function == my_current_proposal->pseudo_random_function) &&
-                               (proposals[i].pseudo_random_function_key_length == my_current_proposal->pseudo_random_function_key_length) &&
-                               (proposals[i].diffie_hellman_group == my_current_proposal->diffie_hellman_group))
-                       {
-                               /* found a matching proposal */
-                               *selected_proposal = *my_current_proposal;
-                               my_iterator->destroy(my_iterator);
-                               return SUCCESS;
-                       }
-                       
-               }                               
+                       iterator->destroy(iterator);
+                       return algo->algorithm;
+               }
        }
-       
-       my_iterator->destroy(my_iterator);
-       return NOT_FOUND;
+       iterator->destroy(iterator);
+       return MODP_UNDEFINED;
 }
 
 /**
- * Implementation of init_config_t.destroy.
+ * Implementation of init_config_t.check_dh_group.
  */
-static void add_proposal (private_init_config_t *this,size_t priority, ike_proposal_t proposal)
+static bool check_dh_group(private_init_config_t *this, diffie_hellman_group_t dh_group)
 {
-       ike_proposal_t * new_proposal = allocator_alloc(sizeof(ike_proposal_t));
-       status_t status;
-       
-       *new_proposal = proposal;
-        
+       iterator_t *prop_iter, *alg_iter;
+       proposal_t *proposal;
+       algorithm_t *algo;
        
-       if (priority > this->proposals->get_count(this->proposals))
+       prop_iter = this->proposals->create_iterator(this->proposals, TRUE);
+       while (prop_iter->has_next(prop_iter))
        {
-               this->proposals->insert_last(this->proposals,new_proposal);
-               return;
+               prop_iter->current(prop_iter, (void**)&proposal);
+               alg_iter = proposal->create_algorithm_iterator(proposal, IKE, DIFFIE_HELLMAN_GROUP);
+               while (alg_iter->has_next(alg_iter))
+               {
+                       alg_iter->current(alg_iter, (void**)&algo);
+                       if (algo->algorithm == dh_group)
+                       {
+                               prop_iter->destroy(prop_iter);
+                               alg_iter->destroy(alg_iter);
+                               return TRUE;
+                       }
+               }
        }
-       
-       status = this->proposals->insert_at_position(this->proposals,(priority - 1),new_proposal);
-
+       prop_iter->destroy(prop_iter);
+       alg_iter->destroy(alg_iter);
+       return FALSE;
 }
 
 /**
@@ -196,12 +199,11 @@ static void add_proposal (private_init_config_t *this,size_t priority, ike_propo
  */
 static void destroy (private_init_config_t *this)
 {
-       ike_proposal_t *proposal;
+       proposal_t *proposal;
        
-       while (this->proposals->get_count(this->proposals) > 0)
+       while (this->proposals->remove_last(this->proposals, (void**)&proposal) == SUCCESS)
        {
-               this->proposals->remove_first(this->proposals,(void **) &proposal);
-               allocator_free(proposal);
+               proposal->destroy(proposal);
        }
        this->proposals->destroy(this->proposals);
        
@@ -222,10 +224,11 @@ init_config_t * init_config_create(char * my_ip, char *other_ip, u_int16_t my_po
        this->public.get_other_host = (host_t*(*)(init_config_t*))get_other_host;
        this->public.get_my_host_clone = (host_t*(*)(init_config_t*))get_my_host_clone;
        this->public.get_other_host_clone = (host_t*(*)(init_config_t*))get_other_host_clone;
-       this->public.get_dh_group_number = (diffie_hellman_group_t (*)(init_config_t*,size_t))get_dh_group_number;
-       this->public.get_proposals = (size_t(*)(init_config_t*,ike_proposal_t**))get_proposals;
-       this->public.select_proposal = (status_t(*)(init_config_t*,ike_proposal_t*,size_t,ike_proposal_t*))select_proposal;
-       this->public.add_proposal = (void(*)(init_config_t*, size_t, ike_proposal_t)) add_proposal;
+       this->public.get_proposals = (linked_list_t*(*)(init_config_t*))get_proposals;
+       this->public.select_proposal = (proposal_t*(*)(init_config_t*,linked_list_t*))select_proposal;
+       this->public.add_proposal = (void(*)(init_config_t*, proposal_t*)) add_proposal;
+       this->public.get_dh_group = (diffie_hellman_group_t(*)(init_config_t*)) get_dh_group;
+       this->public.check_dh_group = (bool(*)(init_config_t*,diffie_hellman_group_t)) check_dh_group;
        this->public.destroy = (void(*)(init_config_t*))destroy;
        
        /* private variables */
index 14ffeee..f63df61 100644 (file)
 
 #include <types.h>
 #include <network/host.h>
-#include <utils/iterator.h>
+#include <utils/linked_list.h>
+#include <config/proposal.h>
 #include <transforms/crypters/crypter.h>
 #include <transforms/prfs/prf.h>
 #include <transforms/signers/signer.h>
 #include <transforms/diffie_hellman.h>
 
 
-typedef struct ike_proposal_t ike_proposal_t;
-
-/**
- * @brief Represents a Proposal used in IKE_SA_INIT phase.
- * 
- * @todo Currently the amount of tranforms with same type in a IKE proposal is limited to 1.
- *              Support of more transforms with same type has to be added.
- * 
- * @ingroup config
- */
-struct ike_proposal_t {
-       /**
-        * Encryption algorithm.
-        */
-       encryption_algorithm_t encryption_algorithm;
-       
-       /**
-        * Key length of encryption algorithm in bytes.
-        */
-       u_int16_t encryption_algorithm_key_length;
-       
-       /**
-        * Integrity algorithm.
-        */
-       integrity_algorithm_t integrity_algorithm;
-       
-       /**
-        * Key length of integrity algorithm.
-        */
-       u_int16_t integrity_algorithm_key_length;
-       
-       /**
-        * Pseudo random function (prf).
-        */
-       pseudo_random_function_t pseudo_random_function;
-       
-       /**
-        * Key length of prf.
-        */
-       u_int16_t pseudo_random_function_key_length;
-       
-       /**
-        * Diffie hellman group.
-        */
-       diffie_hellman_group_t diffie_hellman_group;
-};
-
 
 typedef struct init_config_t init_config_t;
 
@@ -100,7 +54,7 @@ struct init_config_t {
         * @param this  calling object
         * @return              host information as host_t object
         */
-       host_t * (*get_my_host) (init_config_t *this);
+       host_t *(*get_my_host) (init_config_t *this);
 
        /**
         * @brief Get other host information as host_t object.
@@ -110,7 +64,7 @@ struct init_config_t {
         * @param this  calling object
         * @return              host information as host_t object
         */
-       host_t * (*get_other_host) (init_config_t *this);
+       host_t *(*get_other_host) (init_config_t *this);
        
        /**
         * @brief Get my host information as host_t object.
@@ -120,7 +74,7 @@ struct init_config_t {
         * @param this  calling object
         * @return              host information as host_t object
         */
-       host_t * (*get_my_host_clone) (init_config_t *this);
+       host_t *(*get_my_host_clone) (init_config_t *this);
 
        /**
         * @brief Get other host information as host_t object.
@@ -130,54 +84,60 @@ struct init_config_t {
         * @param this  calling object
         * @return              host information as host_t object
         */
-       host_t * (*get_other_host_clone) (init_config_t *this);
+       host_t *(*get_other_host_clone) (init_config_t *this);
        
        /**
-        * @brief Get the diffie hellman group to use as initiator with given priority.
+        * @brief Returns a list of all supported proposals.
         * 
-        * @param this          calling object
-        * @param priority      priority of dh group number (starting at 1)
-        * @return                      diffie hellman group number for given priority or 
-        *                                      MODP_UNDEFINED for not supported priorities
-        */
-       diffie_hellman_group_t (*get_dh_group_number) (init_config_t *this,size_t priority);
-       
-       /**
-        * @brief Returns a list of all supported ike_proposals of type ike_proposal_t *.
-        * 
-        * Returned array of ike_proposal_t has to get destroyed by the caller.
+        * Returned list is still owned by init_config and MUST NOT
+        * modified or destroyed.
         * 
         * @param this                          calling object
-        * @param proposals                     first proposal in a array
-        * @return                                      number of proposals in array
+        * @return                                      list containing all the proposals
         */
-       size_t (*get_proposals) (init_config_t *this,ike_proposal_t **proposals);
+       linked_list_t *(*get_proposals) (init_config_t *this);
        
        /**
-        * @brief Adds a proposal with given priority to the current stored proposals.
+        * @brief Adds a proposal to the list..
         * 
-        * If allready a proposal with given priority is stored the other one is 
-        * moved one priority back. If priority is higher then all other stored 
-        * proposals, it is inserted as last one.
+        * The first added proposal has the highest priority, the last
+        * added the lowest.
         * 
         * @param this                          calling object
         * @param priority                      priority of adding proposal
         * @param proposal                      proposal to add
         */
-       void (*add_proposal) (init_config_t *this,size_t priority, ike_proposal_t proposal);
+       void (*add_proposal) (init_config_t *this, proposal_t *proposal);
        
        /**
         * @brief Select a proposed from suggested proposals.
         * 
+        * Returned proposal must be destroyed after usage.
+        * 
+        * @param this                                  calling object
+        * @param proposals                             list of proposals to select from
+        * @return                                              selected proposal, or NULL if none matches.
+        */
+       proposal_t *(*select_proposal) (init_config_t *this, linked_list_t *proposals);
+       
+       /**
+        * @brief Get the DH group to use for connection initialization.
+        * 
+        * @param this                                  calling object
+        * @return                                              dh group to use for initialization
+        */
+       diffie_hellman_group_t (*get_dh_group) (init_config_t *this);
+       
+       /**
+        * @brief Check if a suggested dh group is acceptable.
+        * 
+        * If we guess a wrong DH group for IKE_SA_INIT, the other
+        * peer will send us a offer. But is this acceptable for us?
+        * 
         * @param this                                  calling object
-        * @param suggested_proposals   first proposal in a array
-        * @param proposal_count                number of suggested proposals in array
-        * @param selected_proposal             the ike_proposal_t pointing to is set
-        * @return                                              
-        *                                                              - SUCCESS if a proposal was selected
-        *                                                              - NOT_FOUND if none of suggested proposals is supported
+        * @return                                              dh group to use for initialization
         */
-       status_t (*select_proposal) (init_config_t *this, ike_proposal_t *proposals, size_t proposal_count, ike_proposal_t *selected_proposal);
+       bool (*check_dh_group) (init_config_t *this, diffie_hellman_group_t dh_group);
        
        /**
         * @brief Destroys a init_config_t object.
@@ -194,6 +154,6 @@ struct init_config_t {
  * 
  * @ingroup config
  */
-init_config_t * init_config_create(char * my_ip, char *other_ip, u_int16_t my_port, u_int16_t other_port);
+init_config_t * init_config_create(char *my_ip, char *other_ip, u_int16_t my_port, u_int16_t other_port);
 
 #endif //_INIT_CONFIG_H_
diff --git a/Source/charon/config/proposal.c b/Source/charon/config/proposal.c
new file mode 100644 (file)
index 0000000..528cf98
--- /dev/null
@@ -0,0 +1,583 @@
+/**
+ * @file proposal.c
+ * 
+ * @brief Implementation of proposal_t.
+ * 
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "proposal.h"
+
+#include <utils/linked_list.h>
+#include <utils/allocator.h>
+#include <utils/identification.h>
+#include <utils/logger.h>
+
+
+/** 
+ * String mappings for protocol_id_t.
+ */
+mapping_t protocol_id_m[] = {
+       {UNDEFINED_PROTOCOL_ID, "UNDEFINED_PROTOCOL_ID"},
+       {IKE, "IKE"},
+       {AH, "AH"},
+       {ESP, "ESP"},
+       {MAPPING_END, NULL}
+};
+
+/** 
+ * String mappings for transform_type_t.
+ */
+mapping_t transform_type_m[] = {
+       {UNDEFINED_TRANSFORM_TYPE, "UNDEFINED_TRANSFORM_TYPE"},
+       {ENCRYPTION_ALGORITHM, "ENCRYPTION_ALGORITHM"},
+       {PSEUDO_RANDOM_FUNCTION, "PSEUDO_RANDOM_FUNCTION"},
+       {INTEGRITY_ALGORITHM, "INTEGRITY_ALGORITHM"},
+       {DIFFIE_HELLMAN_GROUP, "DIFFIE_HELLMAN_GROUP"},
+       {EXTENDED_SEQUENCE_NUMBERS, "EXTENDED_SEQUENCE_NUMBERS"},
+       {MAPPING_END, NULL}
+};
+
+/** 
+ * String mappings for extended_sequence_numbers_t.
+ */
+mapping_t extended_sequence_numbers_m[] = {
+       {NO_EXT_SEQ_NUMBERS, "NO_EXT_SEQ_NUMBERS"},
+       {EXT_SEQ_NUMBERS, "EXT_SEQ_NUMBERS"},
+       {MAPPING_END, NULL}
+};
+
+
+typedef struct protocol_proposal_t protocol_proposal_t;
+
+/**
+ * substructure which holds all data algos for a specific protocol
+ */
+struct protocol_proposal_t {
+       /**
+        * protocol (ESP or AH)
+        */
+       protocol_id_t protocol;
+       
+       /**
+        * priority ordered list of encryption algorithms
+        */
+       linked_list_t *encryption_algos;
+       
+       /**
+        * priority ordered list of integrity algorithms
+        */
+       linked_list_t *integrity_algos;
+       
+       /**
+        * priority ordered list of pseudo random functions
+        */
+       linked_list_t *prf_algos;
+       
+       /**
+        * priority ordered list of dh groups
+        */
+       linked_list_t *dh_groups;
+       
+       /**
+        * priority ordered list of extended sequence number flags
+       */
+       linked_list_t *esns;
+       
+       /** 
+        * senders SPI
+        */
+       chunk_t spi;
+};
+
+
+typedef struct private_proposal_t private_proposal_t;
+
+/**
+ * Private data of an proposal_t object
+ */
+struct private_proposal_t {
+
+       /**
+        * Public part
+        */
+       proposal_t public;
+       
+       /**
+        * number of this proposal, as used in the payload
+        */
+       u_int8_t number;
+       
+       /**
+        * list of protocol_proposal_t's
+        */
+       linked_list_t *protocol_proposals;
+};
+
+/**
+ * Look up a protocol_proposal, or create one if necessary...
+ */
+static protocol_proposal_t *get_protocol_proposal(private_proposal_t *this, protocol_id_t proto, bool create)
+{
+       protocol_proposal_t *proto_proposal = NULL, *current_proto_proposal;;
+       iterator_t *iterator;
+        
+       /* find our protocol in the proposals */
+       iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
+       while (iterator->has_next(iterator))
+       {
+               iterator->current(iterator, (void**)&current_proto_proposal);
+               if (current_proto_proposal->protocol == proto)
+               {
+                       proto_proposal = current_proto_proposal;
+                       break;
+               }
+       }
+       iterator->destroy(iterator);
+
+       if (!proto_proposal && create)
+       {
+               /* nope, create a new one */
+               proto_proposal = allocator_alloc_thing(protocol_proposal_t);
+               proto_proposal->protocol = proto;
+               proto_proposal->encryption_algos = linked_list_create();
+               proto_proposal->integrity_algos = linked_list_create();
+               proto_proposal->prf_algos = linked_list_create();
+               proto_proposal->dh_groups = linked_list_create();
+               proto_proposal->esns = linked_list_create();
+               if (proto == IKE)
+               {
+                       proto_proposal->spi.len = 8;
+               }
+               else
+               {
+                       proto_proposal->spi.len = 4;
+               }
+               proto_proposal->spi.ptr = allocator_alloc(proto_proposal->spi.len);
+               /* add to the list */
+               this->protocol_proposals->insert_last(this->protocol_proposals, (void*)proto_proposal);
+       }
+       return proto_proposal;
+}
+
+/**
+ * Add algorithm/keysize to a algorithm list
+ */
+static void add_algo(linked_list_t *list, u_int8_t algo, size_t key_size)
+{
+       algorithm_t *algo_key = allocator_alloc_thing(algorithm_t);
+       
+       algo_key->algorithm = algo;
+       algo_key->key_size = key_size;
+       list->insert_last(list, (void*)algo_key);
+}
+
+/**
+ * Implements proposal_t.add_algorithm
+ */
+static void add_algorithm(private_proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t algo, size_t key_size)
+{
+       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, TRUE);
+       
+       switch (type)
+       {
+               case ENCRYPTION_ALGORITHM:
+                       add_algo(proto_proposal->encryption_algos, algo, key_size);
+                       break;
+               case INTEGRITY_ALGORITHM:
+                       add_algo(proto_proposal->integrity_algos, algo, key_size);
+                       break;
+               case PSEUDO_RANDOM_FUNCTION:
+                       add_algo(proto_proposal->prf_algos, algo, key_size);
+                       break;
+               case DIFFIE_HELLMAN_GROUP:
+                       add_algo(proto_proposal->dh_groups, algo, 0);
+                       break;
+               case EXTENDED_SEQUENCE_NUMBERS:
+                       add_algo(proto_proposal->esns, algo, 0);
+                       break;
+               default:
+                       break;
+       }
+}
+
+/**
+ * Implements proposal_t.get_algorithm.
+ */
+static bool get_algorithm(private_proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo)
+{
+       linked_list_t * list;
+       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
+       
+       if (proto_proposal == NULL)
+       {
+               return FALSE;
+       }
+       switch (type)
+       {
+               case ENCRYPTION_ALGORITHM:
+                       list = proto_proposal->encryption_algos;
+                       break;
+               case INTEGRITY_ALGORITHM:
+                       list = proto_proposal->integrity_algos;
+                       break;
+               case PSEUDO_RANDOM_FUNCTION:
+                       list = proto_proposal->prf_algos;
+                       break;
+               case DIFFIE_HELLMAN_GROUP:
+                       list = proto_proposal->dh_groups;
+                       break;
+               case EXTENDED_SEQUENCE_NUMBERS:
+                       list = proto_proposal->esns;
+                       break;
+               default:
+                       return FALSE;
+       }
+       if (list->get_first(list, (void**)algo) != SUCCESS)
+       {
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/**
+ * Implements proposal_t.create_algorithm_iterator.
+ */
+static iterator_t *create_algorithm_iterator(private_proposal_t *this, protocol_id_t proto, transform_type_t type)
+{
+       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
+       if (proto_proposal == NULL)
+       {
+               return NULL;
+       }
+       
+       switch (type)
+       {
+               case ENCRYPTION_ALGORITHM:
+                       return proto_proposal->encryption_algos->create_iterator(proto_proposal->encryption_algos, TRUE);
+               case INTEGRITY_ALGORITHM:
+                       return proto_proposal->integrity_algos->create_iterator(proto_proposal->integrity_algos, TRUE);
+               case PSEUDO_RANDOM_FUNCTION:
+                       return proto_proposal->prf_algos->create_iterator(proto_proposal->prf_algos, TRUE);
+               case DIFFIE_HELLMAN_GROUP:
+                       return proto_proposal->dh_groups->create_iterator(proto_proposal->dh_groups, TRUE);
+               case EXTENDED_SEQUENCE_NUMBERS:
+                       return proto_proposal->esns->create_iterator(proto_proposal->esns, TRUE);
+               default:
+                       break;
+       }
+       return NULL;
+}
+
+/**
+ * Find a matching alg/keysize in two linked lists
+ */
+static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add, u_int16_t *alg, size_t *key_size)
+{
+       iterator_t *first_iter, *second_iter;
+       algorithm_t *first_alg, *second_alg;
+       
+       /* if in both are zero algorithms specified, we HAVE a match */
+       if (first->get_count(first) == 0 && second->get_count(second) == 0)
+       {
+               *add = FALSE;
+               return TRUE;
+       }
+       
+       first_iter = first->create_iterator(first, TRUE);
+       second_iter = second->create_iterator(second, TRUE);
+       /* compare algs, order of algs in "first" is preferred */
+       while (first_iter->has_next(first_iter))
+       {
+               first_iter->current(first_iter, (void**)&first_alg);
+               second_iter->reset(second_iter);
+               while (second_iter->has_next(second_iter))
+               {
+                       second_iter->current(second_iter, (void**)&second_alg);
+                       if (first_alg->algorithm == second_alg->algorithm &&
+                               first_alg->key_size == second_alg->key_size)
+                       {
+                               /* ok, we have an algorithm */
+                               *alg = first_alg->algorithm;
+                               *key_size = first_alg->key_size;
+                               *add = TRUE;
+                               first_iter->destroy(first_iter);
+                               second_iter->destroy(second_iter);
+                               return TRUE;
+                       }
+               }
+       }
+       /* no match in all comparisons */
+       first_iter->destroy(first_iter);
+       second_iter->destroy(second_iter);
+       return FALSE;
+}
+
+/**
+ * Implements proposal_t.select.
+ */
+static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t *other)
+{
+       proposal_t *selected;
+       u_int16_t algo;
+       size_t key_size;
+       iterator_t *iterator;
+       protocol_proposal_t *this_prop, *other_prop;
+       protocol_id_t proto;
+       bool add;
+       
+       /* empty proposal? no match */
+       if (this->protocol_proposals->get_count(this->protocol_proposals) == 0 ||
+               other->protocol_proposals->get_count(other->protocol_proposals) == 0)
+       {
+               return NULL;
+       }
+       /* they MUST have the same amount of protocols */
+       if (this->protocol_proposals->get_count(this->protocol_proposals) !=
+               other->protocol_proposals->get_count(other->protocol_proposals))
+       {
+               return NULL;
+       }
+       
+       selected = proposal_create(this->number);
+       
+       /* iterate over supplied proposals */
+       iterator = other->protocol_proposals->create_iterator(other->protocol_proposals, TRUE);
+       while (iterator->has_next(iterator))
+       {
+               iterator->current(iterator, (void**)&other_prop);
+               /* get the proposal with the same protocol */
+               proto = other_prop->protocol;
+               this_prop = get_protocol_proposal(this, proto, FALSE);
+               
+               if (this_prop == NULL)
+               {
+                       iterator->destroy(iterator);
+                       selected->destroy(selected);
+                       return NULL;
+               }
+               
+               /* select encryption algorithm */
+               if (select_algo(this_prop->encryption_algos, other_prop->encryption_algos, &add, &algo, &key_size))
+               {
+                       if (add)
+                       {
+                               selected->add_algorithm(selected, proto, ENCRYPTION_ALGORITHM, algo, key_size);
+                       }
+               }
+               else
+               {
+                       iterator->destroy(iterator);
+                       selected->destroy(selected);
+                       return NULL;
+               }
+               /* select integrity algorithm */
+               if (select_algo(this_prop->integrity_algos, other_prop->integrity_algos, &add, &algo, &key_size))
+               {
+                       if (add)
+                       {
+                               selected->add_algorithm(selected, proto, INTEGRITY_ALGORITHM, algo, key_size);
+                       }
+               }
+               else
+               {
+                       iterator->destroy(iterator);
+                       selected->destroy(selected);
+                       return NULL;
+               }
+               /* select prf algorithm */
+               if (select_algo(this_prop->prf_algos, other_prop->prf_algos, &add, &algo, &key_size))
+               {
+                       if (add)
+                       {
+                               selected->add_algorithm(selected, proto, PSEUDO_RANDOM_FUNCTION, algo, key_size);
+                       }
+               }
+               else
+               {
+                       iterator->destroy(iterator);
+                       selected->destroy(selected);
+                       return NULL;
+               }
+               /* select a DH-group */
+               if (select_algo(this_prop->dh_groups, other_prop->dh_groups, &add, &algo, &key_size))
+               {
+                       if (add)
+                       {
+                               selected->add_algorithm(selected, proto, DIFFIE_HELLMAN_GROUP, algo, 0);
+                       }
+               }
+               else
+               {
+                       iterator->destroy(iterator);
+                       selected->destroy(selected);
+                       return NULL;
+               }
+               /* select if we use ESNs */
+               if (select_algo(this_prop->esns, other_prop->esns, &add, &algo, &key_size))
+               {
+                       if (add)
+                       {
+                               selected->add_algorithm(selected, proto, EXTENDED_SEQUENCE_NUMBERS, algo, 0);
+                       }
+               }
+               else
+               {
+                       iterator->destroy(iterator);
+                       selected->destroy(selected);
+                       return NULL;
+               }
+       }
+       iterator->destroy(iterator);
+       /* everything matched, return new proposal */
+       return selected;
+}
+
+/**
+ * Implements proposal_t.get_number.
+ */
+static u_int8_t get_number(private_proposal_t *this)
+{
+       return this->number;
+}
+
+/**
+ * Implements proposal_t.get_protocols.
+ */
+static void get_protocols(private_proposal_t *this, protocol_id_t ids[2])
+{
+       iterator_t *iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
+       u_int i = 0;
+       
+       ids[0] = UNDEFINED_PROTOCOL_ID;
+       ids[1] = UNDEFINED_PROTOCOL_ID;
+       while (iterator->has_next(iterator))
+       {
+               protocol_proposal_t *proto_prop;
+               iterator->current(iterator, (void**)&proto_prop);
+               ids[i++] = proto_prop->protocol;
+               if (i>1)
+               {
+                       /* should not happen, but who knows */
+                       break;
+               }
+       }
+       iterator->destroy(iterator);
+}
+
+/**
+ * Implements proposal_t.set_spi.
+ */
+static void set_spi(private_proposal_t *this, protocol_id_t proto, u_int64_t spi)
+{
+       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
+       if (proto_proposal)
+       {
+               if (proto == IKE)
+               {
+                       *((u_int32_t*)proto_proposal->spi.ptr) = (u_int32_t)spi;
+               }
+               else
+               {
+                       *((u_int64_t*)proto_proposal->spi.ptr) = spi;
+               }
+               
+       }
+}
+
+/**
+ * Implements proposal_t.get_spi.
+ */
+static u_int64_t get_spi(private_proposal_t *this, protocol_id_t proto)
+{
+       protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
+       if (proto_proposal)
+       {
+               if (proto == IKE)
+               {
+                       return (u_int64_t)*((u_int32_t*)proto_proposal->spi.ptr);
+               }
+               else
+               {
+                       return *((u_int64_t*)proto_proposal->spi.ptr);
+               }
+       }
+       return 0;
+}
+
+/**
+ * Frees all list items and destroys the list
+ */
+static void free_algo_list(linked_list_t *list)
+{
+       algorithm_t *algo;
+       
+       while(list->get_count(list) > 0)
+       {
+               list->remove_last(list, (void**)&algo);
+               allocator_free(algo);
+       }
+       list->destroy(list);
+}
+
+/**
+ * Implements proposal_t.destroy.
+ */
+static void destroy(private_proposal_t *this)
+{
+       while(this->protocol_proposals->get_count(this->protocol_proposals) > 0)
+       {
+               protocol_proposal_t *proto_prop;
+               this->protocol_proposals->remove_last(this->protocol_proposals, (void**)&proto_prop);
+               
+               free_algo_list(proto_prop->encryption_algos);
+               free_algo_list(proto_prop->integrity_algos);
+               free_algo_list(proto_prop->prf_algos);
+               free_algo_list(proto_prop->dh_groups);
+               free_algo_list(proto_prop->esns);
+               
+               allocator_free(proto_prop->spi.ptr);
+               allocator_free(proto_prop);
+       }
+       this->protocol_proposals->destroy(this->protocol_proposals);
+       
+       allocator_free(this);
+}
+
+/*
+ * Describtion in header-file
+ */
+proposal_t *proposal_create(u_int8_t number)
+{
+       private_proposal_t *this = allocator_alloc_thing(private_proposal_t);
+       
+       this->public.add_algorithm = (void (*)(proposal_t*,protocol_id_t,transform_type_t,u_int16_t,size_t))add_algorithm;
+       this->public.create_algorithm_iterator = (iterator_t* (*)(proposal_t*,protocol_id_t,transform_type_t))create_algorithm_iterator;
+       this->public.get_algorithm = (bool (*)(proposal_t*,protocol_id_t,transform_type_t,algorithm_t**))get_algorithm;
+       this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*))select_proposal;
+       this->public.get_number = (u_int8_t (*)(proposal_t*))get_number;
+       this->public.get_protocols = (void(*)(proposal_t *this, protocol_id_t ids[2]))get_protocols;
+       this->public.set_spi = (void(*)(proposal_t*,protocol_id_t,u_int64_t spi))set_spi;
+       this->public.get_spi = (u_int64_t(*)(proposal_t*,protocol_id_t))get_spi;
+       this->public.destroy = (void(*)(proposal_t*))destroy;
+       
+       /* init private members*/
+       this->number = number;
+       this->protocol_proposals = linked_list_create();
+       
+       return (&this->public);
+}
diff --git a/Source/charon/config/proposal.h b/Source/charon/config/proposal.h
new file mode 100644 (file)
index 0000000..53d417b
--- /dev/null
@@ -0,0 +1,253 @@
+/**
+ * @file proposal.h
+ * 
+ * @brief Interface of proposal_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _PROPOSAL_H_
+#define _PROPOSAL_H_
+
+#include <types.h>
+#include <utils/identification.h>
+#include <utils/linked_list.h>
+#include <network/host.h>
+#include <transforms/crypters/crypter.h>
+#include <transforms/signers/signer.h>
+#include <transforms/diffie_hellman.h>
+#include <config/traffic_selector.h>
+
+
+typedef enum protocol_id_t protocol_id_t;
+
+/**
+ * Protocol ID of a proposal.
+ * 
+ * @ingroup config
+ */
+enum protocol_id_t {
+       UNDEFINED_PROTOCOL_ID = 201,
+       IKE = 1,
+       AH = 2,
+       ESP = 3,
+};
+
+/** 
+ * String mappings for protocol_id_t.
+ * 
+ * @ingroup config
+ */
+extern mapping_t protocol_id_m[];
+
+
+typedef enum transform_type_t transform_type_t;
+
+/**
+ * Type of a transform, as in IKEv2 draft 3.3.2.
+ * 
+ * @ingroup payloads
+ */
+enum transform_type_t {
+       UNDEFINED_TRANSFORM_TYPE = 241,
+       ENCRYPTION_ALGORITHM = 1,
+       PSEUDO_RANDOM_FUNCTION = 2,
+       INTEGRITY_ALGORITHM = 3,
+       DIFFIE_HELLMAN_GROUP = 4,
+       EXTENDED_SEQUENCE_NUMBERS = 5
+};
+
+/** 
+ * String mappings for transform_type_t.
+ * 
+ * @ingroup payloads
+ */
+extern mapping_t transform_type_m[];
+
+
+typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
+
+/** 
+ * Extended sequence numbers, as in IKEv2 draft 3.3.2.
+ * 
+ * @ingroup payloads
+ */
+enum extended_sequence_numbers_t {
+       NO_EXT_SEQ_NUMBERS = 0,
+       EXT_SEQ_NUMBERS = 1
+};
+
+/** 
+ * String mappings for extended_sequence_numbers_t.
+ * 
+ * @ingroup payloads
+ */
+extern mapping_t extended_sequence_numbers_m[];
+
+
+typedef struct algorithm_t algorithm_t;
+
+/**
+ * Struct used to store different kinds of algorithms. The internal
+ * lists of algorithms contain such structures.
+ */
+struct algorithm_t {
+       /**
+        * Value from an encryption_algorithm_t/integrity_algorithm_t/...
+        */
+       u_int16_t algorithm;
+       
+       /**
+        * the associated key size, or zero if not needed
+        */
+       u_int16_t key_size;
+};
+
+typedef struct proposal_t proposal_t;
+
+/**
+ * @brief Stores a proposal for a child SA.
+ * 
+ * A proposal may contain more than one algorithm
+ * of the same kind. ONE of them can be selected.
+ *
+ * @warning This class is NOT thread-save!
+ * 
+ * @b Constructors:
+ *   - proposal_create()
+ * 
+ * @ingroup config
+ */
+struct proposal_t {
+       
+       /**
+        * @brief Add an algorithm to the proposal.
+        * 
+        * The algorithms are stored by priority, first added
+        * is the most preferred.
+        * Key size is only needed for encryption algorithms
+        * with variable key size (such as AES), or integrity
+        * algorithms.
+        * The alg parameter accepts encryption_algorithm_t,
+        * integrity_algorithm_t, dh_group_number_t and
+        * extended_sequence_numbers_t.
+        * 
+        * @warning Do not add while other threads are reading.
+        * 
+        * @param this                                  calling object
+        * @param proto                                 desired protocol
+        * @param type                                  kind of algorithm
+        * @param alg                                   identifier for algorithm
+        * @param key_size                              key size to use
+        */
+       void (*add_algorithm) (proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t alg, size_t key_size);
+       
+       /**
+        * @brief Get an iterator over algorithms for a specifc protocol/algo type.
+        * 
+        * @param this                                  calling object
+        * @param proto                                 desired protocol
+        * @param type                                  kind of algorithm
+        * @return                                              iterator over algorithms
+        */
+       iterator_t *(*create_algorithm_iterator) (proposal_t *this, protocol_id_t proto, transform_type_t type);
+       
+       /**
+        * @brief Get the algorithm for a type to use.
+        * 
+        * If there are multiple algorithms, only the first is returned.
+        * Result is still owned by proposal, do not modify!
+        * 
+        * @param this                                  calling object
+        * @param proto                                 desired protocol
+        * @param type                                  kind of algorithm
+        * @param[out] algo                             pointer which receives algorithm and key size
+        * @return                                              TRUE if algorithm of this kind available
+        */
+       bool (*get_algorithm) (proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo);
+
+       /**
+        * @brief Compare two proposal, and select a matching subset.
+        * 
+        * If the proposals are for the same protocols (AH/ESP), they are
+        * compared. If they have at least one algorithm of each type
+        * in common, a resulting proposal of this kind is created.
+        * 
+        * @param this                                  calling object
+        * @param other                                 proposal to compair agains
+        * @return                                              
+        *                                                              - selected proposal, if possible
+        *                                                              - NULL, if proposals don't match
+        */
+       proposal_t *(*select) (proposal_t *this, proposal_t *other);
+       
+       /**
+        * @brief Get the number set on construction.
+        * 
+        * @param this                          calling object
+        * @return                                      number
+        */
+       u_int8_t (*get_number) (proposal_t *this);
+       
+       /**
+        * @brief Get the protocol ids in the proposals.
+        * 
+        * With AH and ESP, there could be two protocols in one
+        * proposal.
+        * 
+        * @param this                          calling object
+        * @param ids                           array of protocol ids, 
+        */
+       void (*get_protocols) (proposal_t *this, protocol_id_t ids[2]);
+       
+       /**
+        * @brief Get the spi for a specific protocol.
+        * 
+        * @param this                          calling object
+        * @param proto                         AH/ESP
+        * @return                                      spi for proto
+        */
+       u_int64_t (*get_spi) (proposal_t *this, protocol_id_t proto);
+       
+       /**
+        * @brief Set the spi for a specific protocol.
+        * 
+        * @param this                          calling object
+        * @param proto                         AH/ESP
+        * @param spi                           spi to set for proto
+        */
+       void (*set_spi) (proposal_t *this, protocol_id_t proto, u_int64_t spi);
+       
+       /**
+        * @brief Destroys the proposal object.
+        * 
+        * @param this                          calling object
+        */
+       void (*destroy) (proposal_t *this);
+};
+
+/**
+ * @brief Create a child proposal for AH and/or ESP.
+ * 
+ * @param number                       number of the proposal, as in the payload
+ * @return                                     proposal_t object
+ * 
+ * @ingroup config
+ */
+proposal_t *proposal_create(u_int8_t number);
+
+#endif //_PROPOSAL_H_
index ca29b02..6e7f8ee 100644 (file)
@@ -216,10 +216,10 @@ static linked_list_t *get_proposals(private_sa_config_t *this)
 /**
  * Implementation of sa_config_t.select_proposal
  */
-static child_proposal_t *select_proposal(private_sa_config_t *this, linked_list_t *proposals)
+static proposal_t *select_proposal(private_sa_config_t *this, linked_list_t *proposals)
 {
        iterator_t *stored_iter, *supplied_iter;
-       child_proposal_t *stored, *supplied, *selected;
+       proposal_t *stored, *supplied, *selected;
        
        stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
        supplied_iter = proposals->create_iterator(proposals, TRUE);
@@ -272,7 +272,7 @@ static void add_traffic_selector_responder(private_sa_config_t *this, traffic_se
 /**
  * Implementation of sa_config_t.add_proposal
  */
-static void add_proposal(private_sa_config_t *this, child_proposal_t *proposal)
+static void add_proposal(private_sa_config_t *this, proposal_t *proposal)
 {
        this->proposals->insert_last(this->proposals, (void*)proposal);
 }
@@ -282,7 +282,7 @@ static void add_proposal(private_sa_config_t *this, child_proposal_t *proposal)
  */
 static status_t destroy(private_sa_config_t *this)
 {      
-       child_proposal_t *proposal;
+       proposal_t *proposal;
        traffic_selector_t *traffic_selector;
        
        
@@ -332,10 +332,10 @@ sa_config_t *sa_config_create(id_type_t my_id_type, char *my_id, id_type_t other
        this->public.get_traffic_selectors_responder = (size_t(*)(sa_config_t*,traffic_selector_t**[]))get_traffic_selectors_responder;
        this->public.select_traffic_selectors_responder = (size_t(*)(sa_config_t*,traffic_selector_t*[],size_t,traffic_selector_t**[]))select_traffic_selectors_responder;
        this->public.get_proposals = (linked_list_t*(*)(sa_config_t*))get_proposals;
-       this->public.select_proposal = (child_proposal_t*(*)(sa_config_t*,linked_list_t*))select_proposal;
+       this->public.select_proposal = (proposal_t*(*)(sa_config_t*,linked_list_t*))select_proposal;
        this->public.add_traffic_selector_initiator = (void(*)(sa_config_t*,traffic_selector_t*))add_traffic_selector_initiator;
        this->public.add_traffic_selector_responder = (void(*)(sa_config_t*,traffic_selector_t*))add_traffic_selector_responder;
-       this->public.add_proposal = (void(*)(sa_config_t*,child_proposal_t*))add_proposal;
+       this->public.add_proposal = (void(*)(sa_config_t*,proposal_t*))add_proposal;
        this->public.destroy = (void(*)(sa_config_t*))destroy;
        
        /* apply init values */
index fd19528..4fd7305 100644 (file)
@@ -32,7 +32,7 @@
 #include <transforms/signers/signer.h>
 #include <transforms/diffie_hellman.h>
 #include <config/traffic_selector.h>
-#include <config/child_proposal.h>
+#include <config/proposal.h>
 
 
 
@@ -174,7 +174,7 @@ struct sa_config_t {
         * @param proposals                             list from from wich proposals are selected
         * @return                                              selected proposal, or NULL if nothing matches
         */
-       child_proposal_t *(*select_proposal) (sa_config_t *this, linked_list_t *proposals);
+       proposal_t *(*select_proposal) (sa_config_t *this, linked_list_t *proposals);
        
        /**
         * @brief Add a traffic selector to the list for initiator.
@@ -211,7 +211,7 @@ struct sa_config_t {
         * @param this                                  calling object
         * @param proposal                              proposal to add
         */
-       void (*add_proposal) (sa_config_t *this, child_proposal_t *proposal);
+       void (*add_proposal) (sa_config_t *this, proposal_t *proposal);
        
        /**
         * @brief Destroys the config object
index 4650c5c..343aecb 100644 (file)
@@ -97,7 +97,6 @@ struct daemon_t {
        /**
         * A send_queue_t instance.
         */
-        
        send_queue_t *send_queue;
        
        /**
index dccc9d1..ee4b44e 100644 (file)
@@ -180,8 +180,22 @@ static status_t verify(private_notify_payload_t *this)
                return FAILED;
        }
        
-       /* notify message types and data is not getting checked in here */
+       /* TODO: Check all kinds of notify */
        
+       if (this->notify_message_type == INVALID_KE_PAYLOAD)
+       {
+               /* check notification data */
+               diffie_hellman_group_t dh_group;
+               if (this->notification_data.len != 2)
+               {
+                       return FAILED;
+               }
+               dh_group = ntohs(*((u_int16_t*)this->notification_data.ptr));
+               if (dh_group < MODP_1024_BIT || dh_group > MODP_8192_BIT)
+               {
+                       return FAILED;
+               }
+       }
        return SUCCESS;
 }
 
index a2ba15b..2cf96fb 100644 (file)
@@ -406,9 +406,9 @@ static size_t get_spi_size (private_proposal_substructure_t *this)
 }
 
 /**
- * Implementation of proposal_substructure_t.add_to_child_proposal.
+ * Implementation of proposal_substructure_t.add_to_proposal.
  */
-void add_to_child_proposal(private_proposal_substructure_t *this, child_proposal_t *proposal)
+void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal)
 {
        iterator_t *iterator = this->transforms->create_iterator(this->transforms, TRUE);
        
@@ -525,7 +525,7 @@ proposal_substructure_t *proposal_substructure_create()
        this->public.get_protocol_id = (u_int8_t (*) (proposal_substructure_t *)) get_protocol_id;
        this->public.get_info_for_transform_type =      (status_t (*) (proposal_substructure_t *,transform_type_t,u_int16_t *, u_int16_t *))get_info_for_transform_type;
        this->public.set_is_last_proposal = (void (*) (proposal_substructure_t *,bool)) set_is_last_proposal;
-       this->public.add_to_child_proposal = (void (*) (proposal_substructure_t*,child_proposal_t*))add_to_child_proposal;
+       this->public.add_to_proposal = (void (*) (proposal_substructure_t*,proposal_t*))add_to_proposal;
        this->public.set_spi = (void (*) (proposal_substructure_t *,chunk_t))set_spi;
        this->public.get_spi = (chunk_t (*) (proposal_substructure_t *)) get_spi;
        this->public.get_transform_count = (size_t (*) (proposal_substructure_t *)) get_transform_count;
@@ -554,7 +554,7 @@ proposal_substructure_t *proposal_substructure_create()
 /*
  * Described in header.
  */
-proposal_substructure_t *proposal_substructure_create_from_child_proposal(child_proposal_t *proposal, protocol_id_t proto)
+proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto)
 {
        private_proposal_substructure_t *this = (private_proposal_substructure_t*)proposal_substructure_create();
        iterator_t *iterator;
index 0247584..2270a52 100644 (file)
@@ -26,7 +26,7 @@
 #include <types.h>
 #include <encoding/payloads/payload.h>
 #include <encoding/payloads/transform_substructure.h>
-#include <config/child_proposal.h>
+#include <config/proposal.h>
 #include <utils/linked_list.h>
 
 
@@ -173,7 +173,7 @@ struct proposal_substructure_t {
         */
        void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
        
-       void (*add_to_child_proposal) (proposal_substructure_t *this, child_proposal_t *proposal);
+       void (*add_to_proposal) (proposal_substructure_t *this, proposal_t *proposal);
 
        /**
         * @brief Clones an proposal_substructure_t object.
@@ -201,7 +201,7 @@ struct proposal_substructure_t {
 proposal_substructure_t *proposal_substructure_create();
 
 /**
- * @brief Creates a proposal substructure from a child_proposal.
+ * @brief Creates a proposal substructure from a proposal.
  * 
  * Since a child proposal may contain data for both AH and ESP, 
  * the protocol must be specified. If the proposal does not contain
@@ -215,7 +215,7 @@ proposal_substructure_t *proposal_substructure_create();
  * 
  * @ingroup payloads
  */
-proposal_substructure_t *proposal_substructure_create_from_child_proposal(child_proposal_t *proposal, protocol_id_t proto);
+proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto);
 
 
 #endif /*PROPOSAL_SUBSTRUCTURE_H_*/
index 90f8698..3a40d41 100644 (file)
@@ -257,9 +257,9 @@ static void add_proposal_substructure (private_sa_payload_t *this,proposal_subst
 }
 
 /**
- * Implementation of sa_payload_t.add_child_proposal.
+ * Implementation of sa_payload_t.add_proposal.
  */
-static void add_child_proposal(private_sa_payload_t *this, child_proposal_t *proposal)
+static void add_proposal(private_sa_payload_t *this, proposal_t *proposal)
 {
        proposal_substructure_t *substructure;
        protocol_id_t proto[2];
@@ -271,161 +271,26 @@ static void add_child_proposal(private_sa_payload_t *this, child_proposal_t *pro
        {
                if (proto[i] != UNDEFINED_PROTOCOL_ID)
                {
-                       substructure = proposal_substructure_create_from_child_proposal(proposal, proto[i]);
+                       substructure = proposal_substructure_create_from_proposal(proposal, proto[i]);
                        add_proposal_substructure(this, substructure);
                }
        }
 }
 
-
 /**
- * Implementation of sa_payload_t.get_ike_proposals.
+ * Implementation of sa_payload_t.get_proposals.
  */
-static status_t get_ike_proposals (private_sa_payload_t *this,ike_proposal_t ** proposals, size_t *proposal_count)
-{
-       int found_ike_proposals = 0;
-       int current_proposal_number = 0;
-       iterator_t *iterator;
-       ike_proposal_t *tmp_proposals;
-       
-       iterator = this->proposals->create_iterator(this->proposals,TRUE);
-       
-       /* first find out the number of ike proposals and check their number of transforms and 
-        * if the SPI is empty!*/
-       while (iterator->has_next(iterator))
-       {
-               proposal_substructure_t *current_proposal;
-               iterator->current(iterator,(void **)&(current_proposal));
-               if (current_proposal->get_protocol_id(current_proposal) == IKE)
-               {
-                       /* a ike proposal consists of an empty spi*/
-                       if (current_proposal->get_spi_size(current_proposal) != 0)
-                   {
-                       iterator->destroy(iterator);
-                       return FAILED;
-                   }
-                       
-                       found_ike_proposals++;
-               }
-       }
-       iterator->reset(iterator);
-       
-       if (found_ike_proposals == 0)
-       {
-               iterator->destroy(iterator);
-               return NOT_FOUND;
-       }
-       
-       /* allocate memory to hold each proposal as ike_proposal_t */
-       
-       tmp_proposals = allocator_alloc(found_ike_proposals * sizeof(ike_proposal_t));
-       
-       /* create from each proposal_substructure a ike_proposal_t data area*/
-       while (iterator->has_next(iterator))
-       {
-               proposal_substructure_t *current_proposal;
-               iterator->current(iterator,(void **)&(current_proposal));
-               if (current_proposal->get_protocol_id(current_proposal) == IKE)
-               {
-                       bool encryption_algorithm_found = FALSE;
-                       bool integrity_algorithm_found = FALSE;
-                       bool pseudo_random_function_found = FALSE;
-                       bool diffie_hellman_group_found = FALSE;
-                       status_t status;
-                       iterator_t *transforms;
-                       
-                       transforms = current_proposal->create_transform_substructure_iterator(current_proposal,TRUE);
-                       while (transforms->has_next(transforms))
-                       {
-                               transform_substructure_t *current_transform;
-                               transforms->current(transforms,(void **)&(current_transform));
-                               
-                               switch (current_transform->get_transform_type(current_transform))
-                               {
-                                       case ENCRYPTION_ALGORITHM:
-                                       {
-                                               tmp_proposals[current_proposal_number].encryption_algorithm = current_transform->get_transform_id(current_transform);
-                                               status = current_transform->get_key_length(current_transform,&(tmp_proposals[current_proposal_number].encryption_algorithm_key_length));
-                                               if (status == SUCCESS)
-                                               {
-                                                       encryption_algorithm_found = TRUE;
-                                               }
-                                               break;
-                                       }
-                                       case INTEGRITY_ALGORITHM:
-                                       {
-                                               tmp_proposals[current_proposal_number].integrity_algorithm = current_transform->get_transform_id(current_transform);
-                                               status = current_transform->get_key_length(current_transform,&(tmp_proposals[current_proposal_number].integrity_algorithm_key_length));
-                                               if (status == SUCCESS)
-                                               {
-                                                       integrity_algorithm_found = TRUE;
-                                               }
-                                               break;
-                                       }
-                                       case PSEUDO_RANDOM_FUNCTION:
-                                       {
-                                               tmp_proposals[current_proposal_number].pseudo_random_function = current_transform->get_transform_id(current_transform);
-                                               status = current_transform->get_key_length(current_transform,&(tmp_proposals[current_proposal_number].pseudo_random_function_key_length));
-                                               if (status == SUCCESS)
-                                               {
-                                                       pseudo_random_function_found = TRUE;
-                                               }
-                                               break;
-                                       }
-                                       case DIFFIE_HELLMAN_GROUP:
-                                       {
-                                               tmp_proposals[current_proposal_number].diffie_hellman_group = current_transform->get_transform_id(current_transform);
-                                               diffie_hellman_group_found = TRUE;
-                                               break;
-                                       }
-                                       default:
-                                       {
-                                               /* not a transform of an ike proposal. Break here */
-                                               break;
-                                       }
-                               }
-                               
-                       }
-
-                       transforms->destroy(transforms);
-                       
-                       if ((!encryption_algorithm_found) ||
-                               (!integrity_algorithm_found) ||
-                               (!pseudo_random_function_found) ||
-                               (!diffie_hellman_group_found))
-                       {
-                               /* one of needed transforms could not be found */
-                               iterator->reset(iterator);
-                               allocator_free(tmp_proposals);
-                               return FAILED;
-                       }
-                       
-                       current_proposal_number++;
-               }
-       }
-
-       iterator->destroy(iterator);    
-       
-       *proposals = tmp_proposals;
-       *proposal_count = found_ike_proposals;
-
-       return SUCCESS;
-}
-
-/**
- * Implementation of sa_payload_t.get_child_proposals.
- */
-static linked_list_t *get_child_proposals(private_sa_payload_t *this)
+static linked_list_t *get_proposals(private_sa_payload_t *this)
 {
        int proposal_struct_number = 0;
        iterator_t *iterator;
-       child_proposal_t *proposal;
+       proposal_t *proposal;
        linked_list_t *proposal_list;
        
        /* this list will hold our proposals */
        proposal_list = linked_list_create();
        
-       /* iterate over structures, one OR MORE structures will result in a child_proposal */
+       /* iterate over structures, one OR MORE structures will result in a proposal */
        iterator = this->proposals->create_iterator(this->proposals,TRUE);
        while (iterator->has_next(iterator))
        {
@@ -436,11 +301,11 @@ static linked_list_t *get_child_proposals(private_sa_payload_t *this)
                {
                        /* here starts a new proposal, create a new one and add it to the list */
                        proposal_struct_number = proposal_struct->get_proposal_number(proposal_struct);
-                       proposal = child_proposal_create(proposal_struct_number);
+                       proposal = proposal_create(proposal_struct_number);
                        proposal_list->insert_last(proposal_list, proposal);
                }
                /* proposal_substructure_t does the dirty work and builds up the proposal */
-               proposal_struct->add_to_child_proposal(proposal_struct, proposal);
+               proposal_struct->add_to_proposal(proposal_struct, proposal);
        }
        iterator->destroy(iterator);
        return proposal_list;
@@ -484,8 +349,7 @@ sa_payload_t *sa_payload_create()
        /* public functions */
        this->public.create_proposal_substructure_iterator = (iterator_t* (*) (sa_payload_t *,bool)) create_proposal_substructure_iterator;
        this->public.add_proposal_substructure = (void (*) (sa_payload_t *,proposal_substructure_t *)) add_proposal_substructure;
-       this->public.get_ike_proposals = (status_t (*) (sa_payload_t *, ike_proposal_t **, size_t *)) get_ike_proposals;
-       this->public.get_child_proposals = (linked_list_t* (*) (sa_payload_t *)) get_child_proposals;
+       this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals;
        this->public.destroy = (void (*) (sa_payload_t *)) destroy;
        
        /* private functions */
@@ -503,52 +367,10 @@ sa_payload_t *sa_payload_create()
 /*
  * Described in header.
  */
-sa_payload_t *sa_payload_create_from_ike_proposals(ike_proposal_t *proposals, size_t proposal_count)
-{
-       int i;
-       sa_payload_t *sa_payload= sa_payload_create();
-       
-       for (i = 0; i < proposal_count; i++)
-       {
-               proposal_substructure_t *proposal_substructure;
-               transform_substructure_t *encryption_algorithm;
-               transform_substructure_t *integrity_algorithm;
-               transform_substructure_t *pseudo_random_function;
-               transform_substructure_t *diffie_hellman_group;
-               
-               /* create proposal substructure */
-               proposal_substructure = proposal_substructure_create();
-               proposal_substructure->set_protocol_id(proposal_substructure,IKE);
-               proposal_substructure->set_proposal_number(proposal_substructure,(i + 1));
-               
-
-               /* create transform substructures to hold each specific transform for an ike proposal */
-               encryption_algorithm = transform_substructure_create_type(ENCRYPTION_ALGORITHM,proposals[i].encryption_algorithm,proposals[i].encryption_algorithm_key_length);
-               proposal_substructure->add_transform_substructure(proposal_substructure,encryption_algorithm);
-               
-               pseudo_random_function = transform_substructure_create_type(PSEUDO_RANDOM_FUNCTION,proposals[i].pseudo_random_function,proposals[i].pseudo_random_function_key_length);
-               proposal_substructure->add_transform_substructure(proposal_substructure,pseudo_random_function);
-
-               integrity_algorithm = transform_substructure_create_type(INTEGRITY_ALGORITHM,proposals[i].integrity_algorithm,proposals[i].integrity_algorithm_key_length);
-               proposal_substructure->add_transform_substructure(proposal_substructure,integrity_algorithm);
-
-               diffie_hellman_group = transform_substructure_create_type(DIFFIE_HELLMAN_GROUP,proposals[i].diffie_hellman_group,0);
-               proposal_substructure->add_transform_substructure(proposal_substructure,diffie_hellman_group);
-               
-               /* add proposal to sa payload */
-               sa_payload->add_proposal_substructure(sa_payload,proposal_substructure);
-       }
-       
-       return sa_payload;
-}
-
-/*
- * Described in header.
- */
-sa_payload_t *sa_payload_create_from_child_proposal_list(linked_list_t *proposals)
+sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals)
 {
        iterator_t *iterator;
-       child_proposal_t *proposal;
+       proposal_t *proposal;
        sa_payload_t *sa_payload = sa_payload_create();
        
        /* add every payload from the list */
@@ -556,7 +378,7 @@ sa_payload_t *sa_payload_create_from_child_proposal_list(linked_list_t *proposal
        while (iterator->has_next(iterator))
        {
                iterator->current(iterator, (void**)&proposal);
-               add_child_proposal((private_sa_payload_t*)sa_payload, proposal);
+               add_proposal((private_sa_payload_t*)sa_payload, proposal);
        }
        iterator->destroy(iterator);
        
@@ -566,11 +388,11 @@ sa_payload_t *sa_payload_create_from_child_proposal_list(linked_list_t *proposal
 /*
  * Described in header.
  */
-sa_payload_t *sa_payload_create_from_child_proposal(child_proposal_t *proposal)
+sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal)
 {
        sa_payload_t *sa_payload = sa_payload_create();
        
-       add_child_proposal((private_sa_payload_t*)sa_payload, proposal);
+       add_proposal((private_sa_payload_t*)sa_payload, proposal);
        
        return sa_payload;
 }
index 0c54ae6..1f11d51 100644 (file)
@@ -54,9 +54,9 @@ typedef struct sa_payload_t sa_payload_t;
  * @b Constructors:
  * - sa_payload_create()
  * - sa_payload_create_from_ike_proposals()
- * - sa_payload_create_from_child_proposal()
+ * - sa_payload_create_from_proposal()
  * 
- * @todo Add support of algorithms without specified keylength in get_child_proposals and get_ike_proposals.
+ * @todo Add support of algorithms without specified keylength in get_proposals and get_ike_proposals.
  * 
  * @ingroup payloads
  */
@@ -91,36 +91,20 @@ struct sa_payload_t {
         * @param proposal              proposal_substructure_t object to add
         */
        void (*add_proposal_substructure) (sa_payload_t *this,proposal_substructure_t *proposal);
-       
-       /**
-        * @brief Creates an array of ike_proposal_t's in this SA payload.
-        * 
-        * An IKE proposal consist of transform of type ENCRYPTION_ALGORITHM,
-        * PSEUDO_RANDOM_FUNCTION, INTEGRITY_ALGORITHM and DIFFIE_HELLMAN_GROUP
-        * 
-        * @param proposals                     the pointer to the first entry of ike_proposal_t's is set
-        * @param proposal_count        the number of found proposals is written at this location
-        * @return
-        *                                                      - SUCCESS if an IKE proposal could be found
-        *                                                      - NOT_FOUND if no IKE proposal could be found
-        *                                                      - FAILED if a proposal does not contain all needed transforms
-        *                                                        for a IKE_PROPOSAL 
-        */
-       status_t (*get_ike_proposals) (sa_payload_t *this, ike_proposal_t **proposals, size_t *proposal_count);
-       
+
        /**
-        * @brief Creates an array of child_proposal_t's in this SA payload.
+        * @brief Gets the proposals in this payload as a list.
         * 
-        * @return                                      a list containing child_proposal_t s
+        * @return                                      a list containing proposal_t s
         */
-       linked_list_t *(*get_child_proposals) (sa_payload_t *this);
+       linked_list_t *(*get_proposals) (sa_payload_t *this);
        
        /**
         * @brief Add a child proposal (AH/ESP) to the payload.
         * 
         * @param proposal                      child proposal to add to the payload
         */
-       void (*add_child_proposal) (sa_payload_t *this, child_proposal_t *proposal);
+       void (*add_proposal) (sa_payload_t *this, proposal_t *proposal);
        
        /**
         * @brief Destroys an sa_payload_t object.
@@ -140,19 +124,26 @@ struct sa_payload_t {
 sa_payload_t *sa_payload_create();
 
 /**
- * @brief Creates a sa_payload_t object from array of ike_proposal_t's.
+ * @brief Creates a sa_payload_t object from a list of proposals.
  * 
- * @return                                     created sa_payload_t object
- * @param proposals                    pointer to first proposal in array of type ike_proposal_t
- * @param proposal_count       number of ike_proposal_t's in array
+ * @param proposals                    list of proposals to build the payload from
  * @return                                     sa_payload_t object
  * 
  * @ingroup payloads
  */
-sa_payload_t *sa_payload_create_from_ike_proposals(ike_proposal_t *proposals, size_t proposal_count);
+sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
 
-sa_payload_t *sa_payload_create_from_child_proposal_list(linked_list_t *proposals);
-
-sa_payload_t *sa_payload_create_from_child_proposal(child_proposal_t *proposal);
+/**
+ * @brief Creates a sa_payload_t object from a single proposal.
+ * 
+ * This is only for convenience. Use sa_payload_create_from_proposal_list
+ * if you want to add more than one proposal.
+ * 
+ * @param proposal                     proposal from which the payload should be built.
+ * @return                                     sa_payload_t object
+ * 
+ * @ingroup payloads
+ */
+sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal);
 
 #endif /*SA_PAYLOAD_H_*/
index 79dd101..62def33 100644 (file)
@@ -32,7 +32,7 @@
 #include <transforms/signers/signer.h>
 #include <transforms/prfs/prf.h>
 #include <transforms/crypters/crypter.h>
-#include <config/child_proposal.h>
+#include <config/proposal.h>
 
 
 /**
index 7d40c78..5aaa2d9 100644 (file)
@@ -116,6 +116,7 @@ static chunk_t allocate_octets(private_authenticator_t *this,
                                                                id_payload_t *my_id,
                                                                bool initiator)
 {
+       prf_t *prf;
        chunk_t id_chunk = my_id->get_data(my_id);
        u_int8_t id_with_header[4 + id_chunk.len];
        /*
@@ -139,23 +140,22 @@ static chunk_t allocate_octets(private_authenticator_t *this,
        
        if (initiator)
        {
-               this->prf->set_key(this->prf,this->ike_sa->get_key_pi(this->ike_sa));
+               prf = this->ike_sa->get_prf_auth_i(this->ike_sa);
        }
        else
        {
-               this->prf->set_key(this->prf,this->ike_sa->get_key_pr(this->ike_sa));
+               prf = this->ike_sa->get_prf_auth_r(this->ike_sa);
        }
-
        
        /* 4 bytes are id type and reserved fields of id payload */
-       octets.len = last_message.len + other_nonce.len + this->prf->get_block_size(this->prf);
+       octets.len = last_message.len + other_nonce.len + prf->get_block_size(prf);
        octets.ptr = allocator_alloc(octets.len);
        current_pos = octets.ptr;
        memcpy(current_pos,last_message.ptr,last_message.len);
        current_pos += last_message.len;
        memcpy(current_pos,other_nonce.ptr,other_nonce.len);
        current_pos += other_nonce.len;
-       this->prf->get_bytes(this->prf,id_with_header_chunk,current_pos);
+       prf->get_bytes(prf, id_with_header_chunk, current_pos);
        
        this->logger->log_chunk(this->logger,RAW | LEVEL2, "Octets (Mesage + Nonce + prf(Sk_px,Idx)",&octets);
        return octets;
index c18b760..2c46243 100644 (file)
@@ -70,7 +70,7 @@ static void destroy(private_child_sa_t *this)
 /*
  * Described in header.
  */
-child_sa_t * child_sa_create(child_proposal_t *proposal, prf_plus_t *prf_plus)
+child_sa_t * child_sa_create(proposal_t *proposal, prf_plus_t *prf_plus)
 {
        private_child_sa_t *this = allocator_alloc_thing(private_child_sa_t);
        u_int i;
index 8a74625..bde032b 100644 (file)
@@ -67,6 +67,6 @@ struct child_sa_t {
  * @return                             child_sa_t object
  * @ingroup sa
  */
-child_sa_t * child_sa_create(child_proposal_t *proposal, prf_plus_t *prf_plus);
+child_sa_t * child_sa_create(proposal_t *proposal, prf_plus_t *prf_plus);
 
 #endif /*_CHILD_SA_H_*/
index 2f403ab..ac617fa 100644 (file)
@@ -57,15 +57,6 @@ struct private_ike_sa_t {
         * Protected part of a ike_sa_t object.
         */
        protected_ike_sa_t protected;
-
-       /**
-        * Resends the last sent reply.
-        * 
-        * @param this                          calling object
-        */
-       status_t (*resend_last_reply) (private_ike_sa_t *this);
-
-       /* private values */
        
        /**
         * Identifier for the current IKE_SA.
@@ -152,112 +143,43 @@ struct private_ike_sa_t {
        
        /**
         * Crypter object for initiator.
-        * 
-        * Gets set in states:
-        *  - IKE_SA_INIT_REQUESTED
-        *  - RESPONDER_INIT
-        * 
-        * Available in states:
-        *  - IKE_SA_INIT_RESPONDED
-        *  - IKE_AUTH_REQUESTED
-        *   -IKE_SA_ESTABLISHED
         */
        crypter_t *crypter_initiator;
        
        /**
         * Crypter object for responder.
-        * 
-        * Gets set in states:
-        *  - IKE_SA_INIT_REQUESTED
-        *  - RESPONDER_INIT
-        * 
-        * Available in states:
-        *  - IKE_SA_INIT_RESPONDED
-        *  - IKE_AUTH_REQUESTED
-        *   -IKE_SA_ESTABLISHED
         */
        crypter_t *crypter_responder;
        
        /**
         * Signer object for initiator.
-        * 
-        * Gets set in states:
-        *  - IKE_SA_INIT_REQUESTED
-        *  - RESPONDER_INIT
-        * 
-        * Available in states:
-        *  - IKE_SA_INIT_RESPONDED
-        *  - IKE_AUTH_REQUESTED
-        *   -IKE_SA_ESTABLISHED
         */
        signer_t *signer_initiator;
        
        /**
         * Signer object for responder.
-        * 
-        * Gets set in states:
-        *  - IKE_SA_INIT_REQUESTED
-        *  - RESPONDER_INIT
-        * 
-        * Available in states:
-        *  - IKE_SA_INIT_RESPONDED
-        *  - IKE_AUTH_REQUESTED
-        *   -IKE_SA_ESTABLISHED
         */
        signer_t *signer_responder;
        
        /**
-        * Prf function.
-        * 
-        * Gets set in states:
-        *  - IKE_SA_INIT_REQUESTED
-        *  - RESPONDER_INIT
-        * 
-        * Available in states:
-        *  - IKE_SA_INIT_RESPONDED
-        *  - IKE_AUTH_REQUESTED
-        *   -IKE_SA_ESTABLISHED
+        * Multi purpose prf, set key, use it, forget it
         */
        prf_t *prf;
        
        /**
         * Prf function for derivating keymat child SAs
-        * 
-        * Gets set in states:
-        *  - IKE_SA_INIT_REQUESTED
-        *  - RESPONDER_INIT
-        * 
-        * Available in states:
-        *  - IKE_SA_INIT_RESPONDED
-        *  - IKE_AUTH_REQUESTED
-        *   -IKE_SA_ESTABLISHED
         */
        prf_t *child_prf;
        
        /**
-        * Shared secrets which have to be stored.
-        * 
-        * Are getting set in states:
-        *  - IKE_SA_INIT_REQUESTED
-        *  - RESPONDER_INIT
-        * 
-        * Available in states:
-        *  - IKE_SA_INIT_RESPONDED
-        *  - IKE_AUTH_REQUESTED
-        *   -IKE_SA_ESTABLISHED
+        * PRF, with key set to pi_key, used for authentication
         */
-       struct {
-               /**
-                * Key for generating auth payload (initiator)
-                */
-               chunk_t pi_key; 
-
-               /**
-                * Key for generating auth payload (responder)
-                */
-               chunk_t pr_key; 
+       prf_t *prf_auth_i;
 
-       } secrets;
+       /**
+        * PRF, with key set to pr_key, used for authentication
+        */
+       prf_t *prf_auth_r;
 
        /**
         * Next message id to receive.
@@ -278,6 +200,13 @@ struct private_ike_sa_t {
         * A logger for this IKE_SA.
         */
        logger_t *logger;
+
+       /**
+        * Resends the last sent reply.
+        * 
+        * @param this                          calling object
+        */
+       status_t (*resend_last_reply) (private_ike_sa_t *this);
 };
 
 /**
@@ -441,103 +370,6 @@ static ike_sa_id_t* get_id(private_ike_sa_t *this)
 }
 
 /**
- * Implementation of protected_ike_sa_t.compute_secrets.
- */
-static void compute_secrets(private_ike_sa_t *this,
-                                                       chunk_t dh_shared_secret,
-                                                       chunk_t initiator_nonce,
-                                                       chunk_t responder_nonce)
-{
-       u_int8_t d_buffer[this->child_prf->get_block_size(this->child_prf)];
-       chunk_t d_key = {ptr: d_buffer, len: sizeof(d_buffer)};
-       u_int8_t ei_buffer[this->crypter_initiator->get_block_size(this->crypter_initiator)];
-       chunk_t ei_key = {ptr: ei_buffer, len: sizeof(ei_buffer)};
-       u_int8_t er_buffer[this->crypter_responder->get_block_size(this->crypter_responder)];
-       chunk_t er_key = {ptr: er_buffer, len: sizeof(er_buffer)};
-       u_int8_t ai_buffer[this->signer_initiator->get_key_size(this->signer_initiator)];
-       chunk_t ai_key = {ptr: ai_buffer, len: sizeof(ai_buffer)};
-       u_int8_t ar_buffer[this->signer_responder->get_key_size(this->signer_responder)];
-       chunk_t ar_key = {ptr: ar_buffer, len: sizeof(ar_buffer)};
-       u_int8_t concatenated_nonces_buffer[initiator_nonce.len + responder_nonce.len];
-       chunk_t concatenated_nonces = {ptr: concatenated_nonces_buffer, len : sizeof(concatenated_nonces_buffer)};
-       u_int8_t skeyseed_buffer[this->prf->get_block_size(this->prf)];
-       chunk_t skeyseed = {ptr: skeyseed_buffer, len: sizeof(skeyseed_buffer)};
-       u_int64_t initiator_spi;
-       u_int64_t responder_spi;
-       chunk_t prf_plus_seed;
-       prf_plus_t *prf_plus;
-
-       /* first is initiator */
-       memcpy(concatenated_nonces.ptr,initiator_nonce.ptr,initiator_nonce.len);
-       /* second is responder */
-       memcpy(concatenated_nonces.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
-
-       this->logger->log_chunk(this->logger, RAW | LEVEL2, "Nonce data", &concatenated_nonces);
-
-       /* Status of set_key is not checked */
-       this->prf->set_key(this->prf,concatenated_nonces);
-
-       this->prf->get_bytes(this->prf,dh_shared_secret,skeyseed_buffer);
-
-       prf_plus_seed.len = (initiator_nonce.len + responder_nonce.len + 16);
-       prf_plus_seed.ptr = allocator_alloc(prf_plus_seed.len);
-       
-       /* first is initiator */
-       memcpy(prf_plus_seed.ptr,initiator_nonce.ptr,initiator_nonce.len);
-       /* second is responder */
-       memcpy(prf_plus_seed.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
-       /* third is initiator spi */
-       initiator_spi = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
-       memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len,&initiator_spi,8);
-       /* fourth is responder spi */
-       responder_spi = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
-       memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len + 8,&responder_spi,8);
-       
-       this->logger->log_chunk(this->logger, PRIVATE | LEVEL1, "Keyseed", &skeyseed);
-       this->logger->log_chunk(this->logger, PRIVATE | LEVEL1, "PRF+ Seed", &prf_plus_seed);
-
-       this->logger->log(this->logger, CONTROL | LEVEL2, "Set new key of prf object");
-       this->prf->set_key(this->prf,skeyseed);
-       this->logger->log(this->logger, CONTROL | LEVEL2, "Create new prf+ object");
-       prf_plus = prf_plus_create(this->prf, prf_plus_seed);
-       allocator_free_chunk(&prf_plus_seed);
-       
-       
-       prf_plus->get_bytes(prf_plus,d_key.len,d_buffer);
-       this->logger->log_chunk(this->logger, PRIVATE, "Sk_d secret", &(d_key));
-       this->child_prf->set_key(this->child_prf, d_key);
-
-       prf_plus->get_bytes(prf_plus,ai_key.len,ai_buffer);
-       this->logger->log_chunk(this->logger, PRIVATE, "Sk_ai secret", &(ai_key));
-       this->signer_initiator->set_key(this->signer_initiator,ai_key);
-
-       prf_plus->get_bytes(prf_plus,ar_key.len,ar_buffer);
-       this->logger->log_chunk(this->logger, PRIVATE, "Sk_ar secret", &(ar_key));
-       this->signer_responder->set_key(this->signer_responder,ar_key);
-
-       prf_plus->get_bytes(prf_plus,ei_key.len,ei_buffer);
-       this->logger->log_chunk(this->logger, PRIVATE, "Sk_ei secret", &(ei_key));
-       this->crypter_initiator->set_key(this->crypter_initiator,ei_key);
-       
-       prf_plus->get_bytes(prf_plus,er_key.len,er_buffer);
-       this->logger->log_chunk(this->logger, PRIVATE, "Sk_er secret", &(er_key));
-       this->crypter_responder->set_key(this->crypter_responder,er_key);
-
-       prf_plus->allocate_bytes(prf_plus,
-                                                               this->crypter_responder->get_block_size(this->crypter_responder),
-                                                               &(this->secrets.pi_key));
-       this->logger->log_chunk(this->logger, PRIVATE, "Sk_pi secret", &(this->secrets.pi_key));
-       
-       prf_plus->allocate_bytes(prf_plus,
-                                                               this->crypter_responder->get_block_size(this->crypter_responder),
-                                                               &(this->secrets.pr_key));
-       this->logger->log_chunk(this->logger, PRIVATE, "Sk_pr secret", &(this->secrets.pr_key));
-       
-       prf_plus->destroy(prf_plus);
-}
-
-/**
  * Implementation of private_ike_sa_t.resend_last_reply.
  */
 static status_t resend_last_reply(private_ike_sa_t *this)
@@ -680,97 +512,209 @@ static prf_t *get_child_prf (private_ike_sa_t *this)
 }
 
 /**
- * Implementation of protected_ike_sa_t.get_key_pr.
+ * Implementation of protected_ike_sa_t.get_prf_auth_i.
  */
-static chunk_t get_key_pr (private_ike_sa_t *this)
+static prf_t *get_prf_auth_i (private_ike_sa_t *this)
 {
-       return this->secrets.pr_key;
+       return this->prf_auth_i;
 }
 
-
 /**
- * Implementation of protected_ike_sa_t.get_key_pi.
+ * Implementation of protected_ike_sa_t.get_prf_auth_r.
  */
-static chunk_t get_key_pi (private_ike_sa_t *this)
+static prf_t *get_prf_auth_r (private_ike_sa_t *this)
 {
-       return this->secrets.pi_key;
+       return this->prf_auth_r;
 }
 
+
 /**
- * Implementation of protected_ike_sa_t.set_prf.
+ * Implementation of protected_ike_sa_t.build_transforms.
  */
-static status_t create_transforms_from_proposal (private_ike_sa_t *this,ike_proposal_t *proposal)
+static status_t build_transforms(private_ike_sa_t *this, proposal_t *proposal, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r)
 {
-       this->logger->log(this->logger, CONTROL|LEVEL2, "Going to create transform objects for proposal");
-       
-       this->logger->log(this->logger, CONTROL|LEVEL2, "Encryption algorithm: %s with keylength %d",
-                                               mapping_find(encryption_algorithm_m,proposal->encryption_algorithm),
-                                               proposal->encryption_algorithm_key_length);
-       this->logger->log(this->logger, CONTROL|LEVEL2, "Integrity algorithm: %s with keylength %d",
-                                               mapping_find(integrity_algorithm_m,proposal->integrity_algorithm),
-                                               proposal->integrity_algorithm_key_length);
-       this->logger->log(this->logger, CONTROL|LEVEL2, "PRF: %s with keylength %d",
-                                               mapping_find(pseudo_random_function_m,proposal->pseudo_random_function),
-                                               proposal->pseudo_random_function_key_length);
+       chunk_t nonces, nonces_spis, skeyseed, key, secret;
+       u_int64_t spi_i, spi_r;
+       prf_plus_t *prf_plus;
+       algorithm_t *algo;
+       size_t key_size;
        
+       /*
+        * Build the PRF+ instance for deriving keys
+        */
        if (this->prf != NULL)
        {
                this->prf->destroy(this->prf);
        }
-       this->prf = prf_create(proposal->pseudo_random_function);
-       if (this->prf == NULL)
+       proposal->get_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, &algo);
+       if (algo == NULL)
        {
-               this->logger->log(this->logger, ERROR|LEVEL1, "PRF %s not supported!",
-                                                       mapping_find(pseudo_random_function_m,proposal->pseudo_random_function));
+               this->logger->log(this->logger, ERROR|LEVEL2, "No PRF algoithm selected!?");
                return FAILED;
        }
-       this->child_prf = prf_create(proposal->pseudo_random_function);
-       if (this->child_prf == NULL)
+       this->prf = prf_create(algo->algorithm);
+       if (this->prf == NULL)
        {
-               this->logger->log(this->logger, ERROR|LEVEL1, "PRF %s not supported!",
-                                                 mapping_find(pseudo_random_function_m,proposal->pseudo_random_function));
+               this->logger->log(this->logger, ERROR|LEVEL1, 
+                                                 "PSEUDO_RANDOM_FUNCTION %s not supported!",
+                                                 mapping_find(pseudo_random_function_m, algo->algorithm));
                return FAILED;
        }
        
-       if (this->crypter_initiator != NULL)
+       /* concatenate nonces =  nonce_i | nonce_r */
+       nonces = allocator_alloc_as_chunk(nonce_i.len + nonce_r.len);
+       memcpy(nonces.ptr, nonce_i.ptr, nonce_i.len);
+       memcpy(nonces.ptr + nonce_i.len, nonce_r.ptr, nonce_r.len);
+
+       /* concatenate prf_seed = nonce_i | nonce_r | spi_i | spi_r */
+       nonces_spis = allocator_alloc_as_chunk(nonces.len + 16);
+       memcpy(nonces_spis.ptr, nonces.ptr, nonces.len);
+       spi_i = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
+       spi_r = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
+       memcpy(nonces_spis.ptr + nonces.len, &spi_i, 8);
+       memcpy(nonces_spis.ptr + nonces.len + 8, &spi_r, 8);
+       
+       /* SKEYSEED = prf(Ni | Nr, g^ir) */
+       dh->get_shared_secret(dh, &secret);
+       this->logger->log_chunk(this->logger, PRIVATE, "Shared Diffie Hellman secret", &secret);
+       this->prf->set_key(this->prf, nonces);
+       this->prf->allocate_bytes(this->prf, secret, &skeyseed);
+       this->logger->log_chunk(this->logger, PRIVATE | LEVEL1, "SKEYSEED", &skeyseed);
+       allocator_free_chunk(&secret);
+
+       /* prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr )
+        * = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr
+        *
+        * we use the prf directly for prf+ 
+        */
+       this->prf->set_key(this->prf, skeyseed);
+       prf_plus = prf_plus_create(this->prf, nonces_spis);
+       
+       /* clean up unused stuff */
+       allocator_free_chunk(&nonces);
+       allocator_free_chunk(&nonces_spis);
+       allocator_free_chunk(&skeyseed);
+       
+       
+       /*
+        * We now can derive all of our key. We build the transforms 
+        * directly.
+        */
+       
+       
+       /* SK_d used for prf+ to derive keys for child SAs */
+       this->child_prf = prf_create(algo->algorithm);
+       key_size = this->child_prf->get_key_size(this->child_prf);
+       prf_plus->allocate_bytes(prf_plus, key_size, &key);
+       this->logger->log_chunk(this->logger, PRIVATE, "Sk_d secret", &key);
+       this->child_prf->set_key(this->child_prf, key);
+       allocator_free_chunk(&key);
+       
+       
+       /* SK_ai/SK_ar used for integrity protection */
+       proposal->get_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, &algo);
+       if (algo == NULL)
        {
-               this->crypter_initiator->destroy(this->crypter_initiator);
+               this->logger->log(this->logger, ERROR|LEVEL2, "No integrity algoithm selected?!");
+               return FAILED;
        }
-       this->crypter_initiator = crypter_create(proposal->encryption_algorithm,
-                                                                                               proposal->encryption_algorithm_key_length);
-       if (this->crypter_initiator == NULL)
+       if (this->signer_initiator != NULL)
+       {
+               this->signer_initiator->destroy(this->signer_initiator);
+       }
+       if (this->signer_responder != NULL)
        {
-               this->logger->log(this->logger, ERROR|LEVEL1, "Encryption algorithm %s not supported!",
-                                                 mapping_find(encryption_algorithm_m,proposal->encryption_algorithm));
+               this->signer_responder->destroy(this->signer_responder);
+       }
+       
+       this->signer_initiator = signer_create(algo->algorithm);
+       this->signer_responder = signer_create(algo->algorithm);
+       if (this->signer_initiator == NULL || this->signer_responder == NULL)
+       {
+               this->logger->log(this->logger, ERROR|LEVEL1, 
+                                                 "INTEGRITY_ALGORITHM %s not supported!",
+                                                 mapping_find(integrity_algorithm_m,algo->algorithm));
                return FAILED;
        }
+       key_size = this->signer_initiator->get_key_size(this->signer_initiator);
+       
+       prf_plus->allocate_bytes(prf_plus, key_size, &key);
+       this->logger->log_chunk(this->logger, PRIVATE, "Sk_ai secret", &key);
+       this->signer_initiator->set_key(this->signer_initiator, key);
+       allocator_free_chunk(&key);
 
+       prf_plus->allocate_bytes(prf_plus, key_size, &key);
+       this->logger->log_chunk(this->logger, PRIVATE, "Sk_ar secret", &key);
+       this->signer_responder->set_key(this->signer_responder, key);
+       allocator_free_chunk(&key);
+       
+       
+       /* SK_ei/SK_er used for encryption */
+       proposal->get_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, &algo);
+       if (algo == NULL)
+       {
+               this->logger->log(this->logger, ERROR|LEVEL2, "No encryption algoithm selected!?");
+               return FAILED;
+       }
+       if (this->crypter_initiator != NULL)
+       {
+               this->crypter_initiator->destroy(this->crypter_initiator);
+       }
        if (this->crypter_responder != NULL)
        {
                this->crypter_responder->destroy(this->crypter_responder);
        }
-       this->crypter_responder = crypter_create(proposal->encryption_algorithm,
-                                                                                               proposal->encryption_algorithm_key_length);
-       /* check must not be done again */
        
-       if (this->signer_initiator != NULL)
+       this->crypter_initiator = crypter_create(algo->algorithm, algo->key_size);
+       this->crypter_responder = crypter_create(algo->algorithm, algo->key_size);
+       if (this->crypter_initiator == NULL || this->crypter_responder == NULL)
        {
-               this->signer_initiator->destroy(this->signer_initiator);
-       }
-       this->signer_initiator = signer_create(proposal->integrity_algorithm);
-       if (this->signer_initiator == NULL)
-       {
-               this->logger->log(this->logger, ERROR|LEVEL1, "Integrity algorithm %s not supported!",
-                                                       mapping_find(integrity_algorithm_m,proposal->integrity_algorithm));
+               this->logger->log(this->logger, ERROR|LEVEL1, 
+                                                 "ENCRYPTION_ALGORITHM %s (key size %d) not supported!",
+                                                 mapping_find(encryption_algorithm_m, algo->algorithm),
+                                                 algo->key_size);
                return FAILED;
        }
+       key_size = this->crypter_initiator->get_key_size(this->crypter_initiator);
        
-       if (this->signer_responder != NULL)
+       prf_plus->allocate_bytes(prf_plus, key_size, &key);
+       this->logger->log_chunk(this->logger, PRIVATE, "Sk_ei secret", &key);
+       this->crypter_initiator->set_key(this->crypter_initiator, key);
+       allocator_free_chunk(&key);
+       
+       prf_plus->allocate_bytes(prf_plus, key_size, &key);
+       this->logger->log_chunk(this->logger, PRIVATE, "Sk_er secret", &key);
+       this->crypter_responder->set_key(this->crypter_responder, key);
+       allocator_free_chunk(&key);
+       
+       /* SK_pi/SK_pr used for authentication */
+       proposal->get_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, &algo);
+       if (this->prf_auth_i != NULL)
        {
-               this->signer_responder->destroy(this->signer_responder);
+               this->prf_auth_i->destroy(this->prf_auth_i);
        }
-       this->signer_responder = signer_create(proposal->integrity_algorithm);
-
+       if (this->prf_auth_r != NULL)
+       {
+               this->prf_auth_r->destroy(this->prf_auth_r);
+       }
+       
+       this->prf_auth_i = prf_create(algo->algorithm);
+       this->prf_auth_r = prf_create(algo->algorithm);
+       
+       key_size = this->prf_auth_i->get_key_size(this->prf_auth_i);
+       prf_plus->allocate_bytes(prf_plus, key_size, &key);
+       this->logger->log_chunk(this->logger, PRIVATE, "Sk_pi secret", &key);
+       this->prf_auth_i->set_key(this->prf_auth_i, key);
+       allocator_free_chunk(&key);
+       
+       prf_plus->allocate_bytes(prf_plus, key_size, &key);
+       this->logger->log_chunk(this->logger, PRIVATE, "Sk_pr secret", &key);
+       this->prf_auth_r->set_key(this->prf_auth_r, key);
+       allocator_free_chunk(&key);
+       
+       /* all done, prf_plus not needed anymore */
+       prf_plus->destroy(prf_plus);
+       
        return SUCCESS;
 }
 
@@ -1081,10 +1025,6 @@ static void destroy (private_ike_sa_t *this)
                /* destroy child sa */
        }
        this->child_sas->destroy(this->child_sas);
-
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy secrets");
-       allocator_free(this->secrets.pi_key.ptr);
-       allocator_free(this->secrets.pr_key.ptr);
        
        if (this->crypter_initiator != NULL)
        {
@@ -1120,6 +1060,14 @@ static void destroy (private_ike_sa_t *this)
                this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy child_prf object");
                this->child_prf->destroy(this->child_prf);
        }
+       if (this->prf_auth_i != NULL)
+       {
+               this->prf_auth_i->destroy(this->prf_auth_i);
+       }
+       if (this->prf_auth_r != NULL)
+       {
+               this->prf_auth_r->destroy(this->prf_auth_r);
+       }
        
        /* destroy ike_sa_id */
        this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy ike_sa_id object");
@@ -1182,11 +1130,10 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        
        /* protected functions */
        this->protected.build_message = (void (*) (protected_ike_sa_t *, exchange_type_t , bool , message_t **)) build_message;
-       this->protected.compute_secrets = (void (*) (protected_ike_sa_t *,chunk_t ,chunk_t , chunk_t )) compute_secrets;
        this->protected.get_prf = (prf_t *(*) (protected_ike_sa_t *)) get_prf;  
-       this->protected.get_child_prf = (prf_t *(*) (protected_ike_sa_t *)) get_child_prf;      
-       this->protected.get_key_pr = (chunk_t (*) (protected_ike_sa_t *)) get_key_pr;   
-       this->protected.get_key_pi = (chunk_t (*) (protected_ike_sa_t *)) get_key_pi;   
+       this->protected.get_child_prf = (prf_t *(*) (protected_ike_sa_t *)) get_child_prf;
+       this->protected.get_prf_auth_i = (prf_t *(*) (protected_ike_sa_t *)) get_prf_auth_i;
+       this->protected.get_prf_auth_r = (prf_t *(*) (protected_ike_sa_t *)) get_prf_auth_r;
        this->protected.get_logger = (logger_t *(*) (protected_ike_sa_t *)) get_logger;         
        this->protected.set_init_config = (void (*) (protected_ike_sa_t *,init_config_t *)) set_init_config;
        this->protected.get_init_config = (init_config_t *(*) (protected_ike_sa_t *)) get_init_config;
@@ -1200,7 +1147,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->protected.send_request = (status_t (*) (protected_ike_sa_t *,message_t *)) send_request;
        this->protected.send_response = (status_t (*) (protected_ike_sa_t *,message_t *)) send_response;
        this->protected.send_notify = (void (*)(protected_ike_sa_t*,exchange_type_t,notify_message_type_t,chunk_t)) send_notify;
-       this->protected.create_transforms_from_proposal = (status_t (*) (protected_ike_sa_t *,ike_proposal_t *)) create_transforms_from_proposal;
+       this->protected.build_transforms = (status_t (*) (protected_ike_sa_t *,proposal_t*,diffie_hellman_t*,chunk_t,chunk_t)) build_transforms;
        this->protected.set_new_state = (void (*) (protected_ike_sa_t *,state_t *)) set_new_state;
        this->protected.get_crypter_initiator = (crypter_t *(*) (protected_ike_sa_t *)) get_crypter_initiator;
        this->protected.get_signer_initiator = (signer_t *(*) (protected_ike_sa_t *)) get_signer_initiator;     
@@ -1230,13 +1177,13 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->message_id_out = 0;
        this->message_id_in = 0;
        this->last_replied_message_id = -1;
-       this->secrets.pi_key = CHUNK_INITIALIZER;
-       this->secrets.pr_key = CHUNK_INITIALIZER;
        this->crypter_initiator = NULL;
        this->crypter_responder = NULL;
        this->signer_initiator = NULL;
        this->signer_responder = NULL;
        this->prf = NULL;
+       this->prf_auth_i = NULL;
+       this->prf_auth_r = NULL;
        this->child_prf = NULL;
        this->init_config = NULL;
        this->sa_config = NULL;
index 09101f7..f5591a0 100644 (file)
@@ -163,22 +163,6 @@ struct protected_ike_sa_t {
         * @param message                       new message is stored at this location
         */
        void (*build_message) (protected_ike_sa_t *this, exchange_type_t type, bool request, message_t **message);
-
-       /**
-        * @brief Compute the shared secrets needed for encryption, signing, etc.
-        * 
-        * Preconditions:
-        *  - Call of function protected_ike_sa_t.create_transforms_from_proposal
-        * 
-        * @param this                          calling object
-        * @param dh_shared_secret      shared secret of diffie hellman exchange
-        * @param initiator_nonce       nonce of initiator
-        * @param responder_nonce       nonce of responder
-        */
-       void (*compute_secrets) (protected_ike_sa_t *this,
-                                                               chunk_t dh_shared_secret,
-                                                               chunk_t initiator_nonce,
-                                                               chunk_t responder_nonce);
        
        /**
         * @brief Get the internal stored logger_t object for given ike_sa_t object.
@@ -259,16 +243,20 @@ struct protected_ike_sa_t {
        void (*set_other_host) (protected_ike_sa_t *this,host_t *other_host);
        
        /**
-        * @brief Create all needed transform objects for this IKE_SA using 
-        * the informations stored in a ike_proposal_t object.
+        * @brief Derive all keys and create the transforms for IKE communication.
         * 
+        * Keys are derived using the diffie hellman secret, nonces and internal
+        * stored SPIs. 
         * Allready existing objects get destroyed.
         * 
         * @param this                          calling object
-        * @param proposal                      proposal used to get informations for transform
-        *                                                      objects (algorithms, key lengths, etc.)
+        * @param proposal                      proposal which contains algorithms to use
+        * @param dh                            diffie hellman object with shared secret
+        * @param nonce_i                       initiators nonce
+        * @param nonce_r                       responders nonce
         */
-       status_t (*create_transforms_from_proposal) (protected_ike_sa_t *this,ike_proposal_t * proposal);
+       status_t (*build_transforms) (protected_ike_sa_t *this, proposal_t* proposal,
+                                                                diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r);
        
        /**
         * @brief Send the next request message.
@@ -368,7 +356,7 @@ struct protected_ike_sa_t {
        signer_t *(*get_signer_responder) (protected_ike_sa_t *this);
        
        /**
-        * @brief Get the internal stored prf_t object.
+        * @brief Get the multi purpose prf.
         * 
         * @param this                          calling object
         * @return                                      pointer to prf_t object
@@ -384,6 +372,22 @@ struct protected_ike_sa_t {
        prf_t *(*get_child_prf) (protected_ike_sa_t *this);
        
        /**
+        * @brief Get the prf used for authentication of initiator.
+        * 
+        * @param this                          calling object
+        * @return                                      pointer to prf_t object
+        */
+       prf_t *(*get_prf_auth_i) (protected_ike_sa_t *this);
+       
+       /**
+        * @brief Get the prf used for authentication of responder.
+        * 
+        * @param this                          calling object
+        * @return                                      pointer to prf_t object
+        */
+       prf_t *(*get_prf_auth_r) (protected_ike_sa_t *this);
+       
+       /**
         * @brief Get the last responded message.
         *  
         * @param this                          calling object
@@ -404,26 +408,6 @@ struct protected_ike_sa_t {
        message_t *(*get_last_requested_message) (protected_ike_sa_t *this);
 
        /**
-        * @brief Get the Shared key SK_pr.
-        * 
-        * Returned value is not cloned!
-        * 
-        * @param this                          calling object
-        * @return                                      SK_pr key
-        */
-       chunk_t (*get_key_pr) (protected_ike_sa_t *this);
-       
-       /**
-        * @brief Get the Shared key SK_pi.
-        * 
-        * Returned value is not cloned!
-        * 
-        * @param this                          calling object
-        * @return                                      SK_pi key
-        */
-       chunk_t (*get_key_pi) (protected_ike_sa_t *this);
-
-       /**
         * @brief Resets message counters and does destroy stored received and sent messages.
         * 
         * @param this                          calling object
index 60369ba..e655931 100644 (file)
@@ -326,14 +326,14 @@ static status_t process_idr_payload(private_ike_auth_requested_t *this, id_paylo
  */
 static status_t process_sa_payload(private_ike_auth_requested_t *this, sa_payload_t *sa_payload)
 {
-       child_proposal_t *proposal, *proposal_tmp;
+       proposal_t *proposal, *proposal_tmp;
        linked_list_t *proposal_list;
        child_sa_t *child_sa;
        chunk_t seed;
        prf_plus_t *prf_plus;
        
        /* get his selected proposal */
-       proposal_list = sa_payload->get_child_proposals(sa_payload);
+       proposal_list = sa_payload->get_proposals(sa_payload);
        /* check count of proposals */
        if (proposal_list->get_count(proposal_list) == 0)
        {
index 7636ecb..327eb2d 100644 (file)
@@ -70,17 +70,14 @@ struct private_ike_sa_init_requested_t {
        chunk_t received_nonce;
        
        /**
-        * Packet data of ike_sa_init request
+        * Selected proposal
         */
-       chunk_t ike_sa_init_request_data;
+       proposal_t *proposal;
        
        /**
-        * DH group priority used to get dh_group_number from configuration manager.
-        * 
-        * Is passed to the next state object of type INITATOR_INIT if the selected group number 
-        * is not the same as in the peers selected proposal.
+        * Packet data of ike_sa_init request
         */
-       u_int16_t dh_group_priority;
+       chunk_t ike_sa_init_request_data;
        
        /**
         * Assigned logger
@@ -329,7 +326,15 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
        {
                return status;
        }
-
+       
+       /* derive all the keys used in the IKE_SA */
+       status = this->ike_sa->build_transforms(this->ike_sa, this->proposal, this->diffie_hellman, this->sent_nonce, this->received_nonce);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger, AUDIT, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
+               return DELETE_ME;
+       }
+       
        /*  build empty message */
        this->ike_sa->build_message(this->ike_sa, IKE_AUTH, TRUE, &request);
        
@@ -402,45 +407,39 @@ status_t process_nonce_payload (private_ike_sa_init_requested_t *this, nonce_pay
  */
 status_t process_sa_payload (private_ike_sa_init_requested_t *this, sa_payload_t *sa_payload)
 {
-       ike_proposal_t selected_proposal;
-       ike_proposal_t *ike_proposals;
+       proposal_t *proposal;
+       linked_list_t *proposal_list;
        init_config_t *init_config;
-       size_t proposal_count;
-       status_t status;
        
        init_config = this->ike_sa->get_init_config(this->ike_sa);
        
-       /* get the list of selected proposals */ 
-       status = sa_payload->get_ike_proposals (sa_payload, &ike_proposals,&proposal_count);
-       if (status != SUCCESS)
+       /* get the list of selected proposals, the peer has to select only one proposal */
+       proposal_list = sa_payload->get_proposals (sa_payload);
+       if (proposal_list->get_count(proposal_list) != 1)
        {
-               this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response did not contain any proposals. Deleting IKE_SA");
-               return DELETE_ME;       
+               this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response did not contain a single proposal. Deleting IKE_SA");
+               while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
+               {
+                       proposal->destroy(proposal);
+               }
+               proposal_list->destroy(proposal_list);
+               return DELETE_ME;
        }
-       /* the peer has to select only one proposal */
-       if (proposal_count != 1)
+       
+       /* we have to re-check if the others selection is valid */
+       this->proposal = init_config->select_proposal(init_config, proposal_list);
+       while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
        {
-               this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response contained more than one proposal. Deleting IKE_SA");
-               allocator_free(ike_proposals);
-               return DELETE_ME;                                                       
+               proposal->destroy(proposal);
        }
+       proposal_list->destroy(proposal_list);
        
-       /* now let the configuration-manager check the selected proposals*/
-       this->logger->log(this->logger, CONTROL | LEVEL2, "Check selected proposal");
-       status = init_config->select_proposal (init_config,ike_proposals,1,&selected_proposal);
-       allocator_free(ike_proposals);
-       if (status != SUCCESS)
+       if (this->proposal == NULL)
        {
                this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response contained selected proposal we did not offer. Deleting IKE_SA");
                return DELETE_ME;
        }
-                               
-       status = this->ike_sa->create_transforms_from_proposal(this->ike_sa,&selected_proposal);        
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, AUDIT, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
-               return DELETE_ME;
-       }
+       
        return SUCCESS;
 }
 
@@ -448,24 +447,9 @@ status_t process_sa_payload (private_ike_sa_init_requested_t *this, sa_payload_t
  * Implementation of private_ike_sa_init_requested_t.process_ke_payload.
  */
 status_t process_ke_payload (private_ike_sa_init_requested_t *this, ke_payload_t *ke_payload)
-{
-       chunk_t shared_secret;
-       status_t status;
-       
+{      
        this->diffie_hellman->set_other_public_value(this->diffie_hellman, ke_payload->get_key_exchange_data(ke_payload));
        
-       /* store shared secret  
-        * status of dh object does not have to get checked cause other key is set
-        */
-       this->logger->log(this->logger, CONTROL | LEVEL2, "Retrieve shared secret and store it");
-       status = this->diffie_hellman->get_shared_secret(this->diffie_hellman, &shared_secret);         
-       this->logger->log_chunk(this->logger, PRIVATE, "Shared secret", &shared_secret);
-
-       this->logger->log(this->logger, CONTROL | LEVEL2, "Going to derive all secrets from shared secret");    
-       this->ike_sa->compute_secrets(this->ike_sa,shared_secret,this->sent_nonce, this->received_nonce);
-       
-       allocator_free_chunk(&(shared_secret));
-       
        return SUCCESS;
 }
 
@@ -528,7 +512,7 @@ static status_t build_sa_payload (private_ike_sa_init_requested_t *this, message
        /* get proposals form config, add to payload */
        sa_config = this->ike_sa->get_sa_config(this->ike_sa);
        proposal_list = sa_config->get_proposals(sa_config);
-       sa_payload = sa_payload_create_from_child_proposal_list(proposal_list);
+       sa_payload = sa_payload_create_from_proposal_list(proposal_list);
 
        /* TODO child sa stuff */
 
@@ -625,9 +609,25 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no
                case INVALID_KE_PAYLOAD:
                {
                        initiator_init_t *initiator_init_state;
-                       u_int16_t new_dh_group_priority;
+                       chunk_t notify_data;
+                       diffie_hellman_group_t dh_group;
+                       init_config_t *init_config;
+                       
+                       notify_data = notify_payload->get_notification_data(notify_payload);
+                       dh_group = ntohs(*((u_int16_t*)notify_data.ptr));
+                       
+                       this->logger->log(this->logger, ERROR|LEVEL1, "Peer wouldn't accept DH group, it requested %s!",
+                                                         mapping_find(diffie_hellman_group_m, dh_group));
+                       /* check if we can accept this dh group */
+                       init_config = this->ike_sa->get_init_config(this->ike_sa);
+                       if (!init_config->check_dh_group(init_config, dh_group))
+                       {
+                               this->logger->log(this->logger, AUDIT, 
+                                                                 "Peer does only accept DH group %s, which we do not accept! Aborting",
+                                                                 mapping_find(diffie_hellman_group_m, dh_group));
+                               return DELETE_ME;
+                       }
                        
-                       this->logger->log(this->logger, ERROR|LEVEL1, "Selected DH group is not the one in the proposal selected by the responder!");
                        /* Going to change state back to initiator_init_t */
                        this->logger->log(this->logger, CONTROL|LEVEL2, "Create next state object");
                        initiator_init_state = initiator_init_create(this->ike_sa);
@@ -644,15 +644,13 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no
 
                        this->logger->log(this->logger, CONTROL|LEVEL2, "Destroy old sate object");
                        this->logger->log(this->logger, CONTROL|LEVEL2, "Going to retry initialization of connection");
-                       new_dh_group_priority = this->dh_group_priority + 1;
                        
                        this->public.state_interface.destroy(&(this->public.state_interface));
-                       if (initiator_init_state->retry_initiate_connection (initiator_init_state,new_dh_group_priority) != SUCCESS)
+                       if (initiator_init_state->retry_initiate_connection (initiator_init_state, dh_group) != SUCCESS)
                        {
                                return DELETE_ME;
                        }
                        return FAILED;
-
                }
                default:
                {
@@ -676,7 +674,6 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no
        }
 }
 
-
 /**
  * Implementation of state_t.get_state.
  */
@@ -690,14 +687,13 @@ static ike_sa_state_t get_state(private_ike_sa_init_requested_t *this)
  */
 static void destroy_after_state_change (private_ike_sa_init_requested_t *this)
 {
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Going to destroy state of type ike_sa_init_requested_t after state change.");
-       
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy diffie hellman object");
        this->diffie_hellman->destroy(this->diffie_hellman);
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy ike_sa_init_request_data");  
        allocator_free_chunk(&(this->ike_sa_init_request_data));
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy object itself");
-       allocator_free(this);   
+       if (this->proposal)
+       {
+               this->proposal->destroy(this->proposal);
+       }
+       allocator_free(this);
 }
 
 /**
@@ -705,24 +701,21 @@ static void destroy_after_state_change (private_ike_sa_init_requested_t *this)
  */
 static void destroy(private_ike_sa_init_requested_t *this)
 {
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Going to destroy state of type ike_sa_init_requested_t");
-       
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy diffie hellman object");
        this->diffie_hellman->destroy(this->diffie_hellman);
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy sent nonce");        
        allocator_free(this->sent_nonce.ptr);
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy received nonce");
        allocator_free(this->received_nonce.ptr);
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy ike_sa_init_request_data");  
        allocator_free_chunk(&(this->ike_sa_init_request_data));
-       this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy object itself");
+       if (this->proposal)
+       {
+               this->proposal->destroy(this->proposal);
+       }
        allocator_free(this);
 }
 
 /* 
  * Described in header.
  */
-ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa, u_int16_t dh_group_priority, diffie_hellman_t *diffie_hellman, chunk_t sent_nonce,chunk_t ike_sa_init_request_data)
+ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa, diffie_hellman_t *diffie_hellman, chunk_t sent_nonce,chunk_t ike_sa_init_request_data)
 {
        private_ike_sa_init_requested_t *this = allocator_alloc_thing(private_ike_sa_init_requested_t);
        
@@ -748,9 +741,9 @@ ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa
        this->received_nonce = CHUNK_INITIALIZER;
        this->logger = this->ike_sa->get_logger(this->ike_sa);
        this->diffie_hellman = diffie_hellman;
+       this->proposal = NULL;
        this->sent_nonce = sent_nonce;
        this->ike_sa_init_request_data = ike_sa_init_request_data;
-       this->dh_group_priority = dh_group_priority;
        
        return &(this->public);
 }
index 7d4df6b..1fe0a6d 100644 (file)
@@ -53,7 +53,6 @@ struct ike_sa_init_requested_t {
  * Constructor of class ike_sa_init_requested_t.
  * 
  * @param ike_sa                                       assigned ike_sa
- * @param dh_group_priority                    the last used priority number to get the DH group for request
  * @param diffie_hellman                       diffie_hellman object use to retrieve shared secret
  * @param sent_nonce                           Sent nonce value
  * @param ike_sa_init_request_data     the binary representation of the IKE_SA_INIT request message
@@ -62,7 +61,6 @@ struct ike_sa_init_requested_t {
  * @ingroup states
  */
 ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa,
-                                                                                                               u_int16_t dh_group_priority,
                                                                                                                diffie_hellman_t *diffie_hellman,
                                                                                                                chunk_t sent_nonce,
                                                                                                                chunk_t ike_sa_init_request_data);
index 2c21992..536041d 100644 (file)
@@ -387,7 +387,7 @@ static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payl
  */
 static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_payload_t *request, message_t *response)
 {
-       child_proposal_t *proposal, *proposal_tmp;
+       proposal_t *proposal, *proposal_tmp;
        linked_list_t *proposal_list;
        sa_payload_t *sa_response;
        child_sa_t *child_sa;
@@ -397,7 +397,7 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
        /* TODO: child sa stuff */
        
        /* get proposals from request */
-       proposal_list = request->get_child_proposals(request);
+       proposal_list = request->get_proposals(request);
        if (proposal_list->get_count(proposal_list) == 0)
        {
                /* if the other side did not offer any proposals, we do not create child sa's */
@@ -426,7 +426,7 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
        }
        
        /* create payload with selected propsal */
-       sa_response = sa_payload_create_from_child_proposal(proposal);
+       sa_response = sa_payload_create_from_proposal(proposal);
        response->add_payload(response, (payload_t*)sa_response);
        
        /* install child SAs for AH and esp */
index 6ab698f..f27dcb5 100644 (file)
@@ -58,17 +58,6 @@ struct private_initiator_init_t {
        diffie_hellman_t *diffie_hellman;
        
        /**
-        * DH group number.
-        */
-       u_int16_t dh_group_number;
-       
-       /**
-        * DH group priority used to get dh_group_number from configuration manager.
-        * This priority is passed to the next state of type IKE_SA_INIT_REQUESTED.
-        */
-       u_int16_t dh_group_priority;
-       
-       /**
         * Sent nonce.
         * This nonce is passed to the next state of type IKE_SA_INIT_REQUESTED.
         */
@@ -124,49 +113,41 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name)
        init_config_t *init_config;
        sa_config_t *sa_config;
        status_t status;
-
+       diffie_hellman_group_t dh_group;
        
        this->logger->log(this->logger, CONTROL, "Initializing connection %s",name);
        
+       /* get configs */
        status = charon->configuration_manager->get_init_config_for_name(charon->configuration_manager,name,&init_config);
        if (status != SUCCESS)
        {       
                this->logger->log(this->logger, ERROR | LEVEL1, "Could not retrieve INIT configuration informations for %s",name);
                return DELETE_ME;
        }
-       
        this->ike_sa->set_init_config(this->ike_sa,init_config);
-       
        status = charon->configuration_manager->get_sa_config_for_name(charon->configuration_manager,name,&sa_config);
-       
        if (status != SUCCESS)
-       {       
+       {
                this->logger->log(this->logger, ERROR | LEVEL1, "Could not retrieve SA configuration informations for %s",name);
                return DELETE_ME;
        }
-       
        this->ike_sa->set_sa_config(this->ike_sa,sa_config);
        
        /* host informations are read from configuration */     
        this->ike_sa->set_other_host(this->ike_sa,init_config->get_other_host_clone(init_config));
        this->ike_sa->set_my_host(this->ike_sa,init_config->get_my_host_clone(init_config));
        
-       this->dh_group_number = init_config->get_dh_group_number(init_config,this->dh_group_priority);
-       if (this->dh_group_number == MODP_UNDEFINED)
-       {
-               this->logger->log(this->logger, AUDIT, "Could not find a matching diffie hellman group after %d. try. Aborting.", 
-                                                       this->dh_group_priority);
-               return DELETE_ME;
-       }
+       /* we must guess now a DH group. For that we choose our most preferred group */
+       dh_group = init_config->get_dh_group(init_config);
        
        /* next step is done in retry_initiate_connection */
-       return this->public.retry_initiate_connection(&(this->public),this->dh_group_priority);
+       return this->public.retry_initiate_connection(&(this->public), dh_group);
 }
 
 /**
  * Implementation of initiator_init_t.retry_initiate_connection.
  */
-status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group_priority)
+status_t retry_initiate_connection (private_initiator_init_t *this, diffie_hellman_group_t dh_group)
 {
        ike_sa_init_requested_t *next_state;
        chunk_t ike_sa_init_request_data;
@@ -174,24 +155,18 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group
        ike_sa_id_t *ike_sa_id;
        message_t *message;
        status_t status;
-
        
-       this->dh_group_priority = dh_group_priority;
-               
-       init_config = this->ike_sa->get_init_config(this->ike_sa);
-       
-       ike_sa_id = this->ike_sa->public.get_id(&(this->ike_sa->public));
-       ike_sa_id->set_responder_spi(ike_sa_id,0);
-       
-       this->dh_group_number = init_config->get_dh_group_number(init_config,dh_group_priority);
-       if (this->dh_group_number == MODP_UNDEFINED)
+       if (dh_group == MODP_UNDEFINED)
        {
-               this->logger->log(this->logger, AUDIT, "Could not find a matching diffie hellman group after %d. try. Aborting.", 
-                                                       this->dh_group_priority);
+               this->logger->log(this->logger, AUDIT, "No DH group acceptable for initialization, Aborting");
+               message->destroy(message);
                return DELETE_ME;
        }
        
-       this->diffie_hellman = diffie_hellman_create(this->dh_group_number);
+       init_config = this->ike_sa->get_init_config(this->ike_sa);
+       this->diffie_hellman = diffie_hellman_create(dh_group);
+       ike_sa_id = this->ike_sa->public.get_id(&(this->ike_sa->public));
+       ike_sa_id->set_responder_spi(ike_sa_id,0);
 
        /* going to build message */
        this->logger->log(this->logger, CONTROL|LEVEL2, "Going to build message");
@@ -222,7 +197,7 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group
 
        /* state can now be changed */
        this->logger->log(this->logger, CONTROL|LEVEL2, "Create next state object");
-       next_state = ike_sa_init_requested_create(this->ike_sa, this->dh_group_priority, this->diffie_hellman, this->sent_nonce,ike_sa_init_request_data);
+       next_state = ike_sa_init_requested_create(this->ike_sa, this->diffie_hellman, this->sent_nonce,ike_sa_init_request_data);
        this->ike_sa->set_new_state(this->ike_sa,(state_t *) next_state);
        
        this->logger->log(this->logger, CONTROL|LEVEL2, "Destroy old sate object");
@@ -236,19 +211,16 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group
 static void build_sa_payload(private_initiator_init_t *this, message_t *request)
 {
        sa_payload_t* sa_payload;
-       size_t proposal_count;
-       ike_proposal_t *proposals;
+       linked_list_t *proposal_list;
        init_config_t *init_config;
        
        this->logger->log(this->logger, CONTROL|LEVEL1, "Building SA payload");
        
        init_config = this->ike_sa->get_init_config(this->ike_sa);
 
-       proposal_count = init_config->get_proposals(init_config,&proposals);
+       proposal_list = init_config->get_proposals(init_config);
        
-       sa_payload = sa_payload_create_from_ike_proposals(proposals,proposal_count);    
-
-       allocator_free(proposals);
+       sa_payload = sa_payload_create_from_proposal_list(proposal_list);       
 
        this->logger->log(this->logger, CONTROL|LEVEL2, "Add SA payload to message");
        request->add_payload(request, (payload_t *) sa_payload);
@@ -261,13 +233,15 @@ static void build_ke_payload(private_initiator_init_t *this, message_t *request)
 {
        ke_payload_t *ke_payload;
        chunk_t key_data;
+       diffie_hellman_group_t dh_group;
        
        this->logger->log(this->logger, CONTROL|LEVEL1, "Building KE payload");
        
        this->diffie_hellman->get_my_public_value(this->diffie_hellman,&key_data);
+       dh_group = this->diffie_hellman->get_dh_group(this->diffie_hellman);
 
        ke_payload = ke_payload_create();
-       ke_payload->set_dh_group_number(ke_payload, this->dh_group_number);
+       ke_payload->set_dh_group_number(ke_payload, dh_group);
        ke_payload->set_key_exchange_data(ke_payload, key_data);
        
        allocator_free_chunk(&key_data);
@@ -372,7 +346,6 @@ initiator_init_t *initiator_init_create(protected_ike_sa_t *ike_sa)
        
        /* private data */
        this->ike_sa = ike_sa;
-       this->dh_group_priority = 1;
        this->logger = this->ike_sa->get_logger(this->ike_sa);
        this->sent_nonce = CHUNK_INITIALIZER;
        this->diffie_hellman = NULL;
index 2ea5b03..c85f12e 100644 (file)
@@ -80,6 +80,11 @@ struct private_responder_init_t {
        chunk_t received_nonce;
        
        /**
+        * Selected proposal
+        */
+       proposal_t *proposal;
+       
+       /**
         * Logger used to log data .
         * 
         * Is logger of ike_sa!
@@ -153,7 +158,6 @@ static status_t process_message(private_responder_init_t *this, message_t *messa
        nonce_payload_t *nonce_request = NULL;
        host_t *source, *destination;
        init_config_t *init_config;
-       chunk_t shared_secret;
        iterator_t *payloads;
        message_t *response;
        status_t status;
@@ -275,17 +279,15 @@ static status_t process_message(private_responder_init_t *this, message_t *messa
        {
                response->destroy(response);
                return status;
-       }
+       }       
        
-       /* store shared secret  */
-       this->logger->log(this->logger, CONTROL | LEVEL2, "Retrieve shared secret and store it");
-       status = this->diffie_hellman->get_shared_secret(this->diffie_hellman, &shared_secret);
-       this->logger->log_chunk(this->logger, PRIVATE, "Shared Diffie Hellman secret", &shared_secret);
-
-       this->ike_sa->compute_secrets(this->ike_sa,shared_secret,this->received_nonce, this->sent_nonce);
-
-       /* not used anymore */
-       allocator_free_chunk(&shared_secret);
+       /* derive all the keys used in the IKE_SA */
+       status = this->ike_sa->build_transforms(this->ike_sa, this->proposal, this->diffie_hellman, this->received_nonce, this->sent_nonce);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger, AUDIT, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
+               return DELETE_ME;
+       }
        
        /* message can now be sent (must not be destroyed) */
        status = this->ike_sa->send_response(this->ike_sa, response);
@@ -318,47 +320,40 @@ static status_t process_message(private_responder_init_t *this, message_t *messa
  */
 static status_t build_sa_payload(private_responder_init_t *this,sa_payload_t *sa_request, message_t *response)
 {
-       ike_proposal_t selected_proposal;
-       ike_proposal_t *ike_proposals;
+       proposal_t *proposal;
+       linked_list_t *proposal_list;
        init_config_t *init_config;
        sa_payload_t* sa_payload;
-       size_t proposal_count;
-       status_t status;
+       algorithm_t *algo;
 
        init_config = this->ike_sa->get_init_config(this->ike_sa);
 
        this->logger->log(this->logger, CONTROL | LEVEL2, "Process received SA payload");
+       
        /* get the list of suggested proposals */ 
-       status = sa_request->get_ike_proposals (sa_request, &ike_proposals,&proposal_count);
-       if (status != SUCCESS)
+       proposal_list = sa_request->get_proposals (sa_request);
+
+       /* select proposal */
+       this->proposal = init_config->select_proposal(init_config, proposal_list);
+       while(proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
        {
-               this->logger->log(this->logger, AUDIT, "IKE_SA_INIT request did not contain any proposals. Deleting IKE_SA");
-               this->ike_sa->send_notify(this->ike_sa, IKE_SA_INIT, NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER);
-               return DELETE_ME;       
+               proposal->destroy(proposal);
        }
-
-       status = init_config->select_proposal(init_config, ike_proposals,proposal_count,&(selected_proposal));
-       allocator_free(ike_proposals);
-       if (status != SUCCESS)
+       proposal_list->destroy(proposal_list);
+       if (this->proposal == NULL)
        {
                this->logger->log(this->logger, AUDIT, "IKE_SA_INIT request did not contain any acceptable proposals. Deleting IKE_SA");
                this->ike_sa->send_notify(this->ike_sa, IKE_SA_INIT, NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER);
                return DELETE_ME;
        }
-       
-       this->dh_group_number = selected_proposal.diffie_hellman_group;
-       
-       status = this->ike_sa->create_transforms_from_proposal(this->ike_sa,&(selected_proposal));      
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, AUDIT, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
-               return DELETE_ME;
-       }
+       /* get selected DH group to force policy, this is very restrictive!? */
+       this->proposal->get_algorithm(this->proposal, IKE, DIFFIE_HELLMAN_GROUP, &algo);
+       this->dh_group_number = algo->algorithm;
        
        this->logger->log(this->logger, CONTROL | LEVEL2, "SA Payload processed");
        
        this->logger->log(this->logger, CONTROL|LEVEL2, "Building SA payload");
-       sa_payload = sa_payload_create_from_ike_proposals(&(selected_proposal),1);      
+       sa_payload = sa_payload_create_from_proposal(this->proposal);   
        this->logger->log(this->logger, CONTROL|LEVEL2, "add SA payload to message");
        response->add_payload(response,(payload_t *) sa_payload);
        
@@ -383,6 +378,7 @@ static status_t build_ke_payload(private_responder_init_t *this,ke_payload_t *ke
                this->logger->log(this->logger, AUDIT, "No diffie hellman group to select. Deleting IKE_SA");
                return DELETE_ME;
        }
+       
        if (this->dh_group_number != group)
        {
                u_int16_t accepted_group;
@@ -510,6 +506,10 @@ static void destroy(private_responder_init_t *this)
                this->logger->log(this->logger, CONTROL | LEVEL2, "Destroy diffie_hellman_t hellman object");
                this->diffie_hellman->destroy(this->diffie_hellman);
        }
+       if (this->proposal)
+       {
+               this->proposal->destroy(this->proposal);
+       }
        this->logger->log(this->logger, CONTROL | LEVEL2, "Destroy object");
        allocator_free(this);
 }
@@ -527,6 +527,10 @@ static void destroy_after_state_change (private_responder_init_t *this)
                this->logger->log(this->logger, CONTROL | LEVEL2, "Destroy diffie_hellman_t object");
                this->diffie_hellman->destroy(this->diffie_hellman);
        }
+       if (this->proposal)
+       {
+               this->proposal->destroy(this->proposal);
+       }
        
        this->logger->log(this->logger, CONTROL | LEVEL2, "Destroy object");    
        allocator_free(this);
@@ -558,6 +562,7 @@ responder_init_t *responder_init_create(protected_ike_sa_t *ike_sa)
        this->received_nonce = CHUNK_INITIALIZER;
        this->dh_group_number = MODP_UNDEFINED;
        this->diffie_hellman = NULL;
+       this->proposal = NULL;
 
        return &(this->public);
 }
index b338989..a459e32 100644 (file)
@@ -116,8 +116,8 @@ TEST_OBJS+= $(BUILD_DIR)sa_config_test.o
 $(BUILD_DIR)sa_config_test.o :         $(TESTCASES_DIR)sa_config_test.c $(TESTCASES_DIR)sa_config_test.h
                                                                        $(CC) $(CFLAGS) -c -o $@ $<
 
-TEST_OBJS+= $(BUILD_DIR)child_proposal_test.o
-$(BUILD_DIR)child_proposal_test.o :    $(TESTCASES_DIR)child_proposal_test.c $(TESTCASES_DIR)child_proposal_test.h
+TEST_OBJS+= $(BUILD_DIR)proposal_test.o
+$(BUILD_DIR)proposal_test.o :          $(TESTCASES_DIR)proposal_test.c $(TESTCASES_DIR)proposal_test.h
                                                                        $(CC) $(CFLAGS) -c -o $@ $<
 
 TEST_OBJS+= $(BUILD_DIR)rsa_test.o
diff --git a/Source/charon/testcases/child_proposal_test.c b/Source/charon/testcases/child_proposal_test.c
deleted file mode 100644 (file)
index f0944df..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * @file child_proposal_test.c
- *
- * @brief Tests for the child_proposal_t class.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "child_proposal_test.h"
-
-#include <daemon.h>
-#include <config/child_proposal.h>
-#include <utils/allocator.h>
-#include <utils/logger.h>
-
-
-/**
- * Described in header.
- */
-void test_child_proposal(protected_tester_t *tester)
-{
-       child_proposal_t *proposal1, *proposal2, *proposal3;
-       iterator_t *iterator;
-       algorithm_t *algo;
-       bool result;
-
-       proposal1 = child_proposal_create(1);
-       proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 0);
-       proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 32);
-       proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
-       proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 0);
-       proposal1->add_algorithm(proposal1, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
-       proposal1->add_algorithm(proposal1, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
-       proposal1->add_algorithm(proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
-       proposal1->add_algorithm(proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
-       
-       proposal2 = child_proposal_create(2);
-       proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_3IDEA, 0);
-       proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
-       proposal2->add_algorithm(proposal2, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
-       proposal1->add_algorithm(proposal2, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
-       
-       /* ah and esp prop */
-       proposal3 = proposal1->select(proposal1, proposal2);
-       tester->assert_false(tester, proposal3 == NULL, "proposal select");
-       if (proposal3)
-       {
-               result = proposal3->get_algorithm(proposal3, ESP, ENCRYPTION_ALGORITHM, &algo);
-               tester->assert_true(tester, result, "encryption algo select");
-               tester->assert_true(tester, algo->algorithm == ENCR_AES_CBC, "encryption algo");
-               tester->assert_true(tester, algo->key_size == 16, "encryption keylen");
-               
-               
-               result = proposal3->get_algorithm(proposal3, ESP, INTEGRITY_ALGORITHM, &algo);
-               tester->assert_true(tester, result, "integrity algo select");
-               tester->assert_true(tester, algo->algorithm == AUTH_HMAC_MD5_96, "integrity algo");
-               tester->assert_true(tester, algo->key_size == 20, "integrity keylen");
-               
-               iterator = proposal3->create_algorithm_iterator(proposal3, ESP, INTEGRITY_ALGORITHM);
-               tester->assert_false(tester, iterator == NULL, "integrity algo select");
-               while(iterator->has_next(iterator))
-               {
-                       iterator->current(iterator, (void**)&algo);
-                       tester->assert_true(tester, algo->algorithm == AUTH_HMAC_MD5_96, "integrity algo");
-                       tester->assert_true(tester, algo->key_size == 20, "integrity keylen");
-               }
-               iterator->destroy(iterator);
-               
-               iterator = proposal3->create_algorithm_iterator(proposal3, AH, DIFFIE_HELLMAN_GROUP );
-               tester->assert_false(tester, iterator == NULL, "dh group algo select");
-               while(iterator->has_next(iterator))
-               {
-                       iterator->current(iterator, (void**)&algo);
-                       tester->assert_true(tester, algo->algorithm == MODP_1024_BIT, "dh group algo");
-                       tester->assert_true(tester, algo->key_size == 0, "dh gorup keylen");
-               }
-               iterator->destroy(iterator);
-               
-               proposal3->destroy(proposal3);
-       }
-       
-       proposal1->destroy(proposal1);
-       proposal2->destroy(proposal2);
-       return;
-}
diff --git a/Source/charon/testcases/child_proposal_test.h b/Source/charon/testcases/child_proposal_test.h
deleted file mode 100644 (file)
index 400951e..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * @file child_proposal_test.h
- *
- * @brief Tests for the child_proposal_t class.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-
-#ifndef CHILD_PROPOSAL_TEST_H_
-#define CHILD_PROPOSAL_TEST_H_
-
-#include <utils/tester.h>
-
-/**
- * @brief Test function used to test the child_proposal_t functionality.
- *
- * @param tester associated protected_tester_t object
- * 
- * @ingroup testcases
- */
-void test_child_proposal(protected_tester_t *tester);
-
-#endif //CHILD_PROPOSAL_TEST_H_
-
-
-
-
index c249e82..e1a1dc1 100644 (file)
@@ -422,11 +422,9 @@ void test_generator_with_sa_payload(protected_tester_t *tester)
        generator_t *generator;
        transform_attribute_t *attribute1, *attribute2, *attribute3;
        transform_substructure_t *transform1, *transform2;
-       proposal_substructure_t *proposal1, *proposal2;
-       ike_proposal_t *ike_proposals;
+       proposal_substructure_t *proposal_str1, *proposal_str2;
        linked_list_t *list;
-       child_proposal_t *child_proposal1, *child_proposal2;
-       size_t ike_proposal_count;
+       proposal_t *proposal1, *proposal2;
        sa_payload_t *sa_payload;
        ike_header_t *ike_header;
        
@@ -488,30 +486,30 @@ void test_generator_with_sa_payload(protected_tester_t *tester)
        logger->log(logger,CONTROL,"transforms created");
        
        /* create proposal 1 */
-       proposal1 = proposal_substructure_create();
+       proposal_str1 = proposal_substructure_create();
        tester->assert_true(tester,(proposal1 != NULL), "proposal create check");
        
        stringval = "ABCDEFGH";
        data.ptr = (void *) stringval;
        data.len = 8;
        
-       proposal1->add_transform_substructure(proposal1,transform1);
-       proposal1->add_transform_substructure(proposal1,transform2);
-       proposal1->set_spi(proposal1,data);
-       proposal1->set_proposal_number(proposal1,7);
-       proposal1->set_protocol_id(proposal1,4);
+       proposal_str1->add_transform_substructure(proposal_str1,transform1);
+       proposal_str1->add_transform_substructure(proposal_str1,transform2);
+       proposal_str1->set_spi(proposal_str1,data);
+       proposal_str1->set_proposal_number(proposal_str1,7);
+       proposal_str1->set_protocol_id(proposal_str1,4);
        
        /* create proposal 2 */
-       proposal2 = proposal_substructure_create();
-       tester->assert_true(tester,(proposal2 != NULL), "proposal create check");
-       proposal2->set_proposal_number(proposal2,7);
-       proposal2->set_protocol_id(proposal2,5);
+       proposal_str2 = proposal_substructure_create();
+       tester->assert_true(tester,(proposal_str2 != NULL), "proposal create check");
+       proposal_str2->set_proposal_number(proposal_str2,7);
+       proposal_str2->set_protocol_id(proposal_str2,5);
 
        /* create sa_payload */
        sa_payload = sa_payload_create();
        
-       sa_payload->add_proposal_substructure(sa_payload,proposal1);
-       sa_payload->add_proposal_substructure(sa_payload,proposal2);
+       sa_payload->add_proposal_substructure(sa_payload,proposal_str1);
+       sa_payload->add_proposal_substructure(sa_payload,proposal_str2);
        
        ike_header = ike_header_create();
        ike_header->set_initiator_spi(ike_header,0x22000054231234LL);
@@ -581,26 +579,22 @@ void test_generator_with_sa_payload(protected_tester_t *tester)
        tester->assert_true(tester,(generator != NULL), "generator create check");
        
 
-       ike_proposal_count = 2;
-       ike_proposals = allocator_alloc(ike_proposal_count * (sizeof(ike_proposal_t)));
+       proposal1 = proposal_create(1);
+       proposal1->add_algorithm(proposal1, IKE, ENCRYPTION_ALGORITHM, 1, 20);
+       proposal1->add_algorithm(proposal1, IKE, PSEUDO_RANDOM_FUNCTION, 2, 22);
+       proposal1->add_algorithm(proposal1, IKE, INTEGRITY_ALGORITHM, 3, 24);
+       proposal1->add_algorithm(proposal1, IKE, DIFFIE_HELLMAN_GROUP, 4, 0);
        
-       ike_proposals[0].encryption_algorithm = 1;
-       ike_proposals[0].encryption_algorithm_key_length = 20;
-       ike_proposals[0].pseudo_random_function = 2;
-       ike_proposals[0].pseudo_random_function_key_length = 22;
-       ike_proposals[0].integrity_algorithm = 3;
-       ike_proposals[0].integrity_algorithm_key_length = 24;
-       ike_proposals[0].diffie_hellman_group = 4;
+       proposal2 = proposal_create(2);
+       proposal2->add_algorithm(proposal2, IKE, ENCRYPTION_ALGORITHM, 5, 26);
+       proposal2->add_algorithm(proposal2, IKE, PSEUDO_RANDOM_FUNCTION, 6, 28);
+       proposal2->add_algorithm(proposal2, IKE, INTEGRITY_ALGORITHM, 7, 30);
+       proposal2->add_algorithm(proposal2, IKE, DIFFIE_HELLMAN_GROUP, 8, 0);
 
-       ike_proposals[1].encryption_algorithm = 5;
-       ike_proposals[1].encryption_algorithm_key_length = 26;
-       ike_proposals[1].pseudo_random_function = 6;
-       ike_proposals[1].pseudo_random_function_key_length = 28;
-       ike_proposals[1].integrity_algorithm = 7;
-       ike_proposals[1].integrity_algorithm_key_length = 30;
-       ike_proposals[1].diffie_hellman_group = 8;
-       
-       sa_payload = sa_payload_create_from_ike_proposals(ike_proposals,ike_proposal_count);
+       list = linked_list_create();
+       list->insert_last(list, (void*)proposal1);
+       list->insert_last(list, (void*)proposal2);
+       sa_payload = sa_payload_create_from_proposal_list(list);
        tester->assert_true(tester,(sa_payload != NULL), "sa_payload create check");
 
        generator->generate_payload(generator,(payload_t *)sa_payload);
@@ -643,7 +637,9 @@ void test_generator_with_sa_payload(protected_tester_t *tester)
        tester->assert_true(tester,(memcmp(expected_generation2,generated_data.ptr,sizeof(expected_generation2)) == 0), "compare generated data");
 
        sa_payload->destroy(sa_payload);
-       allocator_free(ike_proposals);
+       list->destroy(list);
+       proposal1->destroy(proposal1);
+       proposal2->destroy(proposal2);
        allocator_free_chunk(&generated_data);
        generator->destroy(generator);
        
@@ -655,32 +651,32 @@ void test_generator_with_sa_payload(protected_tester_t *tester)
        tester->assert_true(tester,(generator != NULL), "generator create check");
        
 
-       child_proposal1 = child_proposal_create(1);
+       proposal1 = proposal_create(1);
        
-       child_proposal1->add_algorithm(child_proposal1, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
-       child_proposal1->add_algorithm(child_proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
-       child_proposal1->add_algorithm(child_proposal1, AH, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0);
-       child_proposal1->set_spi(child_proposal1, AH, 0x01010101l);
+       proposal1->add_algorithm(proposal1, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+       proposal1->add_algorithm(proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+       proposal1->add_algorithm(proposal1, AH, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0);
+       proposal1->set_spi(proposal1, AH, 0x01010101l);
        
-       child_proposal1->add_algorithm(child_proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
-       child_proposal1->add_algorithm(child_proposal1, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
-       child_proposal1->set_spi(child_proposal1, ESP, 0x02020202);
+       proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
+       proposal1->add_algorithm(proposal1, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+       proposal1->set_spi(proposal1, ESP, 0x02020202);
        
        
-       child_proposal2->add_algorithm(child_proposal2, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
-       child_proposal2->add_algorithm(child_proposal2, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
-       child_proposal2->add_algorithm(child_proposal2, AH, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0);
-       child_proposal2->set_spi(child_proposal2, AH, 0x01010101);
+       proposal2->add_algorithm(proposal2, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+       proposal2->add_algorithm(proposal2, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+       proposal2->add_algorithm(proposal2, AH, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0);
+       proposal2->set_spi(proposal2, AH, 0x01010101);
        
-       child_proposal2->add_algorithm(child_proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 32);
-       child_proposal2->add_algorithm(child_proposal2, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
-       child_proposal2->add_algorithm(child_proposal2, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
-       child_proposal2->set_spi(child_proposal2, ESP, 0x02020202);
+       proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 32);
+       proposal2->add_algorithm(proposal2, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+       proposal2->add_algorithm(proposal2, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+       proposal2->set_spi(proposal2, ESP, 0x02020202);
        
-       list->insert_last(list, (void*)child_proposal1);
-       list->insert_last(list, (void*)child_proposal2);
+       list->insert_last(list, (void*)proposal1);
+       list->insert_last(list, (void*)proposal2);
        
-       sa_payload = sa_payload_create_from_child_proposal_list(list);
+       sa_payload = sa_payload_create_from_proposal_list(list);
        tester->assert_true(tester,(sa_payload != NULL), "sa_payload create check");
 
        generator->generate_payload(generator,(payload_t *)sa_payload);
@@ -754,8 +750,8 @@ void test_generator_with_sa_payload(protected_tester_t *tester)
        tester->assert_true(tester,(memcmp(expected_generation3,generated_data.ptr,sizeof(expected_generation3)) == 0), "compare generated data");
 
        sa_payload->destroy(sa_payload);
-       child_proposal1->destroy(child_proposal1);
-       child_proposal2->destroy(child_proposal2);
+       proposal1->destroy(proposal1);
+       proposal2->destroy(proposal2);
        list->destroy(list);
        allocator_free_chunk(&generated_data);
        generator->destroy(generator);
index b8c9853..5e4506a 100644 (file)
 void test_init_config(protected_tester_t *tester)
 {
        init_config_t *init_config = init_config_create("192.168.0.1","192.168.0.2",500,500);
-       ike_proposal_t prop1, prop2, prop3, prop4, selected_one;
-       ike_proposal_t *proposal_list;
-       size_t proposal_count;
+       proposal_t *prop1, *prop2, *prop3, *prop4, *selected_one;
+       linked_list_t *list;
        status_t status;
 
-       prop1.encryption_algorithm = ENCR_AES_CBC;
-       prop1.encryption_algorithm_key_length = 20;
-       prop1.integrity_algorithm = AUTH_HMAC_SHA1_96;
-       prop1.integrity_algorithm_key_length = 20;
-       prop1.pseudo_random_function = PRF_HMAC_SHA1;
-       prop1.pseudo_random_function_key_length = 20;
-       prop1.diffie_hellman_group = MODP_2048_BIT;
+       prop1 = proposal_create(1);
+       prop1->add_algorithm(prop1, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
+       prop1->add_algorithm(prop1, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+       prop1->add_algorithm(prop1, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA1, 20);
+       prop1->add_algorithm(prop1, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
        
-       prop2 = prop1;
-       prop2.pseudo_random_function = PRF_HMAC_MD5;
-       prop2.diffie_hellman_group = MODP_1024_BIT;
+       prop2 = proposal_create(2);
+       prop2->add_algorithm(prop2, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
+       prop2->add_algorithm(prop2, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+       prop2->add_algorithm(prop2, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 20);
+       prop2->add_algorithm(prop2, IKE, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
        
-       prop3 = prop1;
-       prop3.encryption_algorithm = ENCR_DES;
-       prop3.diffie_hellman_group = MODP_768_BIT;
+       prop3 = proposal_create(3);
+       prop3->add_algorithm(prop3, IKE, ENCRYPTION_ALGORITHM, ENCR_DES, 20);
+       prop3->add_algorithm(prop3, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+       prop3->add_algorithm(prop3, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 20);
+       prop3->add_algorithm(prop3, IKE, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0);
        
-       prop4 = prop1;
+       prop4 = proposal_create(4);
+       prop4->add_algorithm(prop4, IKE, ENCRYPTION_ALGORITHM, ENCR_3DES, 20);
+       prop4->add_algorithm(prop4, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+       prop4->add_algorithm(prop4, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_TIGER, 20);
+       prop4->add_algorithm(prop4, IKE, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0);
        
-       prop4.encryption_algorithm = ENCR_3DES;
-       prop4.pseudo_random_function = PRF_HMAC_TIGER;
+       init_config->add_proposal(init_config, prop1);
+       init_config->add_proposal(init_config, prop2);
+       init_config->add_proposal(init_config, prop3);
+       init_config->add_proposal(init_config, prop4);
        
-       init_config->add_proposal(init_config,1,prop1);
-       init_config->add_proposal(init_config,1,prop2);
-       init_config->add_proposal(init_config,3,prop3);
-       init_config->add_proposal(init_config,2,prop4);
+       list = init_config->get_proposals(init_config);
        
-       proposal_count = init_config->get_proposals(init_config,&proposal_list);
-       
-       tester->assert_true(tester,(proposal_count == 4), "proposal count check ");
-       
-       tester->assert_true(tester,(proposal_list[0].encryption_algorithm == ENCR_AES_CBC), "encryption algorithm check 1");
-       tester->assert_true(tester,(proposal_list[0].pseudo_random_function == PRF_HMAC_MD5), "prf check 1");
+       tester->assert_true(tester,(list->get_count(list) == 4), "proposal count check ");
 
-       tester->assert_true(tester,(proposal_list[1].encryption_algorithm == ENCR_3DES), "encryption algorithm check 2");
-       tester->assert_true(tester,(proposal_list[1].pseudo_random_function == PRF_HMAC_TIGER), "prf check 2");
-       
-       tester->assert_true(tester,(proposal_list[2].encryption_algorithm == ENCR_AES_CBC), "encryption algorithm check 3");
-       tester->assert_true(tester,(proposal_list[2].pseudo_random_function == PRF_HMAC_SHA1), "prf check 3");
-
-       tester->assert_true(tester,(proposal_list[3].encryption_algorithm == ENCR_DES), "encryption algorithm check 4");
-       tester->assert_true(tester,(proposal_list[3].pseudo_random_function == PRF_HMAC_SHA1), "prf check 4");
-       
-       
        
        /* going to check proposals */
-       status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
-       tester->assert_true(tester,(status == SUCCESS), "select proposal call check 1");
-
-       tester->assert_true(tester,(selected_one.encryption_algorithm == ENCR_AES_CBC), "encryption algorithm check");
-       tester->assert_true(tester,(selected_one.pseudo_random_function == PRF_HMAC_MD5), "prf check");
-
-       proposal_list[0].encryption_algorithm = ENCR_DES_IV32;  
-       
-       status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
-       tester->assert_true(tester,(status == SUCCESS), "select proposal call check 2");
-
-       tester->assert_true(tester,(selected_one.encryption_algorithm == ENCR_3DES), "encryption algorithm check");
-       tester->assert_true(tester,(selected_one.pseudo_random_function == PRF_HMAC_TIGER), "prf check");
-
-       proposal_list[1].pseudo_random_function = PRF_AES128_CBC;
-       
-       status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
-       tester->assert_true(tester,(status == SUCCESS), "select proposal call check 3");
-
-       tester->assert_true(tester,(selected_one.encryption_algorithm == ENCR_AES_CBC), "encryption algorithm check");
-       tester->assert_true(tester,(selected_one.pseudo_random_function == PRF_HMAC_SHA1), "prf check");
-
-       proposal_list[2].pseudo_random_function = PRF_AES128_CBC;
-       
-       status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
-       tester->assert_true(tester,(status == SUCCESS), "select proposal call check 4");
-
-       tester->assert_true(tester,(selected_one.encryption_algorithm == ENCR_DES), "encryption algorithm check");
-       tester->assert_true(tester,(selected_one.pseudo_random_function == PRF_HMAC_SHA1), "prf check");
-
-       proposal_list[3].pseudo_random_function = PRF_AES128_CBC;
-       
-       status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
-       tester->assert_true(tester,(status == NOT_FOUND), "select proposal call check 5");
-
-       tester->assert_true(tester,(init_config->get_dh_group_number(init_config,1) == MODP_1024_BIT), "get DH group number call check 1");
-       tester->assert_true(tester,(init_config->get_dh_group_number(init_config,2) == MODP_2048_BIT), "get DH group number call check 2");
-       tester->assert_true(tester,(init_config->get_dh_group_number(init_config,3) == MODP_2048_BIT), "get DH group number call check 3");
-       tester->assert_true(tester,(init_config->get_dh_group_number(init_config,4) == MODP_768_BIT), "get DH group number call check 4");      
+       /* TODO test?*/
        
-       allocator_free(proposal_list);
+       list->destroy(list);
        
        init_config->destroy(init_config);
 }
index 92493b2..5dcfc7c 100644 (file)
@@ -104,8 +104,6 @@ void test_parser_with_sa_payload(protected_tester_t *tester)
        status_t status;
        chunk_t sa_chunk, sa_chunk2, sa_chunk3;
        iterator_t *proposals, *transforms, *attributes;
-    ike_proposal_t *ike_proposals;
-    size_t ike_proposal_count;
        
        /* first test generic parsing functionality */
                
@@ -242,7 +240,7 @@ void test_parser_with_sa_payload(protected_tester_t *tester)
 
        status = sa_payload->payload_interface.verify(&(sa_payload->payload_interface));
        tester->assert_true(tester,(status == SUCCESS),"verify call check");
-
+       /*
        status = sa_payload->get_ike_proposals (sa_payload, &ike_proposals, &ike_proposal_count);       
        tester->assert_true(tester,(status == SUCCESS),"get ike proposals call check"); 
        
@@ -268,6 +266,7 @@ void test_parser_with_sa_payload(protected_tester_t *tester)
        {
                allocator_free(ike_proposals);
        }
+       */
        sa_payload->destroy(sa_payload);
        
        /* now test SA functionality after parsing an SA payload with child sa proposals*/
@@ -347,59 +346,59 @@ void test_parser_with_sa_payload(protected_tester_t *tester)
 
        status = sa_payload->payload_interface.verify(&(sa_payload->payload_interface));
        tester->assert_true(tester,(status == SUCCESS),"verify call check");
-
+/*
        status = sa_payload->get_ike_proposals (sa_payload, &ike_proposals, &ike_proposal_count);       
        tester->assert_false(tester,(status == SUCCESS),"get ike proposals call check");
-       /*
-       status = sa_payload->get_child_proposals (sa_payload, &child_proposals, &child_proposal_count); 
+       
+       status = sa_payload->get_proposals (sa_payload, &proposals, &proposal_count);   
        tester->assert_true(tester,(status == SUCCESS),"get child proposals call check");       
        
 
-       tester->assert_true(tester,(child_proposal_count == 2),"child proposal count check");
-       tester->assert_true(tester,(child_proposals[0].ah.is_set == TRUE),"is ah set check");
-       tester->assert_true(tester,(child_proposals[0].ah.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
-       tester->assert_true(tester,(child_proposals[0].ah.integrity_algorithm_key_size == 20),"integrity_algorithm_key_size check");
-       tester->assert_true(tester,(child_proposals[0].ah.diffie_hellman_group == MODP_2048_BIT),"diffie_hellman_group check");
-       tester->assert_true(tester,(child_proposals[0].ah.extended_sequence_numbers == EXT_SEQ_NUMBERS),"extended_sequence_numbers check");
-       tester->assert_true(tester,(child_proposals[0].ah.spi[0] == 1),"spi check");
-       tester->assert_true(tester,(child_proposals[0].ah.spi[1] == 1),"spi check");
-       tester->assert_true(tester,(child_proposals[0].ah.spi[2] == 1),"spi check");
-       tester->assert_true(tester,(child_proposals[0].ah.spi[3] == 1),"spi check");
-       
-       tester->assert_true(tester,(child_proposals[0].esp.is_set == TRUE),"is ah set check");
-       tester->assert_true(tester,(child_proposals[0].esp.encryption_algorithm == ENCR_AES_CBC),"integrity_algorithm check");
-       tester->assert_true(tester,(child_proposals[0].esp.encryption_algorithm_key_size == 32),"integrity_algorithm_key_size check");
-       tester->assert_true(tester,(child_proposals[0].esp.diffie_hellman_group == MODP_1024_BIT),"diffie_hellman_group check");
-       tester->assert_true(tester,(child_proposals[0].esp.integrity_algorithm == AUTH_UNDEFINED),"integrity_algorithm check");
-       tester->assert_true(tester,(child_proposals[0].esp.spi[0] == 2),"spi check");
-       tester->assert_true(tester,(child_proposals[0].esp.spi[1] == 2),"spi check");
-       tester->assert_true(tester,(child_proposals[0].esp.spi[2] == 2),"spi check");
-       tester->assert_true(tester,(child_proposals[0].esp.spi[3] == 2),"spi check");
-
-       tester->assert_true(tester,(child_proposals[1].ah.is_set == TRUE),"is ah set check");
-       tester->assert_true(tester,(child_proposals[1].ah.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
-       tester->assert_true(tester,(child_proposals[1].ah.integrity_algorithm_key_size == 20),"integrity_algorithm_key_size check");
-       tester->assert_true(tester,(child_proposals[1].ah.diffie_hellman_group == MODP_2048_BIT),"diffie_hellman_group check");
-       tester->assert_true(tester,(child_proposals[1].ah.extended_sequence_numbers == EXT_SEQ_NUMBERS),"extended_sequence_numbers check");
-       tester->assert_true(tester,(child_proposals[1].ah.spi[0] == 1),"spi check");
-       tester->assert_true(tester,(child_proposals[1].ah.spi[1] == 1),"spi check");
-       tester->assert_true(tester,(child_proposals[1].ah.spi[2] == 1),"spi check");
-       tester->assert_true(tester,(child_proposals[1].ah.spi[3] == 1),"spi check");    
-
-       tester->assert_true(tester,(child_proposals[1].esp.is_set == TRUE),"is ah set check");
-       tester->assert_true(tester,(child_proposals[1].esp.encryption_algorithm == ENCR_AES_CBC),"integrity_algorithm check");
-       tester->assert_true(tester,(child_proposals[1].esp.encryption_algorithm_key_size == 32),"integrity_algorithm_key_size check");
-       tester->assert_true(tester,(child_proposals[1].esp.diffie_hellman_group == MODP_1024_BIT),"diffie_hellman_group check");
-       tester->assert_true(tester,(child_proposals[1].esp.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
-       tester->assert_true(tester,(child_proposals[1].esp.integrity_algorithm_key_size == 20),"integrity_algorithm check");
-       tester->assert_true(tester,(child_proposals[1].esp.spi[0] == 2),"spi check");
-       tester->assert_true(tester,(child_proposals[1].esp.spi[1] == 2),"spi check");
-       tester->assert_true(tester,(child_proposals[1].esp.spi[2] == 2),"spi check");
-       tester->assert_true(tester,(child_proposals[1].esp.spi[3] == 2),"spi check");
+       tester->assert_true(tester,(proposal_count == 2),"child proposal count check");
+       tester->assert_true(tester,(proposals[0].ah.is_set == TRUE),"is ah set check");
+       tester->assert_true(tester,(proposals[0].ah.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
+       tester->assert_true(tester,(proposals[0].ah.integrity_algorithm_key_size == 20),"integrity_algorithm_key_size check");
+       tester->assert_true(tester,(proposals[0].ah.diffie_hellman_group == MODP_2048_BIT),"diffie_hellman_group check");
+       tester->assert_true(tester,(proposals[0].ah.extended_sequence_numbers == EXT_SEQ_NUMBERS),"extended_sequence_numbers check");
+       tester->assert_true(tester,(proposals[0].ah.spi[0] == 1),"spi check");
+       tester->assert_true(tester,(proposals[0].ah.spi[1] == 1),"spi check");
+       tester->assert_true(tester,(proposals[0].ah.spi[2] == 1),"spi check");
+       tester->assert_true(tester,(proposals[0].ah.spi[3] == 1),"spi check");
+       
+       tester->assert_true(tester,(proposals[0].esp.is_set == TRUE),"is ah set check");
+       tester->assert_true(tester,(proposals[0].esp.encryption_algorithm == ENCR_AES_CBC),"integrity_algorithm check");
+       tester->assert_true(tester,(proposals[0].esp.encryption_algorithm_key_size == 32),"integrity_algorithm_key_size check");
+       tester->assert_true(tester,(proposals[0].esp.diffie_hellman_group == MODP_1024_BIT),"diffie_hellman_group check");
+       tester->assert_true(tester,(proposals[0].esp.integrity_algorithm == AUTH_UNDEFINED),"integrity_algorithm check");
+       tester->assert_true(tester,(proposals[0].esp.spi[0] == 2),"spi check");
+       tester->assert_true(tester,(proposals[0].esp.spi[1] == 2),"spi check");
+       tester->assert_true(tester,(proposals[0].esp.spi[2] == 2),"spi check");
+       tester->assert_true(tester,(proposals[0].esp.spi[3] == 2),"spi check");
+
+       tester->assert_true(tester,(proposals[1].ah.is_set == TRUE),"is ah set check");
+       tester->assert_true(tester,(proposals[1].ah.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
+       tester->assert_true(tester,(proposals[1].ah.integrity_algorithm_key_size == 20),"integrity_algorithm_key_size check");
+       tester->assert_true(tester,(proposals[1].ah.diffie_hellman_group == MODP_2048_BIT),"diffie_hellman_group check");
+       tester->assert_true(tester,(proposals[1].ah.extended_sequence_numbers == EXT_SEQ_NUMBERS),"extended_sequence_numbers check");
+       tester->assert_true(tester,(proposals[1].ah.spi[0] == 1),"spi check");
+       tester->assert_true(tester,(proposals[1].ah.spi[1] == 1),"spi check");
+       tester->assert_true(tester,(proposals[1].ah.spi[2] == 1),"spi check");
+       tester->assert_true(tester,(proposals[1].ah.spi[3] == 1),"spi check");  
+
+       tester->assert_true(tester,(proposals[1].esp.is_set == TRUE),"is ah set check");
+       tester->assert_true(tester,(proposals[1].esp.encryption_algorithm == ENCR_AES_CBC),"integrity_algorithm check");
+       tester->assert_true(tester,(proposals[1].esp.encryption_algorithm_key_size == 32),"integrity_algorithm_key_size check");
+       tester->assert_true(tester,(proposals[1].esp.diffie_hellman_group == MODP_1024_BIT),"diffie_hellman_group check");
+       tester->assert_true(tester,(proposals[1].esp.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
+       tester->assert_true(tester,(proposals[1].esp.integrity_algorithm_key_size == 20),"integrity_algorithm check");
+       tester->assert_true(tester,(proposals[1].esp.spi[0] == 2),"spi check");
+       tester->assert_true(tester,(proposals[1].esp.spi[1] == 2),"spi check");
+       tester->assert_true(tester,(proposals[1].esp.spi[2] == 2),"spi check");
+       tester->assert_true(tester,(proposals[1].esp.spi[3] == 2),"spi check");
        
        if (status == SUCCESS)
        {
-               allocator_free(child_proposals);
+               allocator_free(proposals);
        }
        */
        
diff --git a/Source/charon/testcases/proposal_test.c b/Source/charon/testcases/proposal_test.c
new file mode 100644 (file)
index 0000000..7e7f2a4
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * @file proposal_test.c
+ *
+ * @brief Tests for the proposal_t class.
+ *
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "proposal_test.h"
+
+#include <daemon.h>
+#include <config/proposal.h>
+#include <utils/allocator.h>
+#include <utils/logger.h>
+
+
+/**
+ * Described in header.
+ */
+void test_proposal(protected_tester_t *tester)
+{
+       proposal_t *proposal1, *proposal2, *proposal3;
+       iterator_t *iterator;
+       algorithm_t *algo;
+       bool result;
+
+       proposal1 = proposal_create(1);
+       proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 0);
+       proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 32);
+       proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+       proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 0);
+       proposal1->add_algorithm(proposal1, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+       proposal1->add_algorithm(proposal1, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+       proposal1->add_algorithm(proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+       proposal1->add_algorithm(proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+       
+       proposal2 = proposal_create(2);
+       proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_3IDEA, 0);
+       proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+       proposal2->add_algorithm(proposal2, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+       proposal1->add_algorithm(proposal2, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+       
+       /* ah and esp prop */
+       proposal3 = proposal1->select(proposal1, proposal2);
+       tester->assert_false(tester, proposal3 == NULL, "proposal select");
+       if (proposal3)
+       {
+               result = proposal3->get_algorithm(proposal3, ESP, ENCRYPTION_ALGORITHM, &algo);
+               tester->assert_true(tester, result, "encryption algo select");
+               tester->assert_true(tester, algo->algorithm == ENCR_AES_CBC, "encryption algo");
+               tester->assert_true(tester, algo->key_size == 16, "encryption keylen");
+               
+               
+               result = proposal3->get_algorithm(proposal3, ESP, INTEGRITY_ALGORITHM, &algo);
+               tester->assert_true(tester, result, "integrity algo select");
+               tester->assert_true(tester, algo->algorithm == AUTH_HMAC_MD5_96, "integrity algo");
+               tester->assert_true(tester, algo->key_size == 20, "integrity keylen");
+               
+               iterator = proposal3->create_algorithm_iterator(proposal3, ESP, INTEGRITY_ALGORITHM);
+               tester->assert_false(tester, iterator == NULL, "integrity algo select");
+               while(iterator->has_next(iterator))
+               {
+                       iterator->current(iterator, (void**)&algo);
+                       tester->assert_true(tester, algo->algorithm == AUTH_HMAC_MD5_96, "integrity algo");
+                       tester->assert_true(tester, algo->key_size == 20, "integrity keylen");
+               }
+               iterator->destroy(iterator);
+               
+               iterator = proposal3->create_algorithm_iterator(proposal3, AH, DIFFIE_HELLMAN_GROUP );
+               tester->assert_false(tester, iterator == NULL, "dh group algo select");
+               while(iterator->has_next(iterator))
+               {
+                       iterator->current(iterator, (void**)&algo);
+                       tester->assert_true(tester, algo->algorithm == MODP_1024_BIT, "dh group algo");
+                       tester->assert_true(tester, algo->key_size == 0, "dh gorup keylen");
+               }
+               iterator->destroy(iterator);
+               
+               proposal3->destroy(proposal3);
+       }
+       
+       proposal1->destroy(proposal1);
+       proposal2->destroy(proposal2);
+       return;
+}
diff --git a/Source/charon/testcases/proposal_test.h b/Source/charon/testcases/proposal_test.h
new file mode 100644 (file)
index 0000000..d6d9681
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * @file proposal_test.h
+ *
+ * @brief Tests for the proposal_t class.
+ *
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+
+#ifndef CHILD_PROPOSAL_TEST_H_
+#define CHILD_PROPOSAL_TEST_H_
+
+#include <utils/tester.h>
+
+/**
+ * @brief Test function used to test the proposal_t functionality.
+ *
+ * @param tester associated protected_tester_t object
+ * 
+ * @ingroup testcases
+ */
+void test_proposal(protected_tester_t *tester);
+
+#endif //CHILD_PROPOSAL_TEST_H_
+
+
+
+
index 8fe624e..2dfb111 100644 (file)
@@ -37,7 +37,7 @@ void test_sa_config(protected_tester_t *tester)
 {
        sa_config_t *sa_config; 
        traffic_selector_t *ts_policy[3], *ts_request[4], *ts_reference[3], **ts_result;
-       child_proposal_t *proposal1, *proposal2, *proposal3, *proposal_sel;
+       proposal_t *proposal1, *proposal2, *proposal3, *proposal_sel;
        linked_list_t *proposals_list;
        iterator_t *iterator;
        size_t count;
@@ -61,15 +61,15 @@ void test_sa_config(protected_tester_t *tester)
         */
        
        /* esp only prop */
-       proposal1 = child_proposal_create(1);
+       proposal1 = proposal_create(1);
        proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
        
        /* ah only prop */
-       proposal2 = child_proposal_create(2);
+       proposal2 = proposal_create(2);
        proposal2->add_algorithm(proposal2, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
        
        /* ah and esp prop */
-       proposal3 = child_proposal_create(3);
+       proposal3 = proposal_create(3);
        proposal3->add_algorithm(proposal3, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 16);
        proposal3->add_algorithm(proposal3, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
        
@@ -84,9 +84,9 @@ void test_sa_config(protected_tester_t *tester)
        
        
        proposals_list = linked_list_create();
-       proposal1 = child_proposal_create(1);
+       proposal1 = proposal_create(1);
        proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 32);
-       proposal2 = child_proposal_create(2);
+       proposal2 = proposal_create(2);
        proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
        proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 16);
        proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 0);
index 170ebf6..af539cb 100644 (file)
@@ -58,7 +58,7 @@
 #include <testcases/encryption_payload_test.h>
 #include <testcases/init_config_test.h>
 #include <testcases/sa_config_test.h>
-#include <testcases/child_proposal_test.h>
+#include <testcases/proposal_test.h>
 #include <testcases/rsa_test.h>
 #include <testcases/kernel_interface_test.h>
 
@@ -123,7 +123,7 @@ test_t hmac_signer_test2 = {test_hmac_sha1_signer, "HMAC SHA1 signer test"};
 test_t encryption_payload_test = {test_encryption_payload, "encryption payload test"};
 test_t init_config_test = {test_init_config, "init_config_t test"};
 test_t sa_config_test = {test_sa_config, "sa_config_t test"};
-test_t child_proposal_test = {test_child_proposal, "child_proposal_t test"};
+test_t proposal_test = {test_proposal, "proposal_t test"};
 test_t rsa_test = {test_rsa, "RSA private/public key test"};
 test_t kernel_interface_test = {test_kernel_interface, "Kernel Interface"};
 
@@ -233,7 +233,7 @@ int main()
                &encryption_payload_test,
                &init_config_test,
                &sa_config_test,
-               &child_proposal_test,
+               &proposal_test,
                &rsa_test,
                NULL
        };
@@ -249,8 +249,8 @@ int main()
        tester_t *tester = tester_create(test_output, FALSE);
        
 
-       //tester->perform_tests(tester,all_tests);
-       tester->perform_test(tester,&kernel_interface_test);
+       tester->perform_tests(tester,all_tests);
+       //tester->perform_test(tester,&kernel_interface_test);
        
        
        tester->destroy(tester);
index 2768c06..d5d0f9a 100644 (file)
@@ -41,6 +41,8 @@
 #define AES_KS_LENGTH   120
 #define AES_RC_LENGTH    29
 
+#define AES_BLOCK_SIZE 16
+
 typedef struct private_aes_cbc_crypter_t private_aes_cbc_crypter_t;
 
 /**
@@ -63,47 +65,48 @@ struct private_aes_cbc_crypter_t {
        /**
         * The number of cipher rounds.
         */
-    u_int32_t    aes_Nrnd;
-    
-    /**
-     * The encryption key schedule.
-     */
-    u_int32_t    aes_e_key[AES_KS_LENGTH];
-    /**
-     * The decryption key schedule.
-     */
-    u_int32_t    aes_d_key[AES_KS_LENGTH];   
-    
-    /**
-     * The number of columns in the cipher state.
-     */
-    u_int32_t    aes_Ncol;     
-
-    /**
-     * Blocksize of this AES cypher object.
-     */
-    u_int32_t    blocksize;    
-    
-    /**
-     * Decrypts a block.
-     * 
-     * No memory gets allocated.
-     * 
-     * @param this                     calling object
-     * @param[in] in_blk       block to decrypt
-     * @param[out] out_blk     decrypted data are written to this location
-     */
-       void (*decrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
-    /**
-     * Encrypts a block.
-     * 
-     * No memory gets allocated.
-     * 
-     * @param this                     calling object
-     * @param[in] in_blk       block to encrypt
-     * @param[out] out_blk     encrypted data are written to this location
-     */        
+       u_int32_t    aes_Nrnd;
+       
+       /**
+       * The encryption key schedule.
+       */
+       u_int32_t    aes_e_key[AES_KS_LENGTH];
+
+       /**
+       * The decryption key schedule.
+       */
+       u_int32_t    aes_d_key[AES_KS_LENGTH];
+       
+       /**
+       * The number of columns in the cipher state.
+       */
+       u_int32_t    aes_Ncol;
+       
+       /**
+       * Key size of this AES cypher object.
+       */
+       u_int32_t    key_size;
+       
+       /**
+       * Decrypts a block.
+       * 
+       * No memory gets allocated.
+       * 
+       * @param this                   calling object
+       * @param[in] in_blk     block to decrypt
+       * @param[out] out_blk   decrypted data are written to this location
+       */
+       void (*decrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
+       
+       /**
+       * Encrypts a block.
+       * 
+       * No memory gets allocated.
+       * 
+       * @param this                   calling object
+       * @param[in] in_blk     block to encrypt
+       * @param[out] out_blk   encrypted data are written to this location
+       */
        void (*encrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
 };
 
@@ -1464,7 +1467,15 @@ static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t
  */
 static size_t get_block_size (private_aes_cbc_crypter_t *this)
 {
-       return this->blocksize;
+       return AES_BLOCK_SIZE;
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size (private_aes_cbc_crypter_t *this)
+{
+       return this->key_size;
 }
 
 /**
@@ -1475,7 +1486,7 @@ static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key)
        u_int32_t    *kf, *kt, rci, f = 0;
        u_int8_t *in_key = key.ptr;
        
-       if (key.len != this->blocksize)
+       if (key.len != this->key_size)
        {
                return INVALID_ARG;
        }
@@ -1574,37 +1585,38 @@ static void destroy (private_aes_cbc_crypter_t *this)
 /*
  * Described in header
  */
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t blocksize)
+aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size)
 {
        private_aes_cbc_crypter_t *this = allocator_alloc_thing(private_aes_cbc_crypter_t);
-
+       
        #if !defined(FIXED_TABLES)
-    if(!tab_gen) { gen_tabs(); tab_gen = 1; }
+       if(!tab_gen) { gen_tabs(); tab_gen = 1; }
        #endif
-
-    switch(blocksize) {
-    case 32:        /* bytes */
-        this->aes_Ncol = 8;
-        this->aes_Nkey = 8;
-        this->blocksize = blocksize;
-        break;
-    case 24:        /* bytes */
-        this->aes_Ncol = 6;
-        this->aes_Nkey = 6;
-        this->blocksize = blocksize;
-        break;
-    case 16:        /* bytes */
-    default:
-        this->aes_Ncol = 4;
-        this->aes_Nkey = 4;
-        this->blocksize = 16;
-        break;
-    }
-
+       
+       this->key_size = key_size;
+       switch(key_size) {
+       case 32:        /* bytes */
+               this->aes_Ncol = 8;
+               this->aes_Nkey = 8;
+               break;
+       case 24:        /* bytes */
+               this->aes_Ncol = 6;
+               this->aes_Nkey = 6;
+               break;
+       case 16:        /* bytes */
+               this->aes_Ncol = 4;
+               this->aes_Nkey = 4;
+               break;
+       default:
+               allocator_free(this);
+               return NULL;
+       }
+       
        /* functions of crypter_t interface */  
        this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
        this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
        this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
+       this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
        this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key;
        this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
        
index 360f245..62cd77a 100644 (file)
@@ -48,14 +48,14 @@ struct aes_cbc_crypter_t {
 /**
  * @brief Constructor to create aes_cbc_crypter_t objects.
  * 
- * If an unvalid blocksize is specified, 16 is selected.
+ * Supported key sizes are: 16, 24 or 32. 
  * 
- * @param blocksize            block size of AES crypter
- *                                             (16, 24 or 32 are supported)
- *                                             Default size is set to 16.
- * @return                             aes_cbc_crypter_t object
+ * @param key_size             key size in bytes
+ * @return                             
+ *                                             - aes_cbc_crypter_t object
+ *                                             - NULL if key size not supported
  */
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t blocksize);
+aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size);
 
 
 #endif //_AES_CRYPTER_H_
index aebb220..37b9630 100644 (file)
@@ -49,13 +49,13 @@ mapping_t encryption_algorithm_m[] = {
 /* 
  * Described in header.
  */
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm,size_t blocksize)
+crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size)
 {
        switch (encryption_algorithm)
        {
                case ENCR_AES_CBC:
                {
-                       return (crypter_t*)aes_cbc_crypter_create(blocksize);
+                       return (crypter_t*)aes_cbc_crypter_create(key_size);
                }
                default:
                        return NULL;
index 25a27e1..7f371de 100644 (file)
@@ -33,11 +33,7 @@ typedef enum encryption_algorithm_t encryption_algorithm_t;
  * Currently only the following algorithms are implemented and therefore supported:
  * - ENCR_AES_CBC
  * 
- * @b Constructors:
- *  - crypter_create()
- *  - aes_cbc_crypter_create()
- * 
- * @todo Implement more enryption algorithm, especially 3DES
+ * @todo Implement more enryption algorithms, such as 3DES
  * 
  * @ingroup crypters
  */
@@ -71,18 +67,14 @@ typedef struct crypter_t crypter_t;
 /**
  * @brief Generic interface for symmetric encryption algorithms.
  * 
- * @todo Distinguish between block_size and key_size, since not all
- * algorithms use key_size == block_size (e.g. 3DES).
- * 
- * @todo Add a getter which says if an algorithm uses fixed key size, needed for
- * tranform_attribute encoding.
+ * @b Constructors:
+ *  - crypter_create()
  * 
  * @ingroup crypters
  */
 struct crypter_t {
        /**
-        * @brief Encrypt a chunk of data and allocate space for 
-        * the encrypted value.
+        * @brief Encrypt a chunk of data and allocate space for the encrypted value.
         * 
         * @param this                          calling object
         * @param data                          data to encrypt
@@ -95,8 +87,7 @@ struct crypter_t {
        status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted);
        
        /**
-        * @brief Decrypt a chunk of data and allocate space for 
-        * the decrypted value.
+        * @brief Decrypt a chunk of data and allocate space for the decrypted value.
         * 
         * @param this                          calling object
         * @param data                          data to decrypt
@@ -115,6 +106,14 @@ struct crypter_t {
         * @return                                      block size in bytes
         */
        size_t (*get_block_size) (crypter_t *this);
+
+       /**
+        * @brief Get the key size of this crypter_t object.
+        * 
+        * @param this                          calling object
+        * @return                                      key size in bytes
+        */
+       size_t (*get_key_size) (crypter_t *this);
        
        /**
         * @brief Set the key for this crypter_t object.
@@ -123,7 +122,7 @@ struct crypter_t {
         * @param key                           key to set
         * @return
         *                                                      - SUCCESS
-        *                                                      - INVALID_ARG if key size != block size
+        *                                                      - INVALID_ARG if key length invalid
         */
        status_t (*set_key) (crypter_t *this, chunk_t key);
        
@@ -141,12 +140,14 @@ struct crypter_t {
  * Currently only the following algorithms are implemented and therefore supported:
  * - ENCR_AES_CBC
  * 
+ * The key_size is ignored for algorithms with fixed key size.
+ * 
  * @param encryption_algorithm Algorithm to use for crypter
- * @param blocksize                    block size in bytes
+ * @param key_size                             size of the key in bytes
  * @return
  *                                                             - crypter_t object
- *                                                             - NULL if encryption algorithm or blocksize is not supported
+ *                                                             - NULL if encryption algorithm/key_size is not supported
  */
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t blocksize);
+crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size);
 
 #endif /*CRYPTER_H_*/
index 9c75237..88900eb 100644 (file)
@@ -531,6 +531,14 @@ static status_t get_shared_secret(private_diffie_hellman_t *this,chunk_t *secret
 }
 
 /**
+ * Implementation of diffie_hellman_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_diffie_hellman_t *this)
+{
+       return this->dh_group_number;
+}
+
+/**
  * Implementation of diffie_hellman_t.destroy.
  */
 static void destroy(private_diffie_hellman_t *this)
@@ -562,6 +570,7 @@ diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t dh_group_number)
        this->public.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
        this->public.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
        this->public.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
+       this->public.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
        this->public.destroy = (void (*)(diffie_hellman_t *)) destroy;
        
        /* private functions */
index 2c0f948..d4f9563 100644 (file)
@@ -117,6 +117,14 @@ struct diffie_hellman_t {
         * @param[out]                          public_value public value of caller is stored at this location
         */
        void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *public_value);
+       
+       /**
+        * @brief Get the DH group used.
+        * 
+        * @param this                          calling diffie_hellman_t object
+        * @return                                      DH group set in construction
+        */
+       diffie_hellman_group_t (*get_dh_group) (diffie_hellman_t *this);
 
        /**
         * @brief Destroys an diffie_hellman_t object.
index af307a4..ce43300 100644 (file)
@@ -68,6 +68,15 @@ static size_t get_block_size(private_hmac_prf_t *this)
 }
 
 /**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_key_size(private_hmac_prf_t *this)
+{
+       /* for HMAC prfs, IKEv2 uses block size as key size */
+       return this->hmac->get_block_size(this->hmac);
+}
+
+/**
  * Implementation of prf_t.set_key.
  */
 static void set_key(private_hmac_prf_t *this, chunk_t key)
@@ -94,6 +103,7 @@ hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm)
        this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
        this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
        this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+       this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
        this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
        this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
        
index d96fc66..17b1110 100644 (file)
@@ -98,6 +98,14 @@ struct prf_t {
        size_t (*get_block_size) (prf_t *this);
        
        /**
+        * @brief Get the key size of this prf_t object.
+        * 
+        * @param this                  calling object
+        * @return                              key size in bytes
+        */
+       size_t (*get_key_size) (prf_t *this);
+       
+       /**
         * @brief Set the key for this prf_t object.
         * 
         * @param this                  calling object
index ed17b23..ee02901 100644 (file)
@@ -109,6 +109,7 @@ static bool verify_signature (private_hmac_signer_t *this, chunk_t data, chunk_t
  */
 static size_t get_key_size (private_hmac_signer_t *this)
 {
+       /* for HMAC signer, IKEv2 uses block size as key size */
        return this->hmac_prf->get_block_size(this->hmac_prf);
 }