aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/sa
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/sa')
-rw-r--r--src/charon/sa/authenticator.c17
-rw-r--r--src/charon/sa/ike_sa.c210
-rw-r--r--src/charon/sa/ike_sa.h9
-rw-r--r--src/charon/sa/states/ike_auth_requested.c123
-rw-r--r--src/charon/sa/states/ike_sa_established.c28
-rw-r--r--src/charon/sa/states/ike_sa_init_requested.c267
-rw-r--r--src/charon/sa/states/ike_sa_init_responded.c305
-rw-r--r--src/charon/sa/states/initiator_init.c52
-rw-r--r--src/charon/sa/states/responder_init.c120
9 files changed, 661 insertions, 470 deletions
diff --git a/src/charon/sa/authenticator.c b/src/charon/sa/authenticator.c
index e895e2df3..aefd1e941 100644
--- a/src/charon/sa/authenticator.c
+++ b/src/charon/sa/authenticator.c
@@ -243,15 +243,14 @@ static status_t verify_auth_data (private_authenticator_t *this,
}
case RSA_DIGITAL_SIGNATURE:
{
- identification_t *other_id = other_id_payload->get_identification(other_id_payload);
- rsa_public_key_t *public_key;
status_t status;
- chunk_t octets, auth_data;
-
- auth_data = auth_payload->get_data(auth_payload);
-
- public_key = charon->credentials->get_rsa_public_key(charon->credentials,
- other_id);
+ chunk_t octets;
+ chunk_t auth_data = auth_payload->get_data(auth_payload);
+ identification_t *other_id = other_id_payload->get_identification(other_id_payload);
+
+ rsa_public_key_t *public_key =
+ charon->credentials->get_trusted_public_key(charon->credentials, other_id);
+
if (public_key == NULL)
{
this->logger->log(this->logger, ERROR, "no public key found for '%s'",
@@ -274,7 +273,6 @@ static status_t verify_auth_data (private_authenticator_t *this,
other_id->get_string(other_id));
}
- public_key->destroy(public_key);
other_id->destroy(other_id);
chunk_free(&octets);
return status;
@@ -356,7 +354,6 @@ static status_t compute_auth_data (private_authenticator_t *this,
this->logger->log(this->logger, CONTROL|LEVEL1, "looking for private key with keyid %s", buf);
my_key = charon->credentials->get_rsa_private_key(charon->credentials, my_pubkey);
- my_pubkey->destroy(my_pubkey);
if (my_key == NULL)
{
char buf[BUF_LEN];
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c
index 2ba9c7432..4bff80846 100644
--- a/src/charon/sa/ike_sa.c
+++ b/src/charon/sa/ike_sa.c
@@ -230,7 +230,7 @@ static void build_message(private_ike_sa_t *this, exchange_type_t type, bool req
me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_host(this->connection);
- this->logger->log(this->logger, CONTROL|LEVEL2, "Build empty message");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "build empty message");
new_message = message_create();
new_message->set_source(new_message, me->clone(me));
new_message->set_destination(new_message, other->clone(other));
@@ -255,7 +255,7 @@ static ike_sa_state_t get_state(private_ike_sa_t *this)
*/
static void set_new_state(private_ike_sa_t *this, state_t *state)
{
- this->logger->log(this->logger, CONTROL, "statechange: %s => %s",
+ this->logger->log(this->logger, CONTROL, "state change: %s => %s",
mapping_find(ike_sa_state_m, get_state(this)),
mapping_find(ike_sa_state_m, state->get_state(state)));
this->current_state = state;
@@ -387,7 +387,7 @@ static status_t retransmit_request(private_ike_sa_t *this, u_int32_t message_id)
return NOT_FOUND;
}
- this->logger->log(this->logger, CONTROL | LEVEL1, "Going to retransmit message with id %d",message_id);
+ this->logger->log(this->logger, CONTROL | LEVEL1, "going to retransmit message with id %d",message_id);
packet = this->last_requested_message->get_packet(this->last_requested_message);
charon->send_queue->add(charon->send_queue, packet);
this->update_timestamp(this, FALSE);
@@ -414,7 +414,7 @@ static status_t build_transforms(private_ike_sa_t *this, proposal_t *proposal, d
}
if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo))
{
- this->logger->log(this->logger, ERROR|LEVEL2, "No PRF algoithm selected!?");
+ this->logger->log(this->logger, ERROR|LEVEL2, "no PRF algoithm selected!?");
return FAILED;
}
this->prf = prf_create(algo->algorithm);
@@ -441,7 +441,7 @@ static status_t build_transforms(private_ike_sa_t *this, proposal_t *proposal, d
/* 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->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);
@@ -479,7 +479,7 @@ static status_t build_transforms(private_ike_sa_t *this, proposal_t *proposal, d
/* SK_ai/SK_ar used for integrity protection */
if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &algo))
{
- this->logger->log(this->logger, ERROR, "No integrity algoithm selected?!");
+ this->logger->log(this->logger, ERROR, "no integrity algoithm selected?!");
return FAILED;
}
if (this->signer_initiator != NULL)
@@ -516,7 +516,7 @@ static status_t build_transforms(private_ike_sa_t *this, proposal_t *proposal, d
/* SK_ei/SK_er used for encryption */
if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &algo))
{
- this->logger->log(this->logger, ERROR, "No encryption algoithm selected!?");
+ this->logger->log(this->logger, ERROR, "no encryption algoithm selected!?");
return FAILED;
}
if (this->crypter_initiator != NULL)
@@ -631,7 +631,7 @@ static void update_timestamp(private_ike_sa_t *this, bool in)
if (0 > gettimeofday(tv, NULL))
{
this->logger->log(this->logger, ERROR|LEVEL1,
- "Warning: Failed to get time of day.");
+ "warning: failed to get time of day.");
}
}
@@ -649,13 +649,13 @@ static status_t send_request(private_ike_sa_t *this, message_t *message)
if (message->get_message_id(message) != this->message_id_out)
{
- this->logger->log(this->logger, ERROR, "Message could not be sent cause id (%d) was not as expected (%d)",
+ this->logger->log(this->logger, ERROR, "message could not be sent cause id (%d) was not as expected (%d)",
message->get_message_id(message),this->message_id_out);
return FAILED;
}
/* generate packet */
- this->logger->log(this->logger, CONTROL|LEVEL2, "Generate packet from message");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "generate packet from message");
if (this->ike_sa_id->is_initiator(this->ike_sa_id))
{
@@ -671,12 +671,12 @@ static status_t send_request(private_ike_sa_t *this, message_t *message)
status = message->generate(message, crypter,signer, &packet);
if (status != SUCCESS)
{
- this->logger->log(this->logger, ERROR, "Could not generate packet from message");
+ this->logger->log(this->logger, ERROR, "could not generate packet from message");
return FAILED;
}
this->logger->log(this->logger, CONTROL|LEVEL3,
- "Add request packet with message id %d to global send queue",
+ "add request packet with message id %d to global send queue",
this->message_id_out);
charon->send_queue->add(charon->send_queue, packet);
@@ -685,25 +685,25 @@ static status_t send_request(private_ike_sa_t *this, message_t *message)
{
this->last_requested_message->destroy(this->last_requested_message);
}
- this->logger->log(this->logger, CONTROL|LEVEL3, "Replace last requested message with new one");
+ this->logger->log(this->logger, CONTROL|LEVEL3, "replace last requested message with new one");
this->last_requested_message = message;
/* schedule a job for retransmission */
status = charon->configuration->get_retransmit_timeout(charon->configuration, 0, &timeout);
if (status != SUCCESS)
{
- this->logger->log(this->logger, CONTROL|LEVEL2, "No retransmit job for message created!");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "no retransmit job for message created!");
}
else
{
- this->logger->log(this->logger, CONTROL|LEVEL2, "Request will be retransmitted in %d ms.", timeout);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "request will be retransmitted in %d ms.", timeout);
retransmit_job = retransmit_request_job_create(this->message_id_out, this->ike_sa_id);
charon->event_queue->add_relative(charon->event_queue, (job_t *)retransmit_job, timeout);
}
/* message counter can now be increased */
this->logger->log(this->logger, CONTROL|LEVEL3,
- "Increase message counter for outgoing messages from %d",
+ "increase message counter for outgoing messages from %d",
this->message_id_out);
this->message_id_out++;
@@ -724,7 +724,7 @@ static status_t send_response(private_ike_sa_t *this, message_t *message)
if (message->get_message_id(message) != this->message_id_in)
{
- this->logger->log(this->logger, ERROR, "Message could not be sent cause id (%d) was not as expected (%d)",
+ this->logger->log(this->logger, ERROR, "message could not be sent cause id (%d) was not as expected (%d)",
message->get_message_id(message),this->message_id_in);
return FAILED;
}
@@ -743,12 +743,12 @@ static status_t send_response(private_ike_sa_t *this, message_t *message)
status = message->generate(message, crypter,signer, &packet);
if (status != SUCCESS)
{
- this->logger->log(this->logger, ERROR, "Could not generate packet from message");
+ this->logger->log(this->logger, ERROR, "could not generate packet from message");
return FAILED;
}
this->logger->log(this->logger, CONTROL|LEVEL3,
- "Add response packet with message id %d to global send queue",
+ "add response packet with message id %d to global send queue",
this->message_id_in);
charon->send_queue->add(charon->send_queue, packet);
@@ -758,11 +758,11 @@ static status_t send_response(private_ike_sa_t *this, message_t *message)
this->last_responded_message->destroy(this->last_responded_message);
}
- this->logger->log(this->logger, CONTROL|LEVEL3, "Replace last responded message with new one");
+ this->logger->log(this->logger, CONTROL|LEVEL3, "replace last responded message with new one");
this->last_responded_message = message;
/* message counter can now be increased */
- this->logger->log(this->logger, CONTROL|LEVEL3, "Increase message counter for incoming messages");
+ this->logger->log(this->logger, CONTROL|LEVEL3, "increase message counter for incoming messages");
this->message_id_in++;
this->update_timestamp(this, FALSE);
@@ -780,32 +780,32 @@ static void send_notify(private_ike_sa_t *this, exchange_type_t exchange_type, n
packet_t *packet;
status_t status;
- this->logger->log(this->logger, CONTROL|LEVEL2, "Going to build message with notify payload");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "going to build message with notify payload");
/* set up the reply */
build_message(this, exchange_type, FALSE, &response);
payload = notify_payload_create_from_protocol_and_type(PROTO_NONE, type);
if ((data.ptr != NULL) && (data.len > 0))
{
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add Data to notify payload");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add Data to notify payload");
payload->set_notification_data(payload,data);
}
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add Notify payload to message");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add Notify payload to message");
response->add_payload(response,(payload_t *) payload);
/* generate packet */
- this->logger->log(this->logger, CONTROL|LEVEL2, "Generate packet from message");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "generate packet from message");
status = response->generate(response, this->crypter_responder, this->signer_responder, &packet);
if (status != SUCCESS)
{
- this->logger->log(this->logger, ERROR|LEVEL1, "Could not generate notify message");
+ this->logger->log(this->logger, ERROR|LEVEL1, "could not generate notify message");
response->destroy(response);
return;
}
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add packet to global send queue");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add packet to global send queue");
charon->send_queue->add(charon->send_queue, packet);
- this->logger->log(this->logger, CONTROL|LEVEL2, "Destroy message");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "destroy message");
response->destroy(response);
this->update_timestamp(this, FALSE);
@@ -856,7 +856,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
is_request = message->get_request(message);
exchange_type = message->get_exchange_type(message);
- this->logger->log(this->logger, CONTROL|LEVEL1, "Process %s of exchange type %s",
+ this->logger->log(this->logger, CONTROL|LEVEL1, "process %s of exchange type %s",
(is_request) ? "request" : "response",
mapping_find(exchange_type_m, exchange_type));
@@ -869,7 +869,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
if (this->last_responded_message)
{
packet_t *packet = this->last_responded_message->get_packet(this->last_responded_message);
- this->logger->log(this->logger, CONTROL|LEVEL1, "Resent request detected. Send stored reply.");
+ this->logger->log(this->logger, CONTROL|LEVEL1, "resent request detected. Send stored reply.");
charon->send_queue->add(charon->send_queue, packet);
this->update_timestamp(this, FALSE);
return SUCCESS;
@@ -888,7 +888,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
if (message_id != this->message_id_in)
{
this->logger->log(this->logger, ERROR | LEVEL1,
- "Message request with message id %d received, but %d expected",
+ "message request with message id %d received, but %d expected",
message_id,this->message_id_in);
return FAILED;
}
@@ -899,7 +899,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
if (message_id != (this->message_id_out - 1))
{
this->logger->log(this->logger, ERROR | LEVEL1,
- "Message reply with message id %d received, but %d expected",
+ "message reply with message id %d received, but %d expected",
message_id,this->message_id_in);
return FAILED;
}
@@ -1003,7 +1003,7 @@ static status_t update_connection_hosts(private_ike_sa_t *this, host_t *me, host
if (other_changes & HOST_DIFF_ADDR)
{
this->logger->log(this->logger, ERROR|LEVEL1,
- "Destination ip changed from %s to %s. As we are NATed this is not allowed!",
+ "destination ip changed from %s to %s. As we are NATed this is not allowed!",
old_other->get_address(old_other), other->get_address(other));
return DESTROY_ME;
}
@@ -1123,7 +1123,7 @@ static status_t delete_child_sa(private_ike_sa_t *this, u_int32_t reqid)
if (this->current_state->get_state(this->current_state) != IKE_SA_ESTABLISHED)
{
this->logger->log(this->logger, ERROR|LEVEL1,
- "Delete of a CHILD_SA whose IKE_SA not in state IKE_SA_ESTABLISHED, aborting");
+ "delete of a CHILD_SA whose IKE_SA not in state IKE_SA_ESTABLISHED, aborting");
return FAILED;
}
@@ -1222,7 +1222,7 @@ static status_t rekey_child_sa(private_ike_sa_t *this, u_int32_t reqid)
if (this->current_state->get_state(this->current_state) != IKE_SA_ESTABLISHED)
{
this->logger->log(this->logger, ERROR|LEVEL1,
- "Rekeying of an CHILD_SA whose IKE_SA not in state IKE_SA_ESTABLISHED, aborting");
+ "rekeying of an CHILD_SA whose IKE_SA not in state IKE_SA_ESTABLISHED, aborting");
return FAILED;
}
@@ -1278,11 +1278,34 @@ static status_t rekey_child_sa(private_ike_sa_t *this, u_int32_t reqid)
}
/**
+ * Implementation of protected_ike_sa_t.establish.
+ */
+static void establish(private_ike_sa_t *this)
+{
+ protected_ike_sa_t *ike_sa = (protected_ike_sa_t *)this;
+
+ connection_t *connection = ike_sa->get_connection(ike_sa);
+ host_t *my_host = connection->get_my_host(connection);
+ host_t *other_host = connection->get_other_host(connection);
+ policy_t *policy = ike_sa->get_policy(ike_sa);
+ identification_t *my_id = policy->get_my_id(policy);
+ identification_t *other_id = policy->get_other_id(policy);
+
+ ike_sa->set_new_state(ike_sa, (state_t*)ike_sa_established_create(ike_sa));
+
+ this->logger->log(this->logger, AUDIT, "IKE_SA established %s[%s]...%s[%s]",
+ my_host->get_address(my_host),
+ my_id->get_string(my_id),
+ other_host->get_address(other_host),
+ other_id->get_string(other_id));
+}
+
+/**
* Implementation of protected_ike_sa_t.reset_message_buffers.
*/
static void reset_message_buffers(private_ike_sa_t *this)
{
- this->logger->log(this->logger, CONTROL|LEVEL2, "Reset message counters and destroy stored messages");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "reset message counters and destroy stored messages");
/* destroy stored requested message */
if (this->last_requested_message != NULL)
{
@@ -1497,14 +1520,14 @@ static void destroy(private_ike_sa_t *this)
{
child_sa_t *child_sa;
- this->logger->log(this->logger, CONTROL|LEVEL2, "Going to destroy IKE SA %llu:%llu, role %s",
+ this->logger->log(this->logger, CONTROL|LEVEL2, "going to destroy IKE SA %llu:%llu, role %s",
this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
this->ike_sa_id->get_responder_spi(this->ike_sa_id),
this->ike_sa_id->is_initiator(this->ike_sa_id) ? "initiator" : "responder");
if (get_state(this) == IKE_SA_ESTABLISHED)
{
- this->logger->log(this->logger, ERROR, "Destroying an established IKE SA without knowledge from remote peer!");
+ this->logger->log(this->logger, ERROR, "destroying an established IKE SA without knowledge from remote peer!");
}
while (this->child_sas->remove_last(this->child_sas, (void**)&child_sa) == SUCCESS)
@@ -1591,66 +1614,67 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
private_ike_sa_t *this = malloc_thing(private_ike_sa_t);
/* Public functions */
- this->protected.public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message;
- this->protected.public.initiate_connection = (status_t(*)(ike_sa_t*,connection_t*)) initiate_connection;
- this->protected.public.delete_child_sa = (status_t(*)(ike_sa_t*,u_int32_t)) delete_child_sa;
- this->protected.public.rekey_child_sa = (status_t(*)(ike_sa_t*,u_int32_t)) rekey_child_sa;
- this->protected.public.get_child_sa = (child_sa_t*(*)(ike_sa_t*,u_int32_t))get_child_sa;
- this->protected.public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id;
- this->protected.public.get_my_host = (host_t*(*)(ike_sa_t*)) get_my_host;
- this->protected.public.get_other_host = (host_t*(*)(ike_sa_t*)) get_other_host;
- this->protected.public.get_my_id = (identification_t*(*)(ike_sa_t*)) get_my_id;
- this->protected.public.get_other_id = (identification_t*(*)(ike_sa_t*)) get_other_id;
- this->protected.public.get_connection = (connection_t*(*)(ike_sa_t*)) get_connection;
- this->protected.public.retransmit_possible = (bool (*) (ike_sa_t *, u_int32_t)) retransmit_possible;
- this->protected.public.retransmit_request = (status_t (*) (ike_sa_t *, u_int32_t)) retransmit_request;
- this->protected.public.get_state = (ike_sa_state_t (*) (ike_sa_t *this)) get_state;
+ this->protected.public.process_message = (status_t (*) (ike_sa_t*,message_t*)) process_message;
+ this->protected.public.initiate_connection = (status_t (*) (ike_sa_t*,connection_t*)) initiate_connection;
+ this->protected.public.delete_child_sa = (status_t (*) (ike_sa_t*,u_int32_t)) delete_child_sa;
+ this->protected.public.rekey_child_sa = (status_t (*) (ike_sa_t*,u_int32_t)) rekey_child_sa;
+ this->protected.public.get_child_sa = (child_sa_t* (*) (ike_sa_t*,u_int32_t))get_child_sa;
+ this->protected.public.get_id = (ike_sa_id_t* (*) (ike_sa_t*)) get_id;
+ this->protected.public.get_my_host = (host_t* (*) (ike_sa_t*)) get_my_host;
+ this->protected.public.get_other_host = (host_t* (*) (ike_sa_t*)) get_other_host;
+ this->protected.public.get_my_id = (identification_t* (*) (ike_sa_t*)) get_my_id;
+ this->protected.public.get_other_id = (identification_t* (*) (ike_sa_t*)) get_other_id;
+ this->protected.public.get_connection = (connection_t* (*) (ike_sa_t*)) get_connection;
+ this->protected.public.retransmit_possible = (bool (*) (ike_sa_t*,u_int32_t)) retransmit_possible;
+ this->protected.public.retransmit_request = (status_t (*) (ike_sa_t*,u_int32_t)) retransmit_request;
+ this->protected.public.get_state = (ike_sa_state_t (*) (ike_sa_t*)) get_state;
this->protected.public.log_status = (void (*) (ike_sa_t*,logger_t*,char*))log_status;
- this->protected.public.delete = (status_t(*)(ike_sa_t*))delete_;
- this->protected.public.destroy = (void(*)(ike_sa_t*))destroy;
- this->protected.public.is_my_host_behind_nat = (bool(*)(ike_sa_t*)) is_my_host_behind_nat;
- this->protected.public.is_other_host_behind_nat = (bool(*)(ike_sa_t*)) is_other_host_behind_nat;
- this->protected.public.is_any_host_behind_nat = (bool(*)(ike_sa_t*)) is_any_host_behind_nat;
- this->protected.public.get_last_traffic_in_tv = (struct timeval (*)(ike_sa_t*)) get_last_traffic_in_tv;
- this->protected.public.get_last_traffic_out_tv = (struct timeval (*)(ike_sa_t*)) get_last_traffic_out_tv;
- this->protected.public.send_dpd_request = (status_t (*)(ike_sa_t*)) send_dpd_request;
+ this->protected.public.delete = (status_t (*) (ike_sa_t*))delete_;
+ this->protected.public.destroy = (void (*) (ike_sa_t*))destroy;
+ this->protected.public.is_my_host_behind_nat = (bool (*) (ike_sa_t*)) is_my_host_behind_nat;
+ this->protected.public.is_other_host_behind_nat = (bool (*) (ike_sa_t*)) is_other_host_behind_nat;
+ this->protected.public.is_any_host_behind_nat = (bool (*) (ike_sa_t*)) is_any_host_behind_nat;
+ this->protected.public.get_last_traffic_in_tv = (struct timeval (*) (ike_sa_t*)) get_last_traffic_in_tv;
+ this->protected.public.get_last_traffic_out_tv = (struct timeval (*) (ike_sa_t*)) get_last_traffic_out_tv;
+ this->protected.public.send_dpd_request = (status_t (*) (ike_sa_t*)) send_dpd_request;
/* protected functions */
- this->protected.build_message = (void (*) (protected_ike_sa_t *, exchange_type_t,bool,message_t**)) build_message;
- 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_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.build_message = (void (*) (protected_ike_sa_t*,exchange_type_t,bool,message_t**)) build_message;
+ 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_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.add_child_sa = (void (*) (protected_ike_sa_t*,child_sa_t*)) add_child_sa;
- this->protected.set_connection = (void (*) (protected_ike_sa_t *,connection_t *)) set_connection;
- this->protected.get_connection = (connection_t *(*) (protected_ike_sa_t *)) get_connection;
- this->protected.set_policy = (void (*) (protected_ike_sa_t *,policy_t *)) set_policy;
- this->protected.get_policy = (policy_t *(*) (protected_ike_sa_t *)) get_policy;
- this->protected.get_randomizer = (randomizer_t *(*) (protected_ike_sa_t *)) get_randomizer;
- 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.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;
- this->protected.get_crypter_responder = (crypter_t *(*) (protected_ike_sa_t *)) get_crypter_responder;
- this->protected.get_signer_responder = (signer_t *(*) (protected_ike_sa_t *)) get_signer_responder;
- this->protected.reset_message_buffers = (void (*) (protected_ike_sa_t *)) reset_message_buffers;
- this->protected.get_last_responded_message = (message_t * (*) (protected_ike_sa_t *)) get_last_responded_message;
- this->protected.get_last_requested_message = (message_t * (*) (protected_ike_sa_t *)) get_last_requested_message;
- this->protected.set_last_replied_message_id = (void (*) (protected_ike_sa_t *,u_int32_t)) set_last_replied_message_id;
- this->protected.destroy_child_sa = (u_int32_t (*)(protected_ike_sa_t*,u_int32_t))destroy_child_sa;
- this->protected.get_child_sa = (child_sa_t* (*)(protected_ike_sa_t*,u_int32_t))get_child_sa_by_spi;
- this->protected.set_my_host_behind_nat = (void(*)(protected_ike_sa_t*, bool)) set_my_host_behind_nat;
- this->protected.set_other_host_behind_nat = (void(*)(protected_ike_sa_t*, bool)) set_other_host_behind_nat;
- this->protected.generate_natd_hash = (chunk_t (*) (protected_ike_sa_t *, u_int64_t, u_int64_t, host_t*)) generate_natd_hash;
+ this->protected.establish = (void (*) (protected_ike_sa_t*)) establish;
+ this->protected.set_connection = (void (*) (protected_ike_sa_t*,connection_t*)) set_connection;
+ this->protected.get_connection = (connection_t* (*) (protected_ike_sa_t*)) get_connection;
+ this->protected.set_policy = (void (*) (protected_ike_sa_t *,policy_t*)) set_policy;
+ this->protected.get_policy = (policy_t* (*) (protected_ike_sa_t*)) get_policy;
+ this->protected.get_randomizer = (randomizer_t* (*) (protected_ike_sa_t*)) get_randomizer;
+ 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.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;
+ this->protected.get_crypter_responder = (crypter_t* (*) (protected_ike_sa_t*)) get_crypter_responder;
+ this->protected.get_signer_responder = (signer_t* (*) (protected_ike_sa_t*)) get_signer_responder;
+ this->protected.reset_message_buffers = (void (*) (protected_ike_sa_t*)) reset_message_buffers;
+ this->protected.get_last_responded_message = (message_t* (*) (protected_ike_sa_t*)) get_last_responded_message;
+ this->protected.get_last_requested_message = (message_t* (*) (protected_ike_sa_t*)) get_last_requested_message;
+ this->protected.set_last_replied_message_id = (void (*) (protected_ike_sa_t*,u_int32_t)) set_last_replied_message_id;
+ this->protected.destroy_child_sa = (u_int32_t (*) (protected_ike_sa_t*,u_int32_t))destroy_child_sa;
+ this->protected.get_child_sa = (child_sa_t* (*) (protected_ike_sa_t*,u_int32_t))get_child_sa_by_spi;
+ this->protected.set_my_host_behind_nat = (void (*) (protected_ike_sa_t*,bool)) set_my_host_behind_nat;
+ this->protected.set_other_host_behind_nat = (void (*) (protected_ike_sa_t*,bool)) set_other_host_behind_nat;
+ this->protected.generate_natd_hash = (chunk_t (*) (protected_ike_sa_t*,u_int64_t, u_int64_t, host_t*)) generate_natd_hash;
this->protected.get_last_dpd_message_id = (u_int32_t (*) (protected_ike_sa_t*)) get_last_dpd_message_id;
- this->protected.update_connection_hosts = (status_t (*) (protected_ike_sa_t *, host_t*, host_t*)) update_connection_hosts;
+ this->protected.update_connection_hosts = (status_t (*) (protected_ike_sa_t*,host_t*,host_t*)) update_connection_hosts;
/* private functions */
this->update_timestamp = (void (*) (private_ike_sa_t*,bool))update_timestamp;
- this->get_last_esp_traffic_tv = (struct timeval (*) (private_ike_sa_t *,bool))get_last_esp_traffic_tv;
+ this->get_last_esp_traffic_tv = (struct timeval (*) (private_ike_sa_t*,bool))get_last_esp_traffic_tv;
/* initialize private fields */
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
@@ -1671,7 +1695,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->prf = NULL;
this->prf_auth_i = NULL;
this->prf_auth_r = NULL;
- this->child_prf = NULL;
+ this->child_prf = NULL;
this->connection = NULL;
this->policy = NULL;
this->nat_hasher = hasher_create(HASH_SHA1);
@@ -1686,12 +1710,12 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
/* at creation time, IKE_SA is in a initiator state */
if (ike_sa_id->is_initiator(ike_sa_id))
{
- this->logger->log(this->logger, CONTROL | LEVEL2, "Create first state_t object of type INITIATOR_INIT");
+ this->logger->log(this->logger, CONTROL | LEVEL2, "create first state_t object of type INITIATOR_INIT");
this->current_state = (state_t *) initiator_init_create(&(this->protected));
}
else
{
- this->logger->log(this->logger, CONTROL | LEVEL2, "Create first state_t object of type RESPONDER_INIT");
+ this->logger->log(this->logger, CONTROL | LEVEL2, "create first state_t object of type RESPONDER_INIT");
this->current_state = (state_t *) responder_init_create(&(this->protected));
}
return &(this->protected.public);
diff --git a/src/charon/sa/ike_sa.h b/src/charon/sa/ike_sa.h
index 719aa94b0..06a5930e4 100644
--- a/src/charon/sa/ike_sa.h
+++ b/src/charon/sa/ike_sa.h
@@ -539,7 +539,14 @@ struct protected_ike_sa_t {
* @return child_sa, or NULL if none found
*/
child_sa_t* (*get_child_sa) (protected_ike_sa_t *this, u_int32_t spi);
-
+
+ /**
+ * @brief establish the IKE SA
+ *
+ * @param this calling object
+ */
+ void (*establish) (protected_ike_sa_t *this);
+
/**
* @brief Get the last responded message.
*
diff --git a/src/charon/sa/states/ike_auth_requested.c b/src/charon/sa/states/ike_auth_requested.c
index e7797d5ea..b2d42fd60 100644
--- a/src/charon/sa/states/ike_auth_requested.c
+++ b/src/charon/sa/states/ike_auth_requested.c
@@ -29,6 +29,7 @@
#include <encoding/payloads/ts_payload.h>
#include <encoding/payloads/sa_payload.h>
#include <encoding/payloads/id_payload.h>
+#include <encoding/payloads/cert_payload.h>
#include <encoding/payloads/auth_payload.h>
#include <encoding/payloads/notify_payload.h>
#include <crypto/signers/signer.h>
@@ -113,6 +114,17 @@ struct private_ike_auth_requested_t {
status_t (*process_idr_payload) (private_ike_auth_requested_t *this, id_payload_t *idr_payload);
/**
+ * Process received CERT payload
+ *
+ * @param this calling object
+ * @param cert_payload payload to process
+ * @return
+ * - DESTROY_ME if IKE_SA should be deleted
+ * - SUCCSS if processed successful
+ */
+ status_t (*process_cert_payload) (private_ike_auth_requested_t *this, cert_payload_t *cert_payload);
+
+ /**
* Process the SA payload (check if selected proposals are valid, setup child sa)
*
* @param this calling object
@@ -176,8 +188,10 @@ struct private_ike_auth_requested_t {
*/
static status_t process_message(private_ike_auth_requested_t *this, message_t *ike_auth_reply)
{
- ts_payload_t *tsi_payload = NULL, *tsr_payload = NULL;
+ ts_payload_t *tsi_payload = NULL;
+ ts_payload_t *tsr_payload = NULL;
id_payload_t *idr_payload = NULL;
+ cert_payload_t *cert_payload = NULL;
auth_payload_t *auth_payload = NULL;
sa_payload_t *sa_payload = NULL;
iterator_t *payloads = NULL;
@@ -193,7 +207,7 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i
if (ike_auth_reply->get_exchange_type(ike_auth_reply) != IKE_AUTH)
{
- this->logger->log(this->logger, ERROR | LEVEL1, "Message of type %s not supported in state ike_auth_requested",
+ this->logger->log(this->logger, ERROR | LEVEL1, "message of type %s not supported in state ike_auth_requested",
mapping_find(exchange_type_m,ike_auth_reply->get_exchange_type(ike_auth_reply)));
return FAILED;
}
@@ -230,33 +244,34 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i
switch (payload->get_type(payload))
{
case AUTHENTICATION:
- {
auth_payload = (auth_payload_t*)payload;
break;
- }
+ case CERTIFICATE:
+ cert_payload = (cert_payload_t*)payload;
+ status = this->process_cert_payload(this, cert_payload);
+ if (status != SUCCESS)
+ {
+ payloads->destroy(payloads);
+ return status;
+
+ }
+ break;
case ID_RESPONDER:
- {
idr_payload = (id_payload_t*)payload;
break;
- }
case SECURITY_ASSOCIATION:
- {
sa_payload = (sa_payload_t*)payload;
break;
- }
case TRAFFIC_SELECTOR_INITIATOR:
- {
tsi_payload = (ts_payload_t*)payload;
break;
- }
case TRAFFIC_SELECTOR_RESPONDER:
- {
tsr_payload = (ts_payload_t*)payload;
break;
- }
case NOTIFY:
{
notify_payload_t *notify_payload = (notify_payload_t *) payload;
+
/* handle the notify directly, abort if no further processing required */
status = this->process_notify_payload(this, notify_payload);
if (status != SUCCESS)
@@ -265,16 +280,10 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i
return status;
}
}
- case CERTIFICATE:
- {
- /* TODO handle cert payloads */
- }
default:
- {
- this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring Payload %s (%d)",
+ this->logger->log(this->logger, ERROR|LEVEL1, "ignoring Payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
break;
- }
}
}
/* iterator can be destroyed */
@@ -291,51 +300,43 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i
ike_auth_reply->get_destination(ike_auth_reply),
ike_auth_reply->get_source(ike_auth_reply));
if (status != SUCCESS)
- {
return status;
- }
/* process all payloads */
status = this->process_idr_payload(this, idr_payload);
if (status != SUCCESS)
- {
return status;
- }
+
status = this->process_auth_payload(this, auth_payload,idr_payload);
if (status != SUCCESS)
- {
return status;
- }
+
status = this->process_sa_payload(this, sa_payload);
if (status != SUCCESS)
- {
return status;
- }
+
status = this->process_ts_payload(this, TRUE, tsi_payload);
if (status != SUCCESS)
- {
return status;
- }
+
status = this->process_ts_payload(this, FALSE, tsr_payload);
if (status != SUCCESS)
- {
return status;
- }
/* install child SAs for AH and esp */
if (!this->child_sa)
{
- this->logger->log(this->logger, CONTROL, "No CHILD_SA requested, no CHILD_SA built");
+ this->logger->log(this->logger, CONTROL, "no CHILD_SA requested, no CHILD_SA built");
}
else if (!this->proposal)
{
- this->logger->log(this->logger, CONTROL, "Proposal negotiation failed, no CHILD_SA built");
+ this->logger->log(this->logger, CONTROL, "proposal negotiation failed, no CHILD_SA built");
this->child_sa->destroy(this->child_sa);
this->child_sa = NULL;
}
else if (this->my_ts->get_count(this->my_ts) == 0 || this->other_ts->get_count(this->other_ts) == 0)
{
- this->logger->log(this->logger, CONTROL, "Traffic selector negotiation failed, no CHILD_SA built");
+ this->logger->log(this->logger, CONTROL, "traffic selector negotiation failed, no CHILD_SA built");
this->child_sa->destroy(this->child_sa);
this->child_sa = NULL;
}
@@ -351,13 +352,13 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i
prf_plus->destroy(prf_plus);
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "could not install CHILD_SA! Deleting IKE_SA");
return DESTROY_ME;
}
status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts);
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA policy! Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "could not install CHILD_SA policy! Deleting IKE_SA");
return DESTROY_ME;
}
this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
@@ -366,19 +367,8 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i
this->ike_sa->set_last_replied_message_id(this->ike_sa,ike_auth_reply->get_message_id(ike_auth_reply));
/* create new state */
- this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa));
+ this->ike_sa->establish(this->ike_sa);
this->destroy_after_state_change(this);
-
- connection = this->ike_sa->get_connection(this->ike_sa);
- my_host = connection->get_my_host(connection);
- other_host = connection->get_other_host(connection);
- policy = this->ike_sa->get_policy(this->ike_sa);
- my_id = policy->get_my_id(policy);
- other_id = policy->get_other_id(policy);
- this->logger->log(this->logger, AUDIT, "IKE_SA established %s[%s]...%s[%s]",
- my_host->get_address(my_host), my_id->get_string(my_id),
- other_host->get_address(other_host), other_id->get_string(other_id));
-
return SUCCESS;
}
@@ -408,6 +398,38 @@ static status_t process_idr_payload(private_ike_auth_requested_t *this, id_paylo
}
/**
+ * Implements private_ike_auth_requested_t.process_cert_payload
+ */
+static status_t process_cert_payload(private_ike_auth_requested_t *this, cert_payload_t * cert_payload)
+{
+ bool found;
+ x509_t *cert;
+
+ if (cert_payload->get_cert_encoding(cert_payload) != CERT_X509_SIGNATURE)
+ {
+ this->logger->log(this->logger, CONTROL, "certificate encoding is %s, ignored",
+ enum_name(&cert_encoding_names, cert_payload->get_cert_encoding(cert_payload)));
+ return SUCCESS;
+ }
+ cert = x509_create_from_chunk(cert_payload->get_data_clone(cert_payload));
+
+ if (charon->credentials->verify(charon->credentials, cert, &found))
+ {
+ this->logger->log(this->logger, CONTROL, "end entity certificate is trusted");
+ if (!found)
+ {
+ cert = charon->credentials->add_end_certificate(charon->credentials, cert);
+ }
+ }
+ else
+ {
+ this->logger->log(this->logger, ERROR, "end entity certificate is not trusted");
+ }
+ return SUCCESS;
+}
+
+
+/**
* Implements private_ike_auth_requested_t.process_sa_payload
*/
static status_t process_sa_payload(private_ike_auth_requested_t *this, sa_payload_t *sa_payload)
@@ -472,7 +494,7 @@ static status_t process_auth_payload(private_ike_auth_requested_t *this, auth_pa
authenticator->destroy(authenticator);
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Verification of IKE_AUTH reply failed. Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "verification of IKE_AUTH reply failed. Deleting IKE_SA");
return DESTROY_ME;
}
@@ -524,7 +546,7 @@ static status_t process_notify_payload(private_ike_auth_requested_t *this, notif
{
notify_message_type_t notify_message_type = notify_payload->get_notify_message_type(notify_payload);
- this->logger->log(this->logger, CONTROL|LEVEL1, "Process notify type %s",
+ this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
mapping_find(notify_message_type_m, notify_message_type));
switch (notify_message_type)
@@ -675,6 +697,7 @@ ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,chunk
/* private functions */
this->process_idr_payload = process_idr_payload;
+ this->process_cert_payload = process_cert_payload;
this->process_sa_payload = process_sa_payload;
this->process_auth_payload = process_auth_payload;
this->process_ts_payload = process_ts_payload;
diff --git a/src/charon/sa/states/ike_sa_established.c b/src/charon/sa/states/ike_sa_established.c
index 800380680..1a29fbba3 100644
--- a/src/charon/sa/states/ike_sa_established.c
+++ b/src/charon/sa/states/ike_sa_established.c
@@ -123,7 +123,7 @@ static status_t build_sa_payload(private_ike_sa_established_t *this, sa_payload_
/* get proposals from request, and select one with ours */
policy = this->ike_sa->get_policy(this->ike_sa);
proposal_list = request->get_proposals(request);
- this->logger->log(this->logger, CONTROL|LEVEL1, "Selecting proposals:");
+ this->logger->log(this->logger, CONTROL|LEVEL1, "selecting proposals:");
proposal = policy->select_proposal(policy, proposal_list);
/* list is not needed anymore */
while (proposal_list->remove_last(proposal_list, (void**)&proposal_tmp) == SUCCESS)
@@ -148,7 +148,7 @@ static status_t build_sa_payload(private_ike_sa_established_t *this, sa_payload_
memcpy(seed.ptr, this->nonce_i.ptr, this->nonce_i.len);
memcpy(seed.ptr + this->nonce_i.len, this->nonce_r.ptr, this->nonce_r.len);
prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
- this->logger->log_chunk(this->logger, RAW|LEVEL2, "Rekey seed", seed);
+ this->logger->log_chunk(this->logger, RAW|LEVEL2, "sekey seed", seed);
chunk_free(&seed);
chunk_free(&this->nonce_i);
chunk_free(&this->nonce_r);
@@ -171,7 +171,7 @@ static status_t build_sa_payload(private_ike_sa_established_t *this, sa_payload_
prf_plus->destroy(prf_plus);
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA!");
+ this->logger->log(this->logger, AUDIT, "sould not install CHILD_SA!");
sa_response->destroy(sa_response);
proposal->destroy(proposal);
return DESTROY_ME;
@@ -322,7 +322,7 @@ static status_t process_create_child_sa(private_ike_sa_established_t *this, mess
}
default:
{
- this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring payload %s (%d)",
+ this->logger->log(this->logger, ERROR|LEVEL1, "sgnoring payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
break;
}
@@ -342,11 +342,11 @@ static status_t process_create_child_sa(private_ike_sa_established_t *this, mess
{
u_int32_t spi = notify->get_spi(notify);
this->old_child_sa = this->ike_sa->get_child_sa(this->ike_sa, spi);
- this->logger->log(this->logger, CONTROL, "Rekeying CHILD_SA with SPI 0x%x", spi);
+ this->logger->log(this->logger, CONTROL, "sekeying CHILD_SA with SPI 0x%x", spi);
}
else
{
- this->logger->log(this->logger, CONTROL, "Create new CHILD_SA");
+ this->logger->log(this->logger, CONTROL, "create new CHILD_SA");
}
/* build response */
@@ -382,7 +382,7 @@ static status_t process_create_child_sa(private_ike_sa_established_t *this, mess
/* message can now be sent (must not be destroyed) */
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Unable to send CREATE_CHILD_SA reply. Ignored");
+ this->logger->log(this->logger, AUDIT, "unable to send CREATE_CHILD_SA reply. Ignored");
response->destroy(response);
return FAILED;
}
@@ -390,11 +390,11 @@ static status_t process_create_child_sa(private_ike_sa_established_t *this, mess
/* install child SA policies */
if (!this->child_sa)
{
- this->logger->log(this->logger, ERROR, "Proposal negotiation failed, no CHILD_SA built");
+ this->logger->log(this->logger, ERROR, "proposal negotiation failed, no CHILD_SA built");
}
else if (this->my_ts->get_count(this->my_ts) == 0 || this->other_ts->get_count(this->other_ts) == 0)
{
- this->logger->log(this->logger, ERROR, "Traffic selector negotiation failed, no CHILD_SA built");
+ this->logger->log(this->logger, ERROR, "traffic selector negotiation failed, no CHILD_SA built");
this->child_sa->destroy(this->child_sa);
this->child_sa = NULL;
}
@@ -403,7 +403,7 @@ static status_t process_create_child_sa(private_ike_sa_established_t *this, mess
status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts);
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA policy!");
+ this->logger->log(this->logger, AUDIT, "could not install CHILD_SA policy!");
}
if (this->old_child_sa)
{ /* mark old child sa as rekeyed */
@@ -443,7 +443,7 @@ static status_t process_informational(private_ike_sa_established_t *this, messag
}
default:
{
- this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring Payload %s (%d)",
+ this->logger->log(this->logger, ERROR|LEVEL1, "ignoring Payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
break;
@@ -489,7 +489,7 @@ static status_t process_informational(private_ike_sa_established_t *this, messag
if (this->ike_sa->send_response(this->ike_sa, response) != SUCCESS)
{
/* something is seriously wrong, kill connection */
- this->logger->log(this->logger, AUDIT, "Unable to send reply. Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "unable to send reply. Deleting IKE_SA");
response->destroy(response);
return DESTROY_ME;
}
@@ -529,7 +529,7 @@ static status_t process_informational_response(private_ike_sa_established_t *thi
{
default:
{
- this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring Payload %s (%d)",
+ this->logger->log(this->logger, ERROR|LEVEL1, "ignoring Payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload));
break;
@@ -619,7 +619,7 @@ static status_t process_message(private_ike_sa_established_t *this, message_t *m
break;
default:
this->logger->log(this->logger, ERROR | LEVEL1,
- "Message of type %s not supported in state ike_sa_established",
+ "message of type %s not supported in state ike_sa_established",
mapping_find(exchange_type_m, message->get_exchange_type(message)));
status = NOT_SUPPORTED;
}
diff --git a/src/charon/sa/states/ike_sa_init_requested.c b/src/charon/sa/states/ike_sa_init_requested.c
index 1383ac4c6..1278fdb76 100644
--- a/src/charon/sa/states/ike_sa_init_requested.c
+++ b/src/charon/sa/states/ike_sa_init_requested.c
@@ -29,6 +29,8 @@
#include <encoding/payloads/nonce_payload.h>
#include <encoding/payloads/notify_payload.h>
#include <encoding/payloads/id_payload.h>
+#include <encoding/payloads/cert_payload.h>
+#include <encoding/payloads/certreq_payload.h>
#include <encoding/payloads/auth_payload.h>
#include <encoding/payloads/ts_payload.h>
#include <crypto/diffie_hellman.h>
@@ -158,12 +160,34 @@ struct private_ike_sa_init_requested_t {
*
* @param this calling object
* @param[out] id_payload buildet ID payload
- * @param response created payload will be added to this message_t object
+ * @param msg created payload will be added to this message_t object
* @return
* - SUCCESS
* - FAILED
*/
- status_t (*build_id_payload) (private_ike_sa_init_requested_t *this,id_payload_t **id_payload, message_t *response);
+ status_t (*build_id_payload) (private_ike_sa_init_requested_t *this,id_payload_t **id_payload, message_t *msg);
+
+ /**
+ * Build CERT payload for IKE_AUTH request.
+ *
+ * @param this calling object
+ * @param msg created payload will be added to this message_t object
+ * @return
+ * - SUCCESS
+ * - FAILED
+ */
+ status_t (*build_cert_payload) (private_ike_sa_init_requested_t *this, message_t *msg);
+
+ /**
+ * Build CERTREQ payload for IKE_AUTH request.
+ *
+ * @param this calling object
+ * @param msg created payload will be added to this message_t object
+ * @return
+ * - SUCCESS
+ * - FAILED
+ */
+ status_t (*build_certreq_payload) (private_ike_sa_init_requested_t *this, message_t *msg);
/**
* Build IDr payload for IKE_AUTH request.
@@ -171,57 +195,57 @@ struct private_ike_sa_init_requested_t {
* Only built when the ID of the responder contains no wildcards.
*
* @param this calling object
- * @param response created payload will be added to this message_t object
+ * @param msg created payload will be added to this message_t object
* @return
* - SUCCESS
* - FAILED
*/
- status_t (*build_idr_payload) (private_ike_sa_init_requested_t *this, message_t *response);
+ status_t (*build_idr_payload) (private_ike_sa_init_requested_t *this, message_t *msg);
/**
* Build AUTH payload for IKE_AUTH request.
*
* @param this calling object
* @param my_id_payload buildet ID payload
- * @param response created payload will be added to this message_t object
+ * @param msg created payload will be added to this message_t object
* @return
* - SUCCESS
* - FAILED
*/
- status_t (*build_auth_payload) (private_ike_sa_init_requested_t *this,id_payload_t *my_id_payload, message_t *response);
+ status_t (*build_auth_payload) (private_ike_sa_init_requested_t *this,id_payload_t *my_id_payload, message_t *msg);
/**
* Build SA payload for IKE_AUTH request.
*
* @param this calling object
- * @param response created payload will be added to this message_t object
+ * @param msg created payload will be added to this message_t object
* @return
* - SUCCESS
* - FAILED
*/
- status_t (*build_sa_payload) (private_ike_sa_init_requested_t *this, message_t *response);
+ status_t (*build_sa_payload) (private_ike_sa_init_requested_t *this, message_t *msg);
/**
* Build TSi payload for IKE_AUTH request.
*
* @param this calling object
- * @param response created payload will be added to this message_t object
+ * @param msg created payload will be added to this message_t object
* @return
* - SUCCESS
* - FAILED
*/
- status_t (*build_tsi_payload) (private_ike_sa_init_requested_t *this, message_t *response);
+ status_t (*build_tsi_payload) (private_ike_sa_init_requested_t *this, message_t *msg);
/**
* Build TSr payload for IKE_AUTH request.
*
* @param this calling object
- * @param response created payload will be added to this message_t object
+ * @param msg created payload will be added to this message_t object
* @return
* - SUCCESS
* - FAILED
*/
- status_t (*build_tsr_payload) (private_ike_sa_init_requested_t *this, message_t *response);
+ status_t (*build_tsr_payload) (private_ike_sa_init_requested_t *this, message_t *msg);
/**
* Process a notify payload and react.
@@ -273,7 +297,7 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
if (ike_sa_init_reply->get_exchange_type(ike_sa_init_reply) != IKE_SA_INIT)
{
- this->logger->log(this->logger, ERROR | LEVEL1, "Message of type %s not supported in state ike_sa_init_requested",
+ this->logger->log(this->logger, ERROR | LEVEL1, "message of type %s not supported in state ike_sa_init_requested",
mapping_find(exchange_type_m,ike_sa_init_reply->get_exchange_type(ike_sa_init_reply)));
return FAILED;
}
@@ -335,20 +359,14 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
switch (payload->get_type(payload))
{
case SECURITY_ASSOCIATION:
- {
sa_payload = (sa_payload_t*)payload;
break;
- }
case KEY_EXCHANGE:
- {
ke_payload = (ke_payload_t*)payload;
break;
- }
case NONCE:
- {
nonce_payload = (nonce_payload_t*)payload;
break;
- }
case NOTIFY:
{
notify_payload_t *notify_payload = (notify_payload_t *) payload;
@@ -362,12 +380,9 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
break;
}
default:
- {
- this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring payload %s (%d)",
+ this->logger->log(this->logger, ERROR|LEVEL1, "ignoring payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
break;
- }
-
}
}
@@ -381,27 +396,21 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
status = this->process_nonce_payload (this,nonce_payload);
if (status != SUCCESS)
- {
return status;
- }
status = this->process_sa_payload (this,sa_payload);
if (status != SUCCESS)
- {
return status;
- }
status = this->process_ke_payload (this,ke_payload);
if (status != SUCCESS)
- {
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");
+ this->logger->log(this->logger, AUDIT, "transform objects could not be created from selected proposal. Deleting IKE_SA");
return DESTROY_ME;
}
@@ -414,16 +423,16 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
}
if (this->natd_seen_r > 1)
{
- this->logger->log(this->logger, AUDIT, "Warning: IKE_SA_INIT request contained multiple Notify(NAT_DETECTION_DESTINATION_IP) payloads.");
+ this->logger->log(this->logger, AUDIT, "warning: IKE_SA_INIT request contained multiple Notify(NAT_DETECTION_DESTINATION_IP) payloads.");
}
if (this->natd_seen_i > 0 && !this->natd_hash_i_matched)
{
- this->logger->log(this->logger, AUDIT, "Remote host is behind NAT, using NAT-T.");
+ this->logger->log(this->logger, AUDIT, "remote host is behind NAT, using NAT-Traversal");
this->ike_sa->set_other_host_behind_nat(this->ike_sa, TRUE);
}
if (this->natd_seen_r > 0 && !this->natd_hash_r_matched)
{
- this->logger->log(this->logger, AUDIT, "Local host is behind NAT, using NAT-T.");
+ this->logger->log(this->logger, AUDIT, "local host is behind NAT, using NAT-Traversal");
this->ike_sa->set_my_host_behind_nat(this->ike_sa, TRUE);
}
@@ -438,11 +447,11 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
{
me->set_port(me, IKEV2_NATT_PORT);
other->set_port(other, IKEV2_NATT_PORT);
- this->logger->log(this->logger, AUDIT, "Switching to port %d.", IKEV2_NATT_PORT);
+ this->logger->log(this->logger, AUDIT, "switching to port %d.", IKEV2_NATT_PORT);
}
else
{
- this->logger->log(this->logger, AUDIT, "No NAT detected, not using NAT-T.");
+ this->logger->log(this->logger, AUDIT, "no NAT detected, not using NAT-Traversal");
}
if (this->ike_sa->public.is_my_host_behind_nat(&this->ike_sa->public))
@@ -454,9 +463,7 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
status = this->ike_sa->update_connection_hosts(this->ike_sa, me, other);
if (status != SUCCESS)
- {
return status;
- }
policy = this->ike_sa->get_policy(this->ike_sa);
policy->update_my_ts(policy, me);
@@ -467,46 +474,41 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
status = this->build_id_payload(this, &id_payload, request);
if (status != SUCCESS)
- {
- request->destroy(request);
- return status;
- }
+ goto destroy_request;
+
+ status = this->build_cert_payload(this, request);
+ if (status != SUCCESS)
+ goto destroy_request;
+
+ status = this->build_certreq_payload(this, request);
+ if (status != SUCCESS)
+ goto destroy_request;
+
status = this->build_idr_payload(this, request);
if (status != SUCCESS)
- {
- request->destroy(request);
- return status;
- }
+ goto destroy_request;
+
status = this->build_auth_payload(this, (id_payload_t*)id_payload, request);
if (status != SUCCESS)
- {
- request->destroy(request);
- return status;
- }
+ goto destroy_request;
+
status = this->build_sa_payload(this, request);
if (status != SUCCESS)
- {
- request->destroy(request);
- return status;
- }
+ goto destroy_request;
+
status = this->build_tsi_payload(this, request);
if (status != SUCCESS)
- {
- request->destroy(request);
- return status;
- }
+ goto destroy_request;
+
status = this->build_tsr_payload(this, request);
if (status != SUCCESS)
- {
- request->destroy(request);
- return status;
- }
+ goto destroy_request;
/* message can now be sent (must not be destroyed) */
status = this->ike_sa->send_request(this->ike_sa, request);
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Unable to send IKE_AUTH request. Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "unable to send IKE_AUTH request. Deleting IKE_SA");
request->destroy(request);
return DESTROY_ME;
}
@@ -522,6 +524,11 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
this->destroy_after_state_change(this);
return SUCCESS;
+
+destroy_request:
+ request->destroy(request);
+ return status;
+
}
@@ -590,18 +597,18 @@ status_t process_ke_payload (private_ike_sa_init_requested_t *this, ke_payload_t
/**
* Implementation of private_ike_sa_init_requested_t.build_id_payload.
*/
-static status_t build_id_payload (private_ike_sa_init_requested_t *this,id_payload_t **id_payload, message_t *request)
+static status_t build_id_payload (private_ike_sa_init_requested_t *this,id_payload_t **id_payload, message_t *msg)
{
policy_t *policy;
+ identification_t *my_id;
id_payload_t *new_id_payload;
- identification_t *identification;
policy = this->ike_sa->get_policy(this->ike_sa);
- identification = policy->get_my_id(policy);
- new_id_payload = id_payload_create_from_identification(TRUE, identification);
+ my_id = policy->get_my_id(policy);
+ new_id_payload = id_payload_create_from_identification(TRUE, my_id);
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add ID payload to message");
- request->add_payload(request,(payload_t *) new_id_payload);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add ID payload to message");
+ msg->add_payload(msg, (payload_t *) new_id_payload);
*id_payload = new_id_payload;
@@ -609,22 +616,64 @@ static status_t build_id_payload (private_ike_sa_init_requested_t *this,id_paylo
}
/**
+ * Implementation of private_ike_sa_init_requested_t.build_cert_payload.
+ */
+static status_t build_cert_payload (private_ike_sa_init_requested_t *this, message_t *msg)
+{
+ connection_t *connection = this->ike_sa->get_connection(this->ike_sa);
+
+ if (connection->get_cert_policy(connection) != CERT_NEVER_SEND)
+ {
+ policy_t *policy;
+ identification_t *my_id;
+ x509_t *cert;
+ cert_payload_t *cert_payload;
+
+ policy = this->ike_sa->get_policy(this->ike_sa);
+ my_id = policy->get_my_id(policy);
+
+ cert = charon->credentials->get_certificate(charon->credentials, my_id);
+ if (cert == NULL)
+ {
+ this->logger->log(this->logger, ERROR, "could not find my certificate");
+ return NOT_FOUND;
+ }
+ cert_payload = cert_payload_create_from_x509(cert);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add CERT payload to message");
+ msg->add_payload(msg, (payload_t *) cert_payload);
+ }
+ return SUCCESS;
+}
+
+/**
+ * Implementation of private_ike_sa_init_requested_t.build_certreq_payload.
+ */
+static status_t build_certreq_payload (private_ike_sa_init_requested_t *this, message_t *msg)
+{
+ if (FALSE)
+ {
+ certreq_payload_t *certreq_payload;
+
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add CERTREQ payload to message");
+ msg->add_payload(msg, (payload_t *) certreq_payload);
+ }
+ return SUCCESS;
+}
+
+/**
* Implementation of private_ike_sa_init_requested_t.build_idr_payload.
*/
-static status_t build_idr_payload (private_ike_sa_init_requested_t *this, message_t *request)
+static status_t build_idr_payload (private_ike_sa_init_requested_t *this, message_t *msg)
{
- policy_t *policy;
- id_payload_t *idr_payload;
- identification_t *identification;
-
- policy = this->ike_sa->get_policy(this->ike_sa);
- identification = policy->get_other_id(policy);
+ policy_t *policy = this->ike_sa->get_policy(this->ike_sa);
+ identification_t *identification = policy->get_other_id(policy);
+
if (!identification->contains_wildcards(identification))
{
- idr_payload = id_payload_create_from_identification(FALSE, identification);
+ id_payload_t *idr_payload = id_payload_create_from_identification(FALSE, identification);
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add IDr payload to message");
- request->add_payload(request,(payload_t *) idr_payload);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add IDr payload to message");
+ msg->add_payload(msg, (payload_t *) idr_payload);
}
return SUCCESS;
}
@@ -632,7 +681,7 @@ static status_t build_idr_payload (private_ike_sa_init_requested_t *this, messag
/**
* Implementation of private_ike_sa_init_requested_t.build_auth_payload.
*/
-static status_t build_auth_payload (private_ike_sa_init_requested_t *this, id_payload_t *my_id_payload, message_t *request)
+static status_t build_auth_payload (private_ike_sa_init_requested_t *this, id_payload_t *my_id_payload, message_t *msg)
{
authenticator_t *authenticator;
auth_payload_t *auth_payload;
@@ -644,12 +693,12 @@ static status_t build_auth_payload (private_ike_sa_init_requested_t *this, id_pa
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Could not generate AUTH data for IKE_AUTH request. Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "could not generate AUTH data for IKE_AUTH request. Deleting IKE_SA");
return DESTROY_ME;
}
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add AUTH payload to message");
- request->add_payload(request,(payload_t *) auth_payload);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add AUTH payload to message");
+ msg->add_payload(msg, (payload_t *) auth_payload);
return SUCCESS;
}
@@ -657,7 +706,7 @@ static status_t build_auth_payload (private_ike_sa_init_requested_t *this, id_pa
/**
* Implementation of private_ike_sa_init_requested_t.build_sa_payload.
*/
-static status_t build_sa_payload (private_ike_sa_init_requested_t *this, message_t *request)
+static status_t build_sa_payload (private_ike_sa_init_requested_t *this, message_t *msg)
{
linked_list_t *proposal_list;
sa_payload_t *sa_payload;
@@ -677,14 +726,14 @@ static status_t build_sa_payload (private_ike_sa_init_requested_t *this, message
this->ike_sa->public.is_any_host_behind_nat(&this->ike_sa->public));
if (this->child_sa->alloc(this->child_sa, proposal_list) != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "could not install CHILD_SA! Deleting IKE_SA");
return DESTROY_ME;
}
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);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add SA payload to message");
+ msg->add_payload(msg, (payload_t *) sa_payload);
return SUCCESS;
}
@@ -692,18 +741,14 @@ static status_t build_sa_payload (private_ike_sa_init_requested_t *this, message
/**
* Implementation of private_ike_sa_init_requested_t.build_tsi_payload.
*/
-static status_t build_tsi_payload (private_ike_sa_init_requested_t *this, message_t *request)
+static status_t build_tsi_payload (private_ike_sa_init_requested_t *this, message_t *msg)
{
- linked_list_t *ts_list;
- ts_payload_t *ts_payload;
- policy_t *policy;
-
- policy = this->ike_sa->get_policy(this->ike_sa);
- ts_list = policy->get_my_traffic_selectors(policy);
- ts_payload = ts_payload_create_from_traffic_selectors(TRUE, ts_list);
+ policy_t *policy = this->ike_sa->get_policy(this->ike_sa);
+ linked_list_t *ts_list = policy->get_my_traffic_selectors(policy);
+ ts_payload_t *ts_payload = ts_payload_create_from_traffic_selectors(TRUE, ts_list);
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add TSi payload to message");
- request->add_payload(request,(payload_t *) ts_payload);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add TSi payload to message");
+ msg->add_payload(msg, (payload_t *) ts_payload);
return SUCCESS;
}
@@ -711,18 +756,14 @@ static status_t build_tsi_payload (private_ike_sa_init_requested_t *this, messag
/**
* Implementation of private_ike_sa_init_requested_t.build_tsr_payload.
*/
-static status_t build_tsr_payload (private_ike_sa_init_requested_t *this, message_t *request)
+static status_t build_tsr_payload (private_ike_sa_init_requested_t *this, message_t *msg)
{
- linked_list_t *ts_list;
- ts_payload_t *ts_payload;
- policy_t *policy;
-
- policy = this->ike_sa->get_policy(this->ike_sa);
- ts_list = policy->get_other_traffic_selectors(policy);
- ts_payload = ts_payload_create_from_traffic_selectors(FALSE, ts_list);
+ policy_t *policy = this->ike_sa->get_policy(this->ike_sa);
+ linked_list_t *ts_list = policy->get_other_traffic_selectors(policy);
+ ts_payload_t *ts_payload = ts_payload_create_from_traffic_selectors(FALSE, ts_list);
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add TSr payload to message");
- request->add_payload(request,(payload_t *) ts_payload);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add TSr payload to message");
+ msg->add_payload(msg, (payload_t *) ts_payload);
return SUCCESS;
}
@@ -735,7 +776,7 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no
chunk_t notification_data;
notify_message_type_t notify_message_type = notify_payload->get_notify_message_type(notify_payload);
- this->logger->log(this->logger, CONTROL|LEVEL1, "Process notify type %s",
+ this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
mapping_find(notify_message_type_m, notify_message_type));
switch (notify_message_type)
@@ -768,20 +809,20 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no
* is cancelled...
*/
- this->logger->log(this->logger, AUDIT, "Peer didn't accept %s, it requested %s!",
+ this->logger->log(this->logger, AUDIT, "peer didn't accept %s, it requested %s!",
mapping_find(diffie_hellman_group_m, old_dh_group),
mapping_find(diffie_hellman_group_m, dh_group));
/* check if we can accept this dh group */
if (!connection->check_dh_group(connection, dh_group))
{
this->logger->log(this->logger, AUDIT,
- "Peer does only accept DH group %s, which we do not accept! Aborting",
+ "peer does only accept DH group %s, which we do not accept! Aborting",
mapping_find(diffie_hellman_group_m, dh_group));
return DESTROY_ME;
}
/* Going to change state back to initiator_init_t */
- this->logger->log(this->logger, CONTROL|LEVEL2, "Create next state object");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "create next state object");
initiator_init_state = initiator_init_create(this->ike_sa);
/* buffer of sent and received messages has to get reseted */
@@ -791,8 +832,8 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no
this->ike_sa->set_new_state(this->ike_sa,(state_t *) initiator_init_state);
/* state has NOW changed :-) */
- this->logger->log(this->logger, CONTROL|LEVEL2, "Destroy old sate object");
- this->logger->log(this->logger, CONTROL|LEVEL2, "Going to retry initialization of connection");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "destroy old sate object");
+ this->logger->log(this->logger, CONTROL|LEVEL2, "going to retry initialization of connection");
this->public.state_interface.destroy(&(this->public.state_interface));
if (initiator_init_state->retry_initiate_connection (initiator_init_state, dh_group) != SUCCESS)
@@ -925,6 +966,8 @@ ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa
this->build_tsr_payload = build_tsr_payload;
this->build_id_payload = build_id_payload;
this->build_idr_payload = build_idr_payload;
+ this->build_cert_payload = build_cert_payload;
+ this->build_certreq_payload = build_certreq_payload;
this->build_sa_payload = build_sa_payload;
this->process_notify_payload = process_notify_payload;
diff --git a/src/charon/sa/states/ike_sa_init_responded.c b/src/charon/sa/states/ike_sa_init_responded.c
index d8f380552..860a53f7b 100644
--- a/src/charon/sa/states/ike_sa_init_responded.c
+++ b/src/charon/sa/states/ike_sa_init_responded.c
@@ -31,6 +31,7 @@
#include <encoding/payloads/ts_payload.h>
#include <encoding/payloads/sa_payload.h>
#include <encoding/payloads/id_payload.h>
+#include <encoding/payloads/cert_payload.h>
#include <encoding/payloads/auth_payload.h>
#include <encoding/payloads/notify_payload.h>
#include <crypto/signers/signer.h>
@@ -108,23 +109,22 @@ struct private_ike_sa_init_responded_t {
* @param this calling object
* @param request_idi ID payload representing initiator
* @param request_idr ID payload representing responder (May be zero)
- * @param response The created IDr payload is added to this message_t object
+ * @param msg The created IDr payload is added to this message_t object
* @param response_idr The created IDr payload is also written to this location
*/
status_t (*build_idr_payload) (private_ike_sa_init_responded_t *this,
id_payload_t *request_idi,
id_payload_t *request_idr,
- message_t *response,
+ message_t *msg,
id_payload_t **response_idr);
/**
- * Process received SA payload and build SA payload for IKE_AUTH response.
+ * Build CERT payload for IKE_AUTH response.
*
* @param this calling object
- * @param request SA payload received in IKE_AUTH request
- * @param response The created SA payload is added to this message_t object
+ * @param msg The created CERT payload is added to this message_t object
*/
- status_t (*build_sa_payload) (private_ike_sa_init_responded_t *this, sa_payload_t *request, message_t *response);
+ status_t (*build_cert_payload) (private_ike_sa_init_responded_t *this, message_t *msg);
/**
* Process received AUTH payload and build AUTH payload for IKE_AUTH response.
@@ -133,19 +133,39 @@ struct private_ike_sa_init_responded_t {
* @param request AUTH payload received in IKE_AUTH request
* @param other_id_payload other ID payload needed to verify AUTH data
* @param my_id_payload my ID payload needed to compute AUTH data
- * @param response The created AUTH payload is added to this message_t object
+ * @param msg The created AUTH payload is added to this message_t object
*/
- status_t (*build_auth_payload) (private_ike_sa_init_responded_t *this, auth_payload_t *request,id_payload_t *other_id_payload,id_payload_t *my_id_payload, message_t* response);
+ status_t (*build_auth_payload) (private_ike_sa_init_responded_t *this, auth_payload_t *request,id_payload_t *other_id_payload,id_payload_t *my_id_payload, message_t* msg);
/**
+ * Process received SA payload and build SA payload for IKE_AUTH response.
+ *
+ * @param this calling object
+ * @param request SA payload received in IKE_AUTH request
+ * @param msg The created SA payload is added to this message_t object
+ */
+ status_t (*build_sa_payload) (private_ike_sa_init_responded_t *this, sa_payload_t *request, message_t *msg);
+
+ /**
* Process received TS payload and build TS payload for IKE_AUTH response.
*
* @param this calling object
* @param is_initiator type of TS payload. TRUE for TSi, FALSE for TSr
* @param request TS payload received in IKE_AUTH request
- * @param response the created TS payload is added to this message_t object
+ * @param msg the created TS payload is added to this message_t object
*/
- status_t (*build_ts_payload) (private_ike_sa_init_responded_t *this, bool ts_initiator, ts_payload_t *request, message_t *response);
+ status_t (*build_ts_payload) (private_ike_sa_init_responded_t *this, bool ts_initiator, ts_payload_t *request, message_t *msg);
+
+ /**
+ * Process received CERT payload
+ *
+ * @param this calling object
+ * @param cert_payload payload to process
+ * @return
+ * - DESTROY_ME if IKE_SA should be deleted
+ * - SUCCSS if processed successful
+ */
+ status_t (*process_cert_payload) (private_ike_sa_init_responded_t *this, cert_payload_t *cert_payload);
/**
* Sends a IKE_AUTH reply containing a notify payload.
@@ -154,7 +174,7 @@ struct private_ike_sa_init_responded_t {
* @param notify_payload payload to process
* @return
* - DESTROY_ME if IKE_SA should be deleted
- * - SUCCSS if processed successfull
+ * - SUCCSS if processed successful
*/
status_t (*process_notify_payload) (private_ike_sa_init_responded_t *this, notify_payload_t* notify_payload);
@@ -170,14 +190,18 @@ struct private_ike_sa_init_responded_t {
};
/**
- * Implements state_t.get_state
+ * Implements state_t.process_message
*/
static status_t process_message(private_ike_sa_init_responded_t *this, message_t *request)
{
- id_payload_t *idi_request = NULL, *idr_request = NULL,*idr_response;
- ts_payload_t *tsi_request = NULL, *tsr_request = NULL;
+ id_payload_t *idi_request = NULL;
+ id_payload_t *idr_request = NULL;
+ id_payload_t *idr_response;
+ ts_payload_t *tsi_request = NULL;
+ ts_payload_t *tsr_request = NULL;
auth_payload_t *auth_request = NULL;
sa_payload_t *sa_request = NULL;
+ cert_payload_t *cert_request = NULL;
iterator_t *payloads;
message_t *response;
crypter_t *crypter;
@@ -190,7 +214,7 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t
if (request->get_exchange_type(request) != IKE_AUTH)
{
- this->logger->log(this->logger, ERROR | LEVEL1, "Message of type %s not supported in state ike_sa_init_responded",
+ this->logger->log(this->logger, ERROR | LEVEL1, "message of type %s not supported in state ike_sa_init_respondd",
mapping_find(exchange_type_m,request->get_exchange_type(request)));
return FAILED;
}
@@ -232,35 +256,32 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t
switch (payload->get_type(payload))
{
case ID_INITIATOR:
- {
idi_request = (id_payload_t*)payload;
break;
- }
+ case CERTIFICATE:
+ cert_request = (cert_payload_t*)payload;
+ status = this->process_cert_payload(this, cert_request);
+ if (status != SUCCESS)
+ {
+ payloads->destroy(payloads);
+ return status;
+ }
+ break;
case AUTHENTICATION:
- {
auth_request = (auth_payload_t*)payload;
break;
- }
case ID_RESPONDER:
- {
idr_request = (id_payload_t*)payload;
break;
- }
case SECURITY_ASSOCIATION:
- {
sa_request = (sa_payload_t*)payload;
break;
- }
case TRAFFIC_SELECTOR_INITIATOR:
- {
tsi_request = (ts_payload_t*)payload;
break;
- }
case TRAFFIC_SELECTOR_RESPONDER:
- {
tsr_request = (ts_payload_t*)payload;
break;
- }
case NOTIFY:
{
notify_payload_t *notify_payload = (notify_payload_t *) payload;
@@ -271,20 +292,14 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t
return status;
}
}
- case CERTIFICATE:
- {
- /* TODO handle cert payloads */
- }
case CERTIFICATE_REQUEST:
{
/* TODO handle certrequest payloads */
}
default:
- {
- this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring payload %s (%d)",
+ this->logger->log(this->logger, ERROR|LEVEL1, "ignoring payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
break;
- }
}
}
/* iterator can be destroyed */
@@ -300,9 +315,7 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t
status = this->ike_sa->update_connection_hosts(this->ike_sa,
request->get_destination(request), request->get_source(request));
if (status != SUCCESS)
- {
return status;
- }
/* build response */
this->ike_sa->build_message(this->ike_sa, IKE_AUTH, FALSE, &response);
@@ -310,40 +323,34 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t
/* add payloads to it */
status = this->build_idr_payload(this, idi_request, idr_request, response, &idr_response);
if (status != SUCCESS)
- {
- response->destroy(response);
- return status;
- }
+ goto destroy_response;
+
+ status = this->build_cert_payload(this, response);
+ if (status != SUCCESS)
+ goto destroy_response;
+
status = this->build_auth_payload(this, auth_request,idi_request, idr_response,response);
if (status != SUCCESS)
- {
- response->destroy(response);
- return status;
- }
+ goto destroy_response;
+
status = this->build_sa_payload(this, sa_request, response);
if (status != SUCCESS)
- {
- response->destroy(response);
- return status;
- }
+ goto destroy_response;
+
status = this->build_ts_payload(this, TRUE, tsi_request, response);
if (status != SUCCESS)
- {
- response->destroy(response);
- return status;
- }
+ goto destroy_response;
+
status = this->build_ts_payload(this, FALSE, tsr_request, response);
if (status != SUCCESS)
- {
- response->destroy(response);
- return status;
- }
+ goto destroy_response;
status = this->ike_sa->send_response(this->ike_sa, response);
/* message can now be sent (must not be destroyed) */
+
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Unable to send IKE_AUTH reply. Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "unable to send IKE_AUTH reply. Deleting IKE_SA");
response->destroy(response);
return DESTROY_ME;
}
@@ -351,11 +358,11 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t
/* install child SA policies */
if (!this->child_sa)
{
- this->logger->log(this->logger, CONTROL, "Proposal negotiation failed, no CHILD_SA built");
+ this->logger->log(this->logger, CONTROL, "proposal negotiation failed, no CHILD_SA built");
}
else if (this->my_ts->get_count(this->my_ts) == 0 || this->other_ts->get_count(this->other_ts) == 0)
{
- this->logger->log(this->logger, CONTROL, "Traffic selector negotiation failed, no CHILD_SA built");
+ this->logger->log(this->logger, CONTROL, "traffic selector negotiation failed, no CHILD_SA built");
this->child_sa->destroy(this->child_sa);
this->child_sa = NULL;
}
@@ -364,33 +371,27 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t
status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts);
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA policy! Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "could not install CHILD_SA policy! Deleting IKE_SA");
return DESTROY_ME;
}
this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
}
/* create new state */
- this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa));
+ this->ike_sa->establish(this->ike_sa);
this->destroy_after_state_change(this);
-
- connection = this->ike_sa->get_connection(this->ike_sa);
- my_host = connection->get_my_host(connection);
- other_host = connection->get_other_host(connection);
- policy = this->ike_sa->get_policy(this->ike_sa);
- my_id = policy->get_my_id(policy);
- other_id = policy->get_other_id(policy);
- this->logger->log(this->logger, AUDIT, "IKE_SA established %s[%s]...%s[%s]",
- my_host->get_address(my_host), my_id->get_string(my_id),
- other_host->get_address(other_host), other_id->get_string(other_id));
-
return SUCCESS;
+
+destroy_response:
+ response->destroy(response);
+ return status;
+
}
/**
* Implementation of private_ike_sa_init_responded_t.build_idr_payload.
*/
-static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payload_t *request_idi, id_payload_t *request_idr, message_t *response,id_payload_t **response_idr)
+static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payload_t *request_idi, id_payload_t *request_idr, message_t *msg,id_payload_t **response_idr)
{
identification_t *other_id, *my_id;
id_payload_t *idr_response;
@@ -410,7 +411,7 @@ static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payl
this->policy = charon->policies->get_policy_by_ids(charon->policies, my_id, other_id);
if (this->policy == NULL)
{
- this->logger->log(this->logger, AUDIT, "We don't have a policy for IDs %s - %s. Deleting IKE_SA",
+ this->logger->log(this->logger, AUDIT, "we don't have a policy for IDs %s - %s. Deleting IKE_SA",
my_id->get_string(my_id), other_id->get_string(other_id));
my_id->destroy(my_id);
other_id->destroy(other_id);
@@ -423,24 +424,86 @@ static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payl
my_id = this->policy->get_my_id(this->policy);
/* update others traffic selectors with actually used address */
- this->policy->update_my_ts(this->policy, response->get_source(response));
- this->policy->update_other_ts(this->policy, response->get_destination(response));
+ this->policy->update_my_ts(this->policy, msg->get_source(msg));
+ this->policy->update_other_ts(this->policy, msg->get_destination(msg));
/* set policy in ike_sa for other states */
this->ike_sa->set_policy(this->ike_sa, this->policy);
/* build response */
idr_response = id_payload_create_from_identification(FALSE, my_id);
- response->add_payload(response, (payload_t*)idr_response);
+ msg->add_payload(msg, (payload_t*)idr_response);
*response_idr = idr_response;
return SUCCESS;
}
/**
+ * Implementation of private_ike_sa_init_responded_t.build_cert_payload.
+ */
+static status_t build_cert_payload (private_ike_sa_init_responded_t *this, message_t *msg)
+{
+ connection_t *connection = this->ike_sa->get_connection(this->ike_sa);
+
+ if (connection->get_cert_policy(connection) != CERT_NEVER_SEND)
+ {
+ policy_t *policy;
+ identification_t *my_id;
+ x509_t *cert;
+ cert_payload_t *cert_payload;
+
+ policy = this->ike_sa->get_policy(this->ike_sa);
+ my_id = policy->get_my_id(policy);
+
+ cert = charon->credentials->get_certificate(charon->credentials, my_id);
+ if (cert == NULL)
+ {
+ this->logger->log(this->logger, ERROR, "could not find my certificate");
+ return NOT_FOUND;
+ }
+ cert_payload = cert_payload_create_from_x509(cert);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add CERT payload to message");
+ msg->add_payload(msg, (payload_t *) cert_payload);
+ }
+ return SUCCESS;
+}
+
+/**
+ * Implementation of private_ike_sa_init_responded_t.build_auth_payload.
+ */
+static status_t build_auth_payload(private_ike_sa_init_responded_t *this, auth_payload_t *auth_request,id_payload_t *other_id_payload,id_payload_t *my_id_payload, message_t* msg)
+{
+ authenticator_t *authenticator;
+ auth_payload_t *auth_reply;
+ status_t status;
+
+ authenticator = authenticator_create(this->ike_sa);
+ status = authenticator->verify_auth_data(authenticator,auth_request, this->ike_sa_init_request_data,this->sent_nonce,other_id_payload,TRUE);
+
+ if (status != SUCCESS)
+ {
+ this->logger->log(this->logger, AUDIT, "IKE_AUTH request verification failed. Deleting IKE_SA");
+ this->ike_sa->send_notify(this->ike_sa, IKE_AUTH, AUTHENTICATION_FAILED, CHUNK_INITIALIZER);
+ authenticator->destroy(authenticator);
+ return DESTROY_ME;
+ }
+
+ status = authenticator->compute_auth_data(authenticator,&auth_reply, this->ike_sa_init_response_data,this->received_nonce,my_id_payload,FALSE);
+ authenticator->destroy(authenticator);
+ if (status != SUCCESS)
+ {
+ this->logger->log(this->logger, AUDIT, "unable to build authentication data for IKE_AUTH reply. Deleting IKE_S");
+ return DESTROY_ME;
+ }
+
+ msg->add_payload(msg, (payload_t *)auth_reply);
+ return SUCCESS;
+}
+
+/**
* Implementation of private_ike_sa_init_responded_t.build_sa_payload.
*/
-static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_payload_t *request, message_t *response)
+static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_payload_t *request, message_t *msg)
{
proposal_t *proposal, *proposal_tmp;
linked_list_t *proposal_list;
@@ -457,7 +520,7 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
/* get proposals from request, and select one with ours */
proposal_list = request->get_proposals(request);
- this->logger->log(this->logger, CONTROL|LEVEL1, "Selecting proposals:");
+ this->logger->log(this->logger, CONTROL|LEVEL1, "selecting proposals:");
proposal = this->policy->select_proposal(this->policy, proposal_list);
/* list is not needed anymore */
while (proposal_list->remove_last(proposal_list, (void**)&proposal_tmp) == SUCCESS)
@@ -473,7 +536,7 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
"Adding NO_PROPOSAL_CHOSEN notify");
/* add NO_PROPOSAL_CHOSEN and an empty SA payload */
notify = notify_payload_create_from_protocol_and_type(PROTO_IKE, NO_PROPOSAL_CHOSEN);
- response->add_payload(response, (payload_t*)notify);
+ msg->add_payload(msg, (payload_t*) notify);
}
else
{
@@ -498,7 +561,7 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
prf_plus->destroy(prf_plus);
if (status != SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA");
+ this->logger->log(this->logger, AUDIT, "could not install CHILD_SA! Deleting IKE_SA");
/* TODO: how do we handle this cleanly? */
sa_response->destroy(sa_response);
proposal->destroy(proposal);
@@ -509,46 +572,14 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
sa_response->add_proposal(sa_response, proposal);
proposal->destroy(proposal);
}
- response->add_payload(response, (payload_t*)sa_response);
+ msg->add_payload(msg, (payload_t*)sa_response);
return SUCCESS;
}
/**
- * Implementation of private_ike_sa_init_responded_t.build_auth_payload.
- */
-static status_t build_auth_payload(private_ike_sa_init_responded_t *this, auth_payload_t *auth_request,id_payload_t *other_id_payload,id_payload_t *my_id_payload, message_t* response)
-{
- authenticator_t *authenticator;
- auth_payload_t *auth_reply;
- status_t status;
-
- authenticator = authenticator_create(this->ike_sa);
- status = authenticator->verify_auth_data(authenticator,auth_request, this->ike_sa_init_request_data,this->sent_nonce,other_id_payload,TRUE);
-
- if (status != SUCCESS)
- {
- this->logger->log(this->logger, AUDIT, "IKE_AUTH request verification failed. Deleting IKE_SA");
- this->ike_sa->send_notify(this->ike_sa, IKE_AUTH, AUTHENTICATION_FAILED, CHUNK_INITIALIZER);
- authenticator->destroy(authenticator);
- return DESTROY_ME;
- }
-
- status = authenticator->compute_auth_data(authenticator,&auth_reply, this->ike_sa_init_response_data,this->received_nonce,my_id_payload,FALSE);
- authenticator->destroy(authenticator);
- if (status != SUCCESS)
- {
- this->logger->log(this->logger, AUDIT, "Unable to build authentication data for IKE_AUTH reply. Deleting IKE_SA");
- return DESTROY_ME;
- }
-
- response->add_payload(response, (payload_t *)auth_reply);
- return SUCCESS;
-}
-
-/**
* Implementation of private_ike_sa_init_responded_t.build_ts_payload.
*/
-static status_t build_ts_payload(private_ike_sa_init_responded_t *this, bool ts_initiator, ts_payload_t *request, message_t* response)
+static status_t build_ts_payload(private_ike_sa_init_responded_t *this, bool ts_initiator, ts_payload_t *request, message_t* msg)
{
linked_list_t *ts_received, *ts_selected;
traffic_selector_t *ts;
@@ -570,7 +601,7 @@ static status_t build_ts_payload(private_ike_sa_init_responded_t *this, bool ts_
}
ts_response = ts_payload_create_from_traffic_selectors(ts_initiator, ts_selected);
- response->add_payload(response, (payload_t*)ts_response);
+ msg->add_payload(msg, (payload_t*) ts_response);
/* add notify if traffic selectors do not match */
if (!ts_initiator &&
@@ -582,7 +613,7 @@ static status_t build_ts_payload(private_ike_sa_init_responded_t *this, bool ts_
"Adding TS_UNACCEPTABLE notify");
notify = notify_payload_create_from_protocol_and_type(0, TS_UNACCEPTABLE);
- response->add_payload(response, (payload_t*)notify);
+ msg->add_payload(msg, (payload_t*)notify);
}
/* cleanup */
@@ -595,11 +626,45 @@ static status_t build_ts_payload(private_ike_sa_init_responded_t *this, bool ts_
return status;
}
+/**
+ * Implements private_ike_sa_init_responded_t.process_cert_payload
+ */
+static status_t process_cert_payload(private_ike_sa_init_responded_t *this, cert_payload_t * cert_payload)
+{
+ bool found;
+ x509_t *cert;
+
+ if (cert_payload->get_cert_encoding(cert_payload) != CERT_X509_SIGNATURE)
+ {
+ this->logger->log(this->logger, CONTROL, "certificate encoding is %s, ignored",
+ enum_name(&cert_encoding_names, cert_payload->get_cert_encoding(cert_payload)));
+ return SUCCESS;
+ }
+ cert = x509_create_from_chunk(cert_payload->get_data_clone(cert_payload));
+
+ if (charon->credentials->verify(charon->credentials, cert, &found))
+ {
+ this->logger->log(this->logger, CONTROL, "end entity certificate is trusted");
+ if (!found)
+ {
+ cert = charon->credentials->add_end_certificate(charon->credentials, cert);
+ }
+ }
+ else
+ {
+ this->logger->log(this->logger, ERROR, "end entity certificate is not trusted");
+ }
+ return SUCCESS;
+}
+
+/**
+ * Implements private_ike_sa_init_responded_t.process_notify_payload
+ */
static status_t process_notify_payload(private_ike_sa_init_responded_t *this, notify_payload_t *notify_payload)
{
notify_message_type_t notify_message_type = notify_payload->get_notify_message_type(notify_payload);
- this->logger->log(this->logger, CONTROL|LEVEL1, "Process notify type %s",
+ this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
mapping_find(notify_message_type_m, notify_message_type));
switch (notify_message_type)
@@ -708,9 +773,11 @@ ike_sa_init_responded_t *ike_sa_init_responded_create(protected_ike_sa_t *ike_sa
/* private functions */
this->build_idr_payload = build_idr_payload;
- this->build_sa_payload = build_sa_payload;
+ this->build_cert_payload = build_cert_payload;
this->build_auth_payload = build_auth_payload;
+ this->build_sa_payload = build_sa_payload;
this->build_ts_payload = build_ts_payload;
+ this->process_cert_payload = process_cert_payload;
this->process_notify_payload = process_notify_payload;
this->destroy_after_state_change = destroy_after_state_change;
diff --git a/src/charon/sa/states/initiator_init.c b/src/charon/sa/states/initiator_init.c
index 503bfef5a..aa86b514b 100644
--- a/src/charon/sa/states/initiator_init.c
+++ b/src/charon/sa/states/initiator_init.c
@@ -75,43 +75,43 @@ struct private_initiator_init_t {
* Builds the SA payload for this state.
*
* @param this calling object
- * @param request message_t object to add the SA payload
+ * @param msg message_t object to add the SA payload
*/
- void (*build_sa_payload) (private_initiator_init_t *this, message_t *request);
+ void (*build_sa_payload) (private_initiator_init_t *this, message_t *msg);
/**
* Builds the KE payload for this state.
*
* @param this calling object
- * @param request message_t object to add the KE payload
+ * @param msg message_t object to add the KE payload
*/
- void (*build_ke_payload) (private_initiator_init_t *this, message_t *request);
+ void (*build_ke_payload) (private_initiator_init_t *this, message_t *msg);
/**
* Builds the NONCE payload for this state.
*
* @param this calling object
- * @param request message_t object to add the NONCE payload
+ * @param msg message_t object to add the NONCE payload
*/
- status_t (*build_nonce_payload) (private_initiator_init_t *this,message_t *request);
+ status_t (*build_nonce_payload) (private_initiator_init_t *this,message_t *msg);
/**
* Builds the NAT-T Notify(NAT_DETECTION_SOURCE_IP) and
* Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state.
*
* @param this calling object
- * @param request message_t object to add the Notify payloads
+ * @param msg message_t object to add the Notify payloads
*/
- void (*build_natd_payload) (private_initiator_init_t *this, message_t *request, notify_message_type_t type, host_t *host);
+ void (*build_natd_payload) (private_initiator_init_t *this, message_t *msg, notify_message_type_t type, host_t *host);
/**
* Builds the NAT-T Notify(NAT_DETECTION_SOURCE_IP) and
* Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state.
*
* @param this calling object
- * @param request message_t object to add the Notify payloads
+ * @param msg message_t object to add the Notify payloads
*/
- void (*build_natd_payloads) (private_initiator_init_t *this, message_t *request);
+ void (*build_natd_payloads) (private_initiator_init_t *this, message_t *msg);
/**
* Destroy function called internally of this class after state change to state
@@ -237,7 +237,7 @@ status_t retry_initiate_connection (private_initiator_init_t *this, diffie_hellm
/**
* Implementation of private_initiator_init_t.build_sa_payload.
*/
-static void build_sa_payload(private_initiator_init_t *this, message_t *request)
+static void build_sa_payload(private_initiator_init_t *this, message_t *msg)
{
sa_payload_t* sa_payload;
linked_list_t *proposal_list;
@@ -252,13 +252,13 @@ static void build_sa_payload(private_initiator_init_t *this, message_t *request)
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);
+ msg->add_payload(msg, (payload_t *) sa_payload);
}
/**
* Implementation of private_initiator_init_t.build_ke_payload.
*/
-static void build_ke_payload(private_initiator_init_t *this, message_t *request)
+static void build_ke_payload(private_initiator_init_t *this, message_t *msg)
{
ke_payload_t *ke_payload;
chunk_t key_data;
@@ -276,13 +276,13 @@ static void build_ke_payload(private_initiator_init_t *this, message_t *request)
chunk_free(&key_data);
this->logger->log(this->logger, CONTROL|LEVEL2, "add KE payload to message");
- request->add_payload(request, (payload_t *) ke_payload);
+ msg->add_payload(msg, (payload_t *) ke_payload);
}
/**
* Implementation of private_initiator_init_t.build_nonce_payload.
*/
-static status_t build_nonce_payload(private_initiator_init_t *this, message_t *request)
+static status_t build_nonce_payload(private_initiator_init_t *this, message_t *msg)
{
nonce_payload_t *nonce_payload;
randomizer_t *randomizer;
@@ -306,36 +306,36 @@ static status_t build_nonce_payload(private_initiator_init_t *this, message_t *r
nonce_payload->set_nonce(nonce_payload, this->sent_nonce);
this->logger->log(this->logger, CONTROL|LEVEL2, "add NONCE payload to message");
- request->add_payload(request, (payload_t *) nonce_payload);
+ msg->add_payload(msg, (payload_t *) nonce_payload);
return SUCCESS;
}
/**
* Implementation of private_initiator_init_t.build_natd_payload.
*/
-static void build_natd_payload(private_initiator_init_t *this, message_t *request, notify_message_type_t type, host_t *host)
+static void build_natd_payload(private_initiator_init_t *this, message_t *msg, notify_message_type_t type, host_t *host)
{
chunk_t hash;
- this->logger->log(this->logger, CONTROL|LEVEL1, "Building Notify(NAT-D) payload");
+ this->logger->log(this->logger, CONTROL|LEVEL1, "building Notify(NAT-D) payload");
notify_payload_t *notify_payload;
notify_payload = notify_payload_create();
/*notify_payload->set_protocol_id(notify_payload, NULL);*/
/*notify_payload->set_spi(notify_payload, NULL);*/
notify_payload->set_notify_message_type(notify_payload, type);
hash = this->ike_sa->generate_natd_hash(this->ike_sa,
- request->get_initiator_spi(request),
- request->get_responder_spi(request),
- host);
+ msg->get_initiator_spi(msg),
+ msg->get_responder_spi(msg),
+ host);
notify_payload->set_notification_data(notify_payload, hash);
chunk_free(&hash);
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add Notify(NAT-D) payload to message");
- request->add_payload(request, (payload_t *) notify_payload);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add Notify(NAT-D) payload to message");
+ msg->add_payload(msg, (payload_t *) notify_payload);
}
/**
* Implementation of private_initiator_init_t.build_natd_payloads.
*/
-static void build_natd_payloads(private_initiator_init_t *this, message_t *request)
+static void build_natd_payloads(private_initiator_init_t *this, message_t *msg)
{
connection_t *connection;
linked_list_t *hostlist;
@@ -348,7 +348,7 @@ static void build_natd_payloads(private_initiator_init_t *this, message_t *reque
hostlist = charon->interfaces->get_addresses(charon->interfaces);
hostiter = hostlist->create_iterator(hostlist, TRUE);
while(hostiter->iterate(hostiter, (void**)&host)) {
- this->build_natd_payload(this, request, NAT_DETECTION_SOURCE_IP,
+ this->build_natd_payload(this, msg, NAT_DETECTION_SOURCE_IP,
host);
}
hostiter->destroy(hostiter);
@@ -357,7 +357,7 @@ static void build_natd_payloads(private_initiator_init_t *this, message_t *reque
* N(NAT_DETECTION_DESTINATION_IP)
*/
connection = this->ike_sa->get_connection(this->ike_sa);
- this->build_natd_payload(this, request, NAT_DETECTION_DESTINATION_IP,
+ this->build_natd_payload(this, msg, NAT_DETECTION_DESTINATION_IP,
connection->get_other_host(connection));
}
diff --git a/src/charon/sa/states/responder_init.c b/src/charon/sa/states/responder_init.c
index 5dad9e78e..f9d61f90d 100644
--- a/src/charon/sa/states/responder_init.c
+++ b/src/charon/sa/states/responder_init.c
@@ -29,6 +29,7 @@
#include <encoding/payloads/sa_payload.h>
#include <encoding/payloads/ke_payload.h>
#include <encoding/payloads/nonce_payload.h>
+#include <encoding/payloads/certreq_payload.h>
#include <encoding/payloads/notify_payload.h>
#include <crypto/diffie_hellman.h>
#include <queues/jobs/send_keepalive_job.h>
@@ -128,52 +129,66 @@ struct private_responder_init_t {
*
* @param this calling object
* @param sa_request The received SA payload
- * @param response the SA payload is added to this response message_t object.
+ * @param msg the SA payload is added to this message_t object.
* @return
* - DESTROY_ME
* - SUCCESS
*/
- status_t (*build_sa_payload) (private_responder_init_t *this,sa_payload_t *sa_request, message_t *response);
+ status_t (*build_sa_payload) (private_responder_init_t *this,sa_payload_t *sa_request, message_t *msg);
/**
* Handles received KE payload and builds the KE payload for the response.
*
- * @param this calling object
+ * @param this calling object
* @param ke_request The received KE payload
- * @param response the KE payload is added to this response message_t object.
+ * @param msg the KE payload is added to this message_t object.
+ * @return
* - DESTROY_ME
* - SUCCESS
*/
- status_t (*build_ke_payload) (private_responder_init_t *this,ke_payload_t *ke_request, message_t *response);
+ status_t (*build_ke_payload) (private_responder_init_t *this,ke_payload_t *ke_request, message_t *msg);
/**
* Handles received NONCE payload and builds the NONCE payload for the response.
*
* @param this calling object
* @param nonce_request The received NONCE payload
- * @param response the NONCE payload is added to this response message_t object.
+ * @param msg the NONCE payload is added to this message_t object.
+ * @return
* - DESTROY_ME
* - SUCCESS
*/
- status_t (*build_nonce_payload) (private_responder_init_t *this,nonce_payload_t *nonce_request, message_t *response);
+ status_t (*build_nonce_payload) (private_responder_init_t *this,nonce_payload_t *nonce_request, message_t *msg);
+
+ /**
+ * Build CERTREQ payload for the response.
+ *
+ * @param this calling object
+ * @param msg the CERTREQ payload is added to this message_t object
+ * @return
+ * - SUCCESS
+ * - FAILED
+ */
+ status_t (*build_certreq_payload) (private_responder_init_t *this, message_t *msg);
+
/**
* Builds the NAT-T Notify(NAT_DETECTION_SOURCE_IP) and
* Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state.
*
* @param this calling object
- * @param request message_t object to add the Notify payloads
+ * @param msg message_t object to add the Notify payloads
*/
- void (*build_natd_payload) (private_responder_init_t *this, message_t *request, notify_message_type_t type, host_t *host);
+ void (*build_natd_payload) (private_responder_init_t *this, message_t *msg, notify_message_type_t type, host_t *host);
/**
* Builds the NAT-T Notify(NAT_DETECTION_SOURCE_IP) and
* Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state.
*
* @param this calling object
- * @param request message_t object to add the Notify payloads
+ * @param msg message_t object to add the Notify payloads
*/
- void (*build_natd_payloads) (private_responder_init_t *this, message_t *request);
+ void (*build_natd_payloads) (private_responder_init_t *this, message_t *msg);
/**
* Sends a IKE_SA_INIT reply containing a notify payload.
@@ -346,16 +361,16 @@ static status_t process_message(private_responder_init_t *this, message_t *messa
}
if (this->natd_seen_r > 1)
{
- this->logger->log(this->logger, AUDIT, "Warning: IKE_SA_INIT request contained multiple Notify(NAT_DETECTION_DESTINATION_IP) payloads.");
+ this->logger->log(this->logger, AUDIT, "warning: IKE_SA_INIT request contained multiple Notify(NAT_DETECTION_DESTINATION_IP) payloads.");
}
if (this->natd_seen_i > 0 && !this->natd_hash_i_matched)
{
- this->logger->log(this->logger, AUDIT, "Remote host is behind NAT, using NAT-T.");
+ this->logger->log(this->logger, AUDIT, "remote host is behind NAT, using NAT-Traversal");
this->ike_sa->set_other_host_behind_nat(this->ike_sa, TRUE);
}
if (this->natd_seen_r > 0 && !this->natd_hash_r_matched)
{
- this->logger->log(this->logger, AUDIT, "Local host is behind NAT, using NAT-T.");
+ this->logger->log(this->logger, AUDIT, "local host is behind NAT, using NAT-Traversal");
this->ike_sa->set_my_host_behind_nat(this->ike_sa, TRUE);
charon->event_queue->add_relative(charon->event_queue,
(job_t*)send_keepalive_job_create(this->ike_sa->public.get_id((ike_sa_t*)this->ike_sa)),
@@ -363,32 +378,27 @@ static status_t process_message(private_responder_init_t *this, message_t *messa
}
if (!this->ike_sa->public.is_any_host_behind_nat((ike_sa_t*)this->ike_sa))
{
- this->logger->log(this->logger, AUDIT, "No NAT detected, not using NAT-T.");
+ this->logger->log(this->logger, AUDIT, "no NAT detected, not using NAT-Traversal");
}
this->ike_sa->build_message(this->ike_sa, IKE_SA_INIT, FALSE, &response);
status = this->build_sa_payload(this, sa_request, response);
if (status != SUCCESS)
- {
- response->destroy(response);
- return status;
- }
+ goto destroy_response;
status = this->build_ke_payload(this, ke_request, response);
if (status != SUCCESS)
- {
- response->destroy(response);
- return status;
- }
+ goto destroy_response;
status = this->build_nonce_payload(this, nonce_request, response);
if (status != SUCCESS)
- {
- response->destroy(response);
- return status;
- }
-
+ goto destroy_response;
+
+ status = this->build_certreq_payload(this, response);
+ if (status != SUCCESS)
+ goto destroy_response;
+
/* build Notify(NAT-D) payloads */
this->build_natd_payloads(this, response);
@@ -422,14 +432,18 @@ static status_t process_message(private_responder_init_t *this, message_t *messa
/* state can now be changed */
this->ike_sa->set_new_state(this->ike_sa, (state_t *) next_state);
this->destroy_after_state_change(this);
-
return SUCCESS;
+
+destroy_response:
+ response->destroy(response);
+ return status;
+
}
/**
* Implementation of private_initiator_init_t.build_sa_payload.
*/
-static status_t build_sa_payload(private_responder_init_t *this,sa_payload_t *sa_request, message_t *response)
+static status_t build_sa_payload(private_responder_init_t *this,sa_payload_t *sa_request, message_t *msg)
{
proposal_t *proposal;
linked_list_t *proposal_list;
@@ -468,7 +482,7 @@ static status_t build_sa_payload(private_responder_init_t *this,sa_payload_t *sa
this->logger->log(this->logger, CONTROL|LEVEL2, "building SA payload");
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);
+ msg->add_payload(msg, (payload_t *) sa_payload);
return SUCCESS;
}
@@ -476,7 +490,7 @@ static status_t build_sa_payload(private_responder_init_t *this,sa_payload_t *sa
/**
* Implementation of private_initiator_init_t.build_ke_payload.
*/
-static status_t build_ke_payload(private_responder_init_t *this,ke_payload_t *ke_request, message_t *response)
+static status_t build_ke_payload(private_responder_init_t *this,ke_payload_t *ke_request, message_t *msg)
{
diffie_hellman_group_t group;
ke_payload_t *ke_payload;
@@ -532,7 +546,7 @@ static status_t build_ke_payload(private_responder_init_t *this,ke_payload_t *ke
chunk_free(&key_data);
this->logger->log(this->logger, CONTROL|LEVEL2, "add KE payload to message");
- response->add_payload(response,(payload_t *) ke_payload);
+ msg->add_payload(msg, (payload_t *) ke_payload);
return SUCCESS;
}
@@ -540,7 +554,7 @@ static status_t build_ke_payload(private_responder_init_t *this,ke_payload_t *ke
/**
* Implementation of private_responder_init_t.build_nonce_payload.
*/
-static status_t build_nonce_payload(private_responder_init_t *this,nonce_payload_t *nonce_request, message_t *response)
+static status_t build_nonce_payload(private_responder_init_t *this,nonce_payload_t *nonce_request, message_t *msg)
{
nonce_payload_t *nonce_payload;
randomizer_t *randomizer;
@@ -567,43 +581,58 @@ static status_t build_nonce_payload(private_responder_init_t *this,nonce_payload
nonce_payload->set_nonce(nonce_payload, this->sent_nonce);
this->logger->log(this->logger, CONTROL|LEVEL2, "add NONCE payload to message");
- response->add_payload(response,(payload_t *) nonce_payload);
+ msg->add_payload(msg, (payload_t *) nonce_payload);
return SUCCESS;
}
/**
+ * Implementation of private_responder_init_t.build_certreq_payload.
+ */
+static status_t build_certreq_payload (private_responder_init_t *this, message_t *msg)
+{
+ if (FALSE)
+ {
+ certreq_payload_t *certreq_payload;
+
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add CERTREQ payload to message");
+ msg->add_payload(msg, (payload_t *) certreq_payload);
+ }
+ return SUCCESS;
+}
+
+/**
* Implementation of private_initiator_init_t.build_natd_payload.
*/
-static void build_natd_payload(private_responder_init_t *this, message_t *request, notify_message_type_t type, host_t *host)
+static void build_natd_payload(private_responder_init_t *this, message_t *msg, notify_message_type_t type, host_t *host)
{
chunk_t hash;
- this->logger->log(this->logger, CONTROL|LEVEL1, "Building Notify(NAT-D) payload");
+ this->logger->log(this->logger, CONTROL|LEVEL1, "building Notify(NAT-D) payload");
notify_payload_t *notify_payload;
notify_payload = notify_payload_create();
/*notify_payload->set_protocol_id(notify_payload, NULL);*/
/*notify_payload->set_spi(notify_payload, NULL);*/
notify_payload->set_notify_message_type(notify_payload, type);
hash = this->ike_sa->generate_natd_hash(this->ike_sa,
- request->get_initiator_spi(request),
- request->get_responder_spi(request),
- host);
+ msg->get_initiator_spi(msg),
+ msg->get_responder_spi(msg),
+ host);
notify_payload->set_notification_data(notify_payload, hash);
chunk_free(&hash);
- this->logger->log(this->logger, CONTROL|LEVEL2, "Add Notify(NAT-D) payload to message");
- request->add_payload(request, (payload_t *) notify_payload);
+ this->logger->log(this->logger, CONTROL|LEVEL2, "add Notify(NAT-D) payload to message");
+ msg->add_payload(msg, (payload_t *) notify_payload);
}
/**
* Implementation of private_initiator_init_t.build_natd_payloads.
*/
-static void build_natd_payloads(private_responder_init_t *this, message_t *request)
+static void build_natd_payloads(private_responder_init_t *this, message_t *msg)
{
connection_t *connection;
connection = this->ike_sa->get_connection(this->ike_sa);
- this->build_natd_payload(this, request, NAT_DETECTION_SOURCE_IP,
+ this->build_natd_payload(this, msg, NAT_DETECTION_SOURCE_IP,
connection->get_my_host(connection));
- this->build_natd_payload(this, request, NAT_DETECTION_DESTINATION_IP,
+ this->build_natd_payload(this, msg, NAT_DETECTION_DESTINATION_IP,
connection->get_other_host(connection));
}
@@ -744,6 +773,7 @@ responder_init_t *responder_init_create(protected_ike_sa_t *ike_sa)
this->build_sa_payload = build_sa_payload;
this->build_ke_payload = build_ke_payload;
this->build_nonce_payload = build_nonce_payload;
+ this->build_certreq_payload = build_certreq_payload;
this->destroy_after_state_change = destroy_after_state_change;
this->process_notify_payload = process_notify_payload;
this->build_natd_payload = build_natd_payload;