diff options
-rw-r--r-- | Source/charon/daemon.c | 8 | ||||
-rw-r--r-- | Source/charon/daemon.h | 10 | ||||
-rw-r--r-- | Source/charon/sa/child_sa.h | 10 | ||||
-rw-r--r-- | Source/charon/sa/ike_sa.c | 50 | ||||
-rw-r--r-- | Source/charon/sa/ike_sa.h | 8 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_sa_init_responded.c | 21 | ||||
-rw-r--r-- | Source/charon/testcases/kernel_interface_test.c | 8 | ||||
-rw-r--r-- | Source/charon/testcases/testcases.c | 2 | ||||
-rw-r--r-- | Source/charon/threads/kernel_interface.c | 2 | ||||
-rw-r--r-- | Source/charon/utils/allocator.c | 33 |
10 files changed, 126 insertions, 26 deletions
diff --git a/Source/charon/daemon.c b/Source/charon/daemon.c index 4ba5d60be..8e5f5e4bb 100644 --- a/Source/charon/daemon.c +++ b/Source/charon/daemon.c @@ -187,7 +187,8 @@ static void initialize(private_daemon_t *this) this->public.sender = sender_create(); this->public.receiver = receiver_create(); this->public.scheduler = scheduler_create(); - this->public.thread_pool = thread_pool_create(NUMBER_OF_WORKING_THREADS); + this->public.kernel_interface = kernel_interface_create(); + this->public.thread_pool = thread_pool_create(NUMBER_OF_WORKING_THREADS); } /** @@ -195,6 +196,10 @@ static void initialize(private_daemon_t *this) */ static void destroy(private_daemon_t *this) { + if (this->public.kernel_interface != NULL) + { + this->public.kernel_interface->destroy(this->public.kernel_interface); + } if (this->public.receiver != NULL) { this->public.receiver->destroy(this->public.receiver); @@ -272,6 +277,7 @@ private_daemon_t *daemon_create() this->public.sender= NULL; this->public.receiver = NULL; this->public.scheduler = NULL; + this->public.kernel_interface = NULL; this->public.thread_pool = NULL; this->main_thread_id = pthread_self(); diff --git a/Source/charon/daemon.h b/Source/charon/daemon.h index 8d466dc76..4522bc347 100644 --- a/Source/charon/daemon.h +++ b/Source/charon/daemon.h @@ -26,6 +26,7 @@ #include <threads/sender.h> #include <threads/receiver.h> #include <threads/scheduler.h> +#include <threads/kernel_interface.h> #include <threads/thread_pool.h> #include <network/socket.h> #include <sa/ike_sa_manager.h> @@ -145,16 +146,21 @@ struct daemon_t { thread_pool_t *thread_pool; /** + * Kernel Interface to communicate with kernel + */ + kernel_interface_t *kernel_interface; + + /** * @brief Shut down the daemon. * * @param this the daemon to kill - * @param reason describition why it will be killed + * @param reason describtion why it will be killed */ void (*kill) (daemon_t *this, char *reason); }; /** - * One and only instance of the daemon. + * The one and only instance of the daemon. */ extern daemon_t *charon; diff --git a/Source/charon/sa/child_sa.h b/Source/charon/sa/child_sa.h index 593187d02..7c2e5a399 100644 --- a/Source/charon/sa/child_sa.h +++ b/Source/charon/sa/child_sa.h @@ -70,4 +70,14 @@ struct child_sa_t { */ child_sa_t * child_sa_create(protocol_id_t protocol_id, prf_plus_t *prf_plus); +/** + * @brief Constructor to create a new CHILD_SA. + * + * @param protocol_id protocol id (AH or ESP) of CHILD_SA + * @param prf_plus prf_plus_t object use to derive shared secrets + * @return child_sa_t object + * @ingroup sa + */ +child_sa_t * child_sa_create_with_spi(protocol_id_t protocol_id, prf_plus_t *prf_plus); + #endif /*_CHILD_SA_H_*/ diff --git a/Source/charon/sa/ike_sa.c b/Source/charon/sa/ike_sa.c index 254786800..2f403abf6 100644 --- a/Source/charon/sa/ike_sa.c +++ b/Source/charon/sa/ike_sa.c @@ -221,6 +221,20 @@ struct private_ike_sa_t { 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: @@ -234,11 +248,6 @@ struct private_ike_sa_t { */ struct { /** - * Key used for deriving other keys - */ - chunk_t d_key; - - /** * Key for generating auth payload (initiator) */ chunk_t pi_key; @@ -439,6 +448,8 @@ static void compute_secrets(private_ike_sa_t *this, 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)]; @@ -493,8 +504,9 @@ static void compute_secrets(private_ike_sa_t *this, allocator_free_chunk(&prf_plus_seed); - prf_plus->allocate_bytes(prf_plus,this->prf->get_block_size(this->prf),&(this->secrets.d_key)); - this->logger->log_chunk(this->logger, PRIVATE, "Sk_d secret", &(this->secrets.d_key)); + 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)); @@ -660,6 +672,14 @@ static prf_t *get_prf (private_ike_sa_t *this) } /** + * Implementation of protected_ike_sa_t.get_prf. + */ +static prf_t *get_child_prf (private_ike_sa_t *this) +{ + return this->child_prf; +} + +/** * Implementation of protected_ike_sa_t.get_key_pr. */ static chunk_t get_key_pr (private_ike_sa_t *this) @@ -704,6 +724,13 @@ static status_t create_transforms_from_proposal (private_ike_sa_t *this,ike_prop mapping_find(pseudo_random_function_m,proposal->pseudo_random_function)); return FAILED; } + this->child_prf = prf_create(proposal->pseudo_random_function); + if (this->child_prf == NULL) + { + this->logger->log(this->logger, ERROR|LEVEL1, "PRF %s not supported!", + mapping_find(pseudo_random_function_m,proposal->pseudo_random_function)); + return FAILED; + } if (this->crypter_initiator != NULL) { @@ -1056,7 +1083,6 @@ static void destroy (private_ike_sa_t *this) this->child_sas->destroy(this->child_sas); this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy secrets"); - allocator_free(this->secrets.d_key.ptr); allocator_free(this->secrets.pi_key.ptr); allocator_free(this->secrets.pr_key.ptr); @@ -1089,6 +1115,11 @@ static void destroy (private_ike_sa_t *this) this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy prf_t object"); this->prf->destroy(this->prf); } + if (this->child_prf != NULL) + { + this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy child_prf object"); + this->child_prf->destroy(this->child_prf); + } /* destroy ike_sa_id */ this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy ike_sa_id object"); @@ -1153,6 +1184,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) 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_logger = (logger_t *(*) (protected_ike_sa_t *)) get_logger; @@ -1198,7 +1230,6 @@ 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.d_key = CHUNK_INITIALIZER; this->secrets.pi_key = CHUNK_INITIALIZER; this->secrets.pr_key = CHUNK_INITIALIZER; this->crypter_initiator = NULL; @@ -1206,6 +1237,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->signer_initiator = NULL; this->signer_responder = NULL; this->prf = NULL; + this->child_prf = NULL; this->init_config = NULL; this->sa_config = NULL; diff --git a/Source/charon/sa/ike_sa.h b/Source/charon/sa/ike_sa.h index 25338363d..09101f7f5 100644 --- a/Source/charon/sa/ike_sa.h +++ b/Source/charon/sa/ike_sa.h @@ -376,6 +376,14 @@ struct protected_ike_sa_t { prf_t *(*get_prf) (protected_ike_sa_t *this); /** + * @brief Get the prf-object, which is used to derive keys for child SAs. + * + * @param this calling object + * @return pointer to prf_t object + */ + prf_t *(*get_child_prf) (protected_ike_sa_t *this); + + /** * @brief Get the last responded message. * * @param this calling object diff --git a/Source/charon/sa/states/ike_sa_init_responded.c b/Source/charon/sa/states/ike_sa_init_responded.c index cb4c42559..848d27db7 100644 --- a/Source/charon/sa/states/ike_sa_init_responded.c +++ b/Source/charon/sa/states/ike_sa_init_responded.c @@ -445,6 +445,27 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo response->add_payload(response, (payload_t*)sa_response); proposal->destroy(proposal); + /* install child SAs for AH and esp */ +// algorithm_t *encr, *integ; +// char enc_key_buffer[] = "123"; +// chunk_t enc_key = {ptr: enc_key_buffer, len: 4}; +// char int_key_buffer[] = "345"; +// chunk_t int_key = {ptr: int_key_buffer, len: 4}; +// proposal->get_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, &encr); +// proposal->get_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, &integ); +// +// charon->kernel_interface->add_sa(charon->kernel_interface, +// this->ike_sa->get_my_host(this->ike_sa), +// this->ike_sa->get_other_host(this->ike_sa), +// proposal->get_spi(proposal, AH), +// AH, +// TRUE, +// encr->algorithm, encr->key_size, enc_key, +// integ->algorithm, integ->key_size, int_key, +// TRUE); +// +// POS; + return SUCCESS; } diff --git a/Source/charon/testcases/kernel_interface_test.c b/Source/charon/testcases/kernel_interface_test.c index 8a24fb7b4..396736607 100644 --- a/Source/charon/testcases/kernel_interface_test.c +++ b/Source/charon/testcases/kernel_interface_test.c @@ -60,13 +60,13 @@ void test_kernel_interface(protected_tester_t *tester) kernel_interface = kernel_interface_create(); - me = host_create(AF_INET, "152.96.193.130", 500); - other = host_create(AF_INET, "152.96.193.130", 500); + me = host_create(AF_INET, "127.0.0.1", 0); + other = host_create(AF_INET, "127.0.0.1", 0); - status = kernel_interface->get_spi(kernel_interface, me, other, 50, TRUE, &spi); - tester->assert_true(tester, status == SUCCESS, "spi get"); + //status = kernel_interface->get_spi(kernel_interface, me, other, 50, TRUE, &spi); + //tester->assert_true(tester, status == SUCCESS, "spi get"); status = kernel_interface->add_sa(kernel_interface, me, other, spi, 50, TRUE, ENCR_AES_CBC, 16, enc_key,AUTH_HMAC_MD5_96,16,inc_key,TRUE); tester->assert_true(tester, status == SUCCESS, "build sa"); diff --git a/Source/charon/testcases/testcases.c b/Source/charon/testcases/testcases.c index 40a114206..170ebf6e8 100644 --- a/Source/charon/testcases/testcases.c +++ b/Source/charon/testcases/testcases.c @@ -250,7 +250,7 @@ int main() //tester->perform_tests(tester,all_tests); - tester->perform_test(tester,&child_proposal_test); + tester->perform_test(tester,&kernel_interface_test); tester->destroy(tester); diff --git a/Source/charon/threads/kernel_interface.c b/Source/charon/threads/kernel_interface.c index ac0cafe3c..4acf14cd4 100644 --- a/Source/charon/threads/kernel_interface.c +++ b/Source/charon/threads/kernel_interface.c @@ -209,7 +209,7 @@ static status_t add_sa( private_kernel_interface_t *this, bool replace) { netlink_message_t request, *response; - + POS; memset(&request, 0, sizeof(request)); request.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; diff --git a/Source/charon/utils/allocator.c b/Source/charon/utils/allocator.c index 5bb545f0b..0ed197c62 100644 --- a/Source/charon/utils/allocator.c +++ b/Source/charon/utils/allocator.c @@ -96,6 +96,16 @@ struct private_allocator_t */ pthread_mutex_t mutex; + /** + * Number of allocations done + */ + u_int32_t allocs; + + /** + * Number of frees done + */ + u_int32_t frees; + /** * Allocates memory with LEAK_DETECTION and * returns an empty data area filled with zeros. @@ -115,8 +125,10 @@ struct private_allocator_t */ static void *allocate_special(private_allocator_t *this,size_t bytes, char * file,int line, bool use_mutex) { - memory_hdr_t *allocated_memory = malloc(sizeof(memory_hdr_t) + bytes);; - + memory_hdr_t *allocated_memory = malloc(sizeof(memory_hdr_t) + bytes); + + this->allocs++; + if (allocated_memory == NULL) { /* TODO LOG this case */ @@ -127,7 +139,7 @@ static void *allocate_special(private_allocator_t *this,size_t bytes, char * fil { pthread_mutex_lock( &(this->mutex)); } - + allocated_memory->info.line = line; allocated_memory->info.filename = file; allocated_memory->info.size_of_memory = bytes; @@ -145,7 +157,7 @@ static void *allocate_special(private_allocator_t *this,size_t bytes, char * fil { pthread_mutex_unlock(&(this->mutex)); } - + /* real memory starts after header */ return (allocated_memory+1); } @@ -178,11 +190,13 @@ static void free_pointer(allocator_t *allocator, void * pointer) { private_allocator_t *this = (private_allocator_t *) allocator; memory_hdr_t *allocated_memory; + if (pointer == NULL) { return; } + this->frees++; pthread_mutex_lock( &(this->mutex)); allocated_memory = ((memory_hdr_t *)pointer) - 1; @@ -294,13 +308,14 @@ static void allocator_report_memory_leaks(allocator_t *allocator) if (p == NULL || pprev->info.filename != p->info.filename) { if (n != 1) - fprintf(stderr,"LEAK: \"%lu * File %s, Line %d\"\n", n, pprev->info.filename,pprev->info.line); + fprintf(stderr,"LEAK: \"%lu * %s, line %d\"\n", n, pprev->info.filename,pprev->info.line); else - fprintf(stderr,"LEAK: \"%s, Line %d\"\n", pprev->info.filename,pprev->info.line); + fprintf(stderr,"LEAK: \"%s, line %d\"\n", pprev->info.filename,pprev->info.line); n = 0; } } - pthread_mutex_unlock( &(this->mutex)); + pthread_mutex_unlock( &(this->mutex)); + fprintf(stderr, "Allocator statistics: %d allocs, %d frees\n", this->allocs, this->frees); } /** @@ -318,7 +333,9 @@ static private_allocator_t allocator = { report_memory_leaks: allocator_report_memory_leaks}, allocations: NULL, allocate_special : allocate_special, - mutex: PTHREAD_MUTEX_INITIALIZER + mutex: PTHREAD_MUTEX_INITIALIZER, + allocs: 0, + frees: 0 }; |