diff options
author | Jan Hutter <jhutter@hsr.ch> | 2005-11-29 17:19:59 +0000 |
---|---|---|
committer | Jan Hutter <jhutter@hsr.ch> | 2005-11-29 17:19:59 +0000 |
commit | f890d8fe62b2f3bbf560a6ed2f532da2aab9c4dd (patch) | |
tree | ec03ffe188c72a576eac7275aaace0f93c9be634 | |
parent | 0f803b4771a94b65344faaea208904428c09aca6 (diff) | |
download | strongswan-f890d8fe62b2f3bbf560a6ed2f532da2aab9c4dd.tar.bz2 strongswan-f890d8fe62b2f3bbf560a6ed2f532da2aab9c4dd.tar.xz |
- encryption seems to work
-rw-r--r-- | Source/charon/daemon.c | 2 | ||||
-rw-r--r-- | Source/charon/encoding/message.c | 148 | ||||
-rw-r--r-- | Source/charon/sa/ike_sa.c | 37 | ||||
-rw-r--r-- | Source/charon/sa/ike_sa.h | 17 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_sa_init_requested.c | 83 | ||||
-rw-r--r-- | Source/charon/testcases/testcases.c | 1 | ||||
-rw-r--r-- | Source/charon/transforms/signers/hmac_signer.c | 6 | ||||
-rw-r--r-- | Source/charon/transforms/signers/signer.h | 8 |
8 files changed, 271 insertions, 31 deletions
diff --git a/Source/charon/daemon.c b/Source/charon/daemon.c index 7fe3d5b28..175cfa372 100644 --- a/Source/charon/daemon.c +++ b/Source/charon/daemon.c @@ -159,7 +159,7 @@ static void build_test_jobs(private_daemon_t *this) for(i = 0; i<1; i++) { initiate_ike_sa_job_t *initiate_job; - initiate_job = initiate_ike_sa_job_create("localhost"); + initiate_job = initiate_ike_sa_job_create("pinflb30"); this->public.job_queue->add(this->public.job_queue, (job_t*)initiate_job); } } diff --git a/Source/charon/encoding/message.c b/Source/charon/encoding/message.c index 389b3339b..11a814ba1 100644 --- a/Source/charon/encoding/message.c +++ b/Source/charon/encoding/message.c @@ -58,6 +58,11 @@ struct supported_payload_entry_t { * Max occurence of this payload. */ size_t max_occurence; + + /** + * TRUE if payload has to get encrypted + */ + bool encrypted; }; typedef struct message_rule_t message_rule_t; @@ -92,9 +97,9 @@ struct message_rule_t { */ static supported_payload_entry_t supported_ike_sa_init_i_payloads[] = { - {SECURITY_ASSOCIATION,1,1}, - {KEY_EXCHANGE,1,1}, - {NONCE,1,1}, + {SECURITY_ASSOCIATION,1,1,FALSE}, + {KEY_EXCHANGE,1,1,FALSE}, + {NONCE,1,1,FALSE}, }; /** @@ -102,18 +107,47 @@ static supported_payload_entry_t supported_ike_sa_init_i_payloads[] = */ static supported_payload_entry_t supported_ike_sa_init_r_payloads[] = { - {SECURITY_ASSOCIATION,1,1}, - {KEY_EXCHANGE,1,1}, - {NONCE,1,1}, + {SECURITY_ASSOCIATION,1,1,FALSE}, + {KEY_EXCHANGE,1,1,FALSE}, + {NONCE,1,1,FALSE}, }; +/** + * Message rule for IKE_AUTH from initiator. + */ +static supported_payload_entry_t supported_ike_auth_i_payloads[] = +{ + {ID_INITIATOR,1,1,TRUE}, + {CERTIFICATE,0,1,TRUE}, + {CERTIFICATE_REQUEST,0,1,TRUE}, + {ID_RESPONDER,0,1,TRUE}, + {AUTHENTICATION,1,1,TRUE}, + {SECURITY_ASSOCIATION,1,1,TRUE}, + {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE}, + {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE}, +}; + +/** + * Message rule for IKE_AUTH from responder. + */ +static supported_payload_entry_t supported_ike_auth_r_payloads[] = +{ + {CERTIFICATE,0,1,TRUE}, + {ID_RESPONDER,0,1,TRUE}, + {AUTHENTICATION,1,1,TRUE}, + {SECURITY_ASSOCIATION,1,1,TRUE}, + {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE}, + {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE}, +}; /** * Message rules, defines allowed payloads. */ static message_rule_t message_rules[] = { {IKE_SA_INIT,TRUE,(sizeof(supported_ike_sa_init_i_payloads)/sizeof(supported_payload_entry_t)),supported_ike_sa_init_i_payloads}, - {IKE_SA_INIT,FALSE,(sizeof(supported_ike_sa_init_r_payloads)/sizeof(supported_payload_entry_t)),supported_ike_sa_init_r_payloads} + {IKE_SA_INIT,FALSE,(sizeof(supported_ike_sa_init_r_payloads)/sizeof(supported_payload_entry_t)),supported_ike_sa_init_r_payloads}, + {IKE_AUTH,TRUE,(sizeof(supported_ike_auth_i_payloads)/sizeof(supported_payload_entry_t)),supported_ike_auth_i_payloads}, + {IKE_AUTH,FALSE,(sizeof(supported_ike_auth_r_payloads)/sizeof(supported_payload_entry_t)),supported_ike_auth_r_payloads} }; typedef struct payload_entry_t payload_entry_t; @@ -218,6 +252,13 @@ struct private_message_t { */ status_t (*get_supported_payloads) (private_message_t *this, supported_payload_entry_t **supported_payloads,size_t *supported_payloads_count); + /** + * Encrypts all payloads which has to get encrypted. + * + * @param this calling object + */ + status_t (*encrypt_payloads) (private_message_t *this,crypter_t *crypter, signer_t* signer); + }; /** @@ -463,6 +504,13 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* return INVALID_STATE; } + status = this->encrypt_payloads(this,crypter,signer); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Could not encrypt payloads"); + return status; + } + /* build ike header */ ike_header = ike_header_create(); @@ -472,7 +520,8 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* ike_header->set_initiator_flag(ike_header, this->ike_sa_id->is_initiator(this->ike_sa_id)); ike_header->set_initiator_spi(ike_header, this->ike_sa_id->get_initiator_spi(this->ike_sa_id)); ike_header->set_responder_spi(ike_header, this->ike_sa_id->get_responder_spi(this->ike_sa_id)); - + + generator = generator_create(); payload = (payload_t*)ike_header; @@ -493,18 +542,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* /* build last payload */ payload->set_next_type(payload, NO_PAYLOAD); /* if it's an encryption payload, build it first */ - if (payload->get_type(payload) == ENCRYPTED) - { - encryption_payload_t *encryption_payload = (encryption_payload_t*)payload; - encryption_payload->set_transforms(encryption_payload, crypter, signer); - status = encryption_payload->encrypt(encryption_payload); - if (status != SUCCESS) - { - generator->destroy(generator); - ike_header->destroy(ike_header); - return status; - } - } + generator->generate_payload(generator, payload); ike_header->destroy(ike_header); @@ -712,6 +750,73 @@ static status_t verify(private_message_t *this) } +static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, signer_t* signer) +{ + status_t status; + supported_payload_entry_t *supported_payloads; + size_t supported_payloads_count; + encryption_payload_t *encryption_payload = NULL; + linked_list_t *all_payloads = linked_list_create(); + int i; + + status = this->get_supported_payloads(this, &supported_payloads, &supported_payloads_count); + if (status != SUCCESS) + { + return status; + } + + /* first copy all payloads in a temporary list */ + while (this->payloads->get_count(this->payloads) > 0) + { + void *current_payload; + this->payloads->remove_first(this->payloads,¤t_payload); + all_payloads->insert_last(all_payloads,current_payload); + } + + while (all_payloads->get_count(all_payloads) > 0) + { + payload_t *current_payload; + bool to_encrypt = FALSE; + + all_payloads->remove_first(all_payloads,(void **)¤t_payload); + + for (i = 0; i < supported_payloads_count;i++) + { + if ((supported_payloads[i].payload_type == current_payload->get_type(current_payload)) && + (supported_payloads[i].encrypted)) + { + to_encrypt = TRUE; + break; + } + } + + if (to_encrypt) + { + if (encryption_payload == NULL) + { + encryption_payload = encryption_payload_create(); + } + encryption_payload->add_payload(encryption_payload,current_payload); + } + else + { + this->payloads->insert_last(this->payloads,current_payload); + } + } + + status = SUCCESS; + if (encryption_payload != NULL) + { + encryption_payload->set_transforms(encryption_payload,crypter,signer); + status = encryption_payload->encrypt(encryption_payload); + this->payloads->insert_last(this->payloads,encryption_payload); + } + + all_payloads->destroy(all_payloads); + + return status; +} + /** * Implements message_t's destroy function. * See #message_s.destroy. @@ -777,7 +882,7 @@ message_t *message_create_from_packet(packet_t *packet) this->public.verify = (status_t (*) (message_t*)) verify; this->public.destroy = (void(*)(message_t*))destroy; - /* public values */ + /* private values */ this->exchange_type = EXCHANGE_TYPE_UNDEFINED; this->is_request = TRUE; this->ike_sa_id = NULL; @@ -786,6 +891,7 @@ message_t *message_create_from_packet(packet_t *packet) /* private functions */ this->get_supported_payloads = get_supported_payloads; + this->encrypt_payloads = encrypt_payloads; /* private values */ if (packet == NULL) diff --git a/Source/charon/sa/ike_sa.c b/Source/charon/sa/ike_sa.c index 7d6fcef20..60e608678 100644 --- a/Source/charon/sa/ike_sa.c +++ b/Source/charon/sa/ike_sa.c @@ -374,6 +374,15 @@ static void compute_secrets(private_ike_sa_t *this,chunk_t dh_shared_secret,chun 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->allocate_bytes(prf_plus,this->signer_initiator->get_key_size(this->signer_initiator),&(this->secrets.ai_key)); + this->logger->log_chunk(this->logger, PRIVATE, "Sk_ai secret", &(this->secrets.ai_key)); + this->signer_initiator->set_key(this->signer_initiator,this->secrets.ai_key); + + prf_plus->allocate_bytes(prf_plus,this->signer_responder->get_key_size(this->signer_responder),&(this->secrets.ar_key)); + this->logger->log_chunk(this->logger, PRIVATE, "Sk_ar secret", &(this->secrets.ar_key)); + this->signer_responder->set_key(this->signer_responder,this->secrets.ar_key); + + prf_plus->allocate_bytes(prf_plus,this->crypter_initiator->get_block_size(this->crypter_initiator),&(this->secrets.ei_key)); this->logger->log_chunk(this->logger, PRIVATE, "Sk_ei secret", &(this->secrets.ei_key)); this->crypter_initiator->set_key(this->crypter_initiator,this->secrets.ei_key); @@ -382,14 +391,6 @@ static void compute_secrets(private_ike_sa_t *this,chunk_t dh_shared_secret,chun this->logger->log_chunk(this->logger, PRIVATE, "Sk_er secret", &(this->secrets.er_key)); this->crypter_responder->set_key(this->crypter_responder,this->secrets.er_key); - prf_plus->allocate_bytes(prf_plus,this->signer_initiator->get_block_size(this->signer_initiator),&(this->secrets.ai_key)); - this->logger->log_chunk(this->logger, PRIVATE, "Sk_ai secret", &(this->secrets.ai_key)); - this->signer_initiator->set_key(this->signer_initiator,this->secrets.ai_key); - - prf_plus->allocate_bytes(prf_plus,this->signer_responder->get_block_size(this->signer_responder),&(this->secrets.ar_key)); - this->logger->log_chunk(this->logger, PRIVATE, "Sk_ar secret", &(this->secrets.ar_key)); - this->signer_responder->set_key(this->signer_responder,this->secrets.ar_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)); @@ -601,6 +602,22 @@ static randomizer_t *get_randomizer (private_ike_sa_t *this) } /** + * Implementation of protected_ike_sa_t.get_crypter_initiator. + */ +static crypter_t *get_crypter_initiator (private_ike_sa_t *this) +{ + return this->crypter_initiator; +} + +/** + * Implementation of protected_ike_sa_t.get_signer_initiator. + */ +static signer_t *get_signer_initiator (private_ike_sa_t *this) +{ + return this->signer_initiator; +} + +/** * Implementation of protected_ike_sa_t.set_last_requested_message. */ static status_t set_last_requested_message (private_ike_sa_t *this,message_t * message) @@ -769,12 +786,16 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->protected.set_last_responded_message = (status_t (*) (protected_ike_sa_t *,message_t *)) set_last_responded_message; this->protected.create_transforms_from_proposal = (status_t (*) (protected_ike_sa_t *,proposal_substructure_t *)) create_transforms_from_proposal; 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; /* private functions */ this->resend_last_reply = resend_last_reply; this->create_delete_job = create_delete_job; + + /* initialize private fields */ this->logger = charon->logger_manager->create_logger(charon->logger_manager, IKE_SA, NULL); diff --git a/Source/charon/sa/ike_sa.h b/Source/charon/sa/ike_sa.h index b4abfa48c..51d8be4e0 100644 --- a/Source/charon/sa/ike_sa.h +++ b/Source/charon/sa/ike_sa.h @@ -230,6 +230,23 @@ struct protected_ike_sa_t { * @param state pointer to the new state_t object */ void (*set_new_state) (protected_ike_sa_t *this,state_t *state); + + /** + * Gets the internal stored initiator crypter_t object. + * + * @param this calling object + * @return pointer to crypter_t object + */ + crypter_t *(*get_crypter_initiator) (protected_ike_sa_t *this); + + /** + * Gets the internal stored initiator signer object. + * + * @param this calling object + * @return pointer to signer_t object + */ + signer_t *(*get_signer_initiator) (protected_ike_sa_t *this); + }; diff --git a/Source/charon/sa/states/ike_sa_init_requested.c b/Source/charon/sa/states/ike_sa_init_requested.c index c039e733a..0663f0a5e 100644 --- a/Source/charon/sa/states/ike_sa_init_requested.c +++ b/Source/charon/sa/states/ike_sa_init_requested.c @@ -27,6 +27,7 @@ #include <encoding/payloads/sa_payload.h> #include <encoding/payloads/ke_payload.h> #include <encoding/payloads/nonce_payload.h> +#include <encoding/payloads/id_payload.h> #include <transforms/diffie_hellman.h> @@ -80,6 +81,24 @@ struct private_ike_sa_init_requested_t { * Is logger of ike_sa! */ logger_t *logger; + + /** + * Builds the IKE_SA_AUTH request message. + * + * @param this calling object + * @param message the created message will be stored at this location + */ + void (*build_ike_auth_request) (private_ike_sa_init_requested_t *this, message_t **message); + + /** + * Builds the id payload for this state. + * + * @param this calling object + * @param payload The generated payload object of type id_payload_t is + * stored at this location. + */ + void (*build_id_payload) (private_ike_sa_init_requested_t *this, payload_t **payload); + }; /** @@ -90,6 +109,8 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t status_t status; iterator_t *payloads; exchange_type_t exchange_type; + message_t *request; + packet_t *packet; u_int64_t responder_spi; ike_sa_id_t *ike_sa_id; @@ -227,6 +248,25 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t this->ike_sa->compute_secrets(this->ike_sa,this->shared_secret,this->sent_nonce, this->received_nonce); + this->build_ike_auth_request (this,&request); + + /* generate packet */ + this->logger->log(this->logger, CONTROL|MOST, "generate packet from message"); + + status = request->generate(request, this->ike_sa->get_crypter_initiator(this->ike_sa), this->ike_sa->get_signer_initiator(this->ike_sa), &packet); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "could not generate packet from message"); + message->destroy(message); + return status; + } + + this->logger->log(this->logger, CONTROL|MOST, "Add packet to global send queue"); + charon->send_queue->add(charon->send_queue, packet); + + + request->destroy(request); + /**************************** * * TODO @@ -252,6 +292,45 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t } /** + * implements private_ike_sa_init_requested_t.build_ike_auth_request + */ +static void build_ike_auth_request (private_ike_sa_init_requested_t *this, message_t **request) +{ + payload_t *payload; + message_t *message; + + /* going to build message */ + this->logger->log(this->logger, CONTROL|MOST, "Going to build empty message"); + this->ike_sa->build_message(this->ike_sa, IKE_AUTH, TRUE, &message); + + + /* build id payload */ + this->build_id_payload(this, &payload); + this->logger->log(this->logger, CONTROL|MOST, "add id payload to message"); + message->add_payload(message, payload); + + *request = message; +} + +static void build_id_payload (private_ike_sa_init_requested_t *this, payload_t **payload) +{ + id_payload_t *id_payload; + chunk_t email; + + /* create IDi */ + id_payload = id_payload_create(TRUE); + /* TODO special functions on id payload */ + /* TODO configuration manager request */ + id_payload->set_id_type(id_payload,ID_RFC822_ADDR); + email.ptr = "moerdi@hsr.ch"; + email.len = strlen(email.ptr); + this->logger->log_chunk(this->logger, CONTROL, "Moerdi",&email); + id_payload->set_data(id_payload,email); + + *payload = (payload_t *) id_payload; +} + +/** * Implements state_t.get_state */ static ike_sa_state_t get_state(private_ike_sa_init_requested_t *this) @@ -287,6 +366,10 @@ ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state; this->public.state_interface.destroy = (void (*) (state_t *)) destroy; + /* private functions */ + this->build_ike_auth_request = build_ike_auth_request; + this->build_id_payload = build_id_payload; + /* private data */ this->ike_sa = ike_sa; this->received_nonce = CHUNK_INITIALIZER; diff --git a/Source/charon/testcases/testcases.c b/Source/charon/testcases/testcases.c index e62ba5f1f..23a6e0a79 100644 --- a/Source/charon/testcases/testcases.c +++ b/Source/charon/testcases/testcases.c @@ -211,7 +211,6 @@ int main() //tester->perform_test(tester,&encryption_payload_test); - tester->destroy(tester); charon->kill(charon, NULL); diff --git a/Source/charon/transforms/signers/hmac_signer.c b/Source/charon/transforms/signers/hmac_signer.c index e6aeeae47..a38999567 100644 --- a/Source/charon/transforms/signers/hmac_signer.c +++ b/Source/charon/transforms/signers/hmac_signer.c @@ -96,6 +96,11 @@ static void verify_signature (private_hmac_signer_t *this, chunk_t data, chunk_t *valid = FALSE; } } + +static size_t get_key_size (private_hmac_signer_t *this) +{ + return this->hmac_prf->get_block_size(this->hmac_prf); +} static size_t get_block_size (private_hmac_signer_t *this) { @@ -138,6 +143,7 @@ hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm) this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature; this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature; this->public.signer_interface.verify_signature = (void (*) (signer_t*, chunk_t, chunk_t,bool *))verify_signature; + this->public.signer_interface.get_key_size = (size_t (*) (signer_t*))get_key_size; this->public.signer_interface.get_block_size = (size_t (*) (signer_t*))get_block_size; this->public.signer_interface.set_key = (void (*) (signer_t*,chunk_t))set_key; this->public.signer_interface.destroy = (void (*) (signer_t*))destroy; diff --git a/Source/charon/transforms/signers/signer.h b/Source/charon/transforms/signers/signer.h index eb6a68a93..ef0a89aed 100644 --- a/Source/charon/transforms/signers/signer.h +++ b/Source/charon/transforms/signers/signer.h @@ -92,6 +92,14 @@ struct signer_t { size_t (*get_block_size) (signer_t *this); /** + * @brief Get the key size of the signature algorithm. + * + * @param this calling signer + * @return key size in bytes + */ + size_t (*get_key_size) (signer_t *this); + + /** * @brief Set the key for this signer. * * @param this calling signer |