support of cert payloads

This commit is contained in:
Andreas Steffen
2006-07-03 06:27:45 +00:00
parent 1d390631d7
commit 971218c3ae
27 changed files with 1082 additions and 634 deletions
+10 -8
View File
@@ -72,7 +72,7 @@ struct private_connection_t {
/** /**
* should we send a certificate request? * should we send a certificate request?
*/ */
cert_policy_t cert_req_policy; cert_policy_t certreq_policy;
/** /**
* should we send a certificates? * should we send a certificates?
@@ -122,11 +122,11 @@ static bool is_ikev2 (private_connection_t *this)
} }
/** /**
* Implementation of connection_t.get_cert_req_policy. * Implementation of connection_t.get_certreq_policy.
*/ */
static cert_policy_t get_cert_req_policy (private_connection_t *this) static cert_policy_t get_certreq_policy (private_connection_t *this)
{ {
return this->cert_req_policy; return this->certreq_policy;
} }
/** /**
@@ -295,7 +295,8 @@ static connection_t *clone(private_connection_t *this)
proposal_t *proposal; proposal_t *proposal;
private_connection_t *clone = (private_connection_t*)connection_create( private_connection_t *clone = (private_connection_t*)connection_create(
this->name, this->ikev2, this->name, this->ikev2,
this->cert_policy, this->cert_req_policy, this->cert_policy,
this->certreq_policy,
this->my_host->clone(this->my_host), this->my_host->clone(this->my_host),
this->other_host->clone(this->other_host), this->other_host->clone(this->other_host),
this->auth_method); this->auth_method);
@@ -336,7 +337,8 @@ static void destroy(private_connection_t *this)
* Described in header. * Described in header.
*/ */
connection_t * connection_create(char *name, bool ikev2, connection_t * connection_create(char *name, bool ikev2,
cert_policy_t cert_policy, cert_policy_t cert_req_policy, cert_policy_t cert_policy,
cert_policy_t certreq_policy,
host_t *my_host, host_t *other_host, host_t *my_host, host_t *other_host,
auth_method_t auth_method) auth_method_t auth_method)
{ {
@@ -346,7 +348,7 @@ connection_t * connection_create(char *name, bool ikev2,
this->public.get_name = (char*(*)(connection_t*))get_name; this->public.get_name = (char*(*)(connection_t*))get_name;
this->public.is_ikev2 = (bool(*)(connection_t*))is_ikev2; this->public.is_ikev2 = (bool(*)(connection_t*))is_ikev2;
this->public.get_cert_policy = (cert_policy_t(*)(connection_t*))get_cert_policy; this->public.get_cert_policy = (cert_policy_t(*)(connection_t*))get_cert_policy;
this->public.get_cert_req_policy = (cert_policy_t(*)(connection_t*))get_cert_req_policy; this->public.get_certreq_policy = (cert_policy_t(*)(connection_t*))get_certreq_policy;
this->public.get_my_host = (host_t*(*)(connection_t*))get_my_host; this->public.get_my_host = (host_t*(*)(connection_t*))get_my_host;
this->public.update_my_host = (void(*)(connection_t*,host_t*))update_my_host; this->public.update_my_host = (void(*)(connection_t*,host_t*))update_my_host;
this->public.update_other_host = (void(*)(connection_t*,host_t*))update_other_host; this->public.update_other_host = (void(*)(connection_t*,host_t*))update_other_host;
@@ -364,7 +366,7 @@ connection_t * connection_create(char *name, bool ikev2,
this->name = strdup(name); this->name = strdup(name);
this->ikev2 = ikev2; this->ikev2 = ikev2;
this->cert_policy = cert_policy; this->cert_policy = cert_policy;
this->cert_req_policy = cert_req_policy; this->certreq_policy = certreq_policy;
this->my_host = my_host; this->my_host = my_host;
this->other_host = other_host; this->other_host = other_host;
this->auth_method = auth_method; this->auth_method = auth_method;
+1 -1
View File
@@ -228,7 +228,7 @@ struct connection_t {
* @param this calling object * @param this calling object
* @return - TRUE, if certificate request should be sent * @return - TRUE, if certificate request should be sent
*/ */
cert_policy_t (*get_cert_req_policy) (connection_t *this); cert_policy_t (*get_certreq_policy) (connection_t *this);
/** /**
* @brief Should be sent a certificate for this connection? * @brief Should be sent a certificate for this connection?
@@ -63,14 +63,21 @@ struct credential_store_t {
/** /**
* @brief Returns the RSA public key of a specific ID. * @brief Returns the RSA public key of a specific ID.
* *
* The returned rsa_public_key_t must be destroyed by the caller after usage.
*
* @param this calling object * @param this calling object
* @param id identification_t object identifiying the key. * @param id identification_t object identifiying the key.
* @return public key, or NULL if not found * @return public key, or NULL if not found
*/ */
rsa_public_key_t* (*get_rsa_public_key) (credential_store_t *this, identification_t *id); rsa_public_key_t* (*get_rsa_public_key) (credential_store_t *this, identification_t *id);
/**
* @brief Returns the RSA public key of a specific ID if is trusted
*
* @param this calling object
* @param id identification_t object identifiying the key.
* @return public key, or NULL if not found or not trusted
*/
rsa_public_key_t* (*get_trusted_public_key) (credential_store_t *this, identification_t *id);
/** /**
* @brief Returns the RSA private key belonging to an RSA public key * @brief Returns the RSA private key belonging to an RSA public key
* *
@@ -91,15 +98,24 @@ struct credential_store_t {
*/ */
bool (*has_rsa_private_key) (credential_store_t *this, rsa_public_key_t *pubkey); bool (*has_rsa_private_key) (credential_store_t *this, rsa_public_key_t *pubkey);
/**
* @brief Returns the certificate of a specific ID.
*
* @param this calling object
* @param id identification_t object identifiying the key.
* @return certificate, or NULL if not found
*/
x509_t* (*get_certificate) (credential_store_t *this, identification_t *id);
/** /**
* @brief Verify an X.509 certificate up to trust anchor including revocation checks * @brief Verify an X.509 certificate up to trust anchor including revocation checks
* *
* @param this calling object * @param this calling object
* @param cert certificate to be verified * @param cert certificate to be verified
* @param until time until which the cert can be trusted * @param found found a certificate copy in the credential store
* @return TRUE if trusted * @return TRUE if trusted
*/ */
bool (*verify) (credential_store_t *this, const x509_t *cert, time_t *until); bool (*verify) (credential_store_t *this, x509_t *cert, bool *found);
/** /**
* @brief If an end certificate does not already exists in the credential store then add it. * @brief If an end certificate does not already exists in the credential store then add it.
@@ -25,6 +25,7 @@
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include <types.h>
#include <utils/lexparser.h> #include <utils/lexparser.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/logger_manager.h> #include <utils/logger_manager.h>
@@ -96,11 +97,11 @@ static status_t get_shared_secret(private_local_credential_store_t *this, identi
} }
/** /**
* Implementation of local_credential_store_t.get_rsa_public_key. * Implementation of credential_store_t.get_certificate.
*/ */
static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *this, identification_t *id) static x509_t* get_certificate(private_local_credential_store_t *this, identification_t * id)
{ {
rsa_public_key_t *found = NULL; x509_t *found = NULL;
iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE); iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
@@ -112,7 +113,7 @@ static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *th
if (id->equals(id, cert->get_subject(cert)) || cert->equals_subjectAltName(cert, id)) if (id->equals(id, cert->get_subject(cert)) || cert->equals_subjectAltName(cert, id))
{ {
found = cert->get_public_key(cert); found = cert;
break; break;
} }
} }
@@ -120,6 +121,52 @@ static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *th
return found; return found;
} }
/**
* Implementation of local_credential_store_t.get_rsa_public_key.
*/
static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *this, identification_t *id)
{
x509_t *cert = get_certificate(this, id);
return (cert == NULL)? NULL:cert->get_public_key(cert);
}
/**
* Implementation of local_credential_store_t.get_trusted_public_key.
*/
static rsa_public_key_t *get_trusted_public_key(private_local_credential_store_t *this, identification_t *id)
{
cert_status_t status;
err_t ugh;
x509_t *cert = get_certificate(this, id);
if (cert == NULL)
return NULL;
ugh = cert->is_valid(cert, NULL);
if (ugh != NULL)
{
this->logger->log(this->logger, ERROR, "certificate %s");
return NULL;
}
status = cert->get_status(cert);
if (status == CERT_REVOKED || status == CERT_UNTRUSTED || (this->strict && status != CERT_GOOD))
{
this->logger->log(this->logger, ERROR, "certificate status: %s",
enum_name(&cert_status_names, status));
return NULL;
}
if (status == CERT_GOOD && cert->get_until(cert) < time(NULL))
{
this->logger->log(this->logger, ERROR, "certificate is good but crl is stale");
return NULL;
}
return cert->get_public_key(cert);
}
/** /**
* Implementation of local_credential_store_t.get_rsa_private_key. * Implementation of local_credential_store_t.get_rsa_private_key.
*/ */
@@ -241,7 +288,6 @@ static cert_status_t verify_by_crl(private_local_credential_store_t* this, const
issuer_public_key = issuer_cert->get_public_key(issuer_cert); issuer_public_key = issuer_cert->get_public_key(issuer_cert);
valid_signature = crl->verify(crl, issuer_public_key); valid_signature = crl->verify(crl, issuer_public_key);
issuer_public_key->destroy(issuer_public_key);
if (!valid_signature) if (!valid_signature)
{ {
@@ -268,21 +314,47 @@ static cert_status_t verify_by_ocsp(private_local_credential_store_t* this,
} }
/** /**
* Remove a public key for the linked list * Find an exact copy of a certificate in a linked list
*/ */
static void remove_public_key(private_local_credential_store_t *this, const x509_t *cert) static x509_t* find_certificate_copy(linked_list_t *certs, x509_t *cert)
{ {
/* TODO implement function */ x509_t *found_cert = NULL;
iterator_t *iterator = certs->create_iterator(certs, TRUE);
while (iterator->has_next(iterator))
{
x509_t *current_cert;
iterator->current(iterator, (void**)&current_cert);
if (cert->equals(cert, current_cert))
{
found_cert = current_cert;
break;
}
}
iterator->destroy(iterator);
return found_cert;
} }
/** /**
* Implementation of credential_store_t.verify. * Implementation of credential_store_t.verify.
*/ */
static bool verify(private_local_credential_store_t *this, const x509_t *cert, time_t *until) static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *found)
{ {
int pathlen; int pathlen;
time_t until = UNDEFINED_TIME;
x509_t *end_cert = cert;
x509_t *cert_copy = find_certificate_copy(this->certs, end_cert);
*until = UNDEFINED_TIME; *found = (cert_copy != NULL);
if (*found)
{
this->logger->log(this->logger, CONTROL|LEVEL1,
"end entitity certificate is already in credential store");
}
for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++) for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
{ {
@@ -297,7 +369,7 @@ static bool verify(private_local_credential_store_t *this, const x509_t *cert, t
this->logger->log(this->logger, CONTROL|LEVEL1, "subject: '%s'", subject->get_string(subject)); this->logger->log(this->logger, CONTROL|LEVEL1, "subject: '%s'", subject->get_string(subject));
this->logger->log(this->logger, CONTROL|LEVEL1, "issuer: '%s'", issuer->get_string(issuer)); this->logger->log(this->logger, CONTROL|LEVEL1, "issuer: '%s'", issuer->get_string(issuer));
ugh = cert->is_valid(cert, until); ugh = cert->is_valid(cert, &until);
if (ugh != NULL) if (ugh != NULL)
{ {
this->logger->log(this->logger, ERROR, "certificate %s", ugh); this->logger->log(this->logger, ERROR, "certificate %s", ugh);
@@ -315,7 +387,6 @@ static bool verify(private_local_credential_store_t *this, const x509_t *cert, t
issuer_public_key = issuer_cert->get_public_key(issuer_cert); issuer_public_key = issuer_cert->get_public_key(issuer_cert);
valid_signature = cert->verify(cert, issuer_public_key); valid_signature = cert->verify(cert, issuer_public_key);
issuer_public_key->destroy(issuer_public_key);
if (!valid_signature) if (!valid_signature)
{ {
@@ -328,6 +399,14 @@ static bool verify(private_local_credential_store_t *this, const x509_t *cert, t
if (pathlen > 0 && cert->is_self_signed(cert)) if (pathlen > 0 && cert->is_self_signed(cert))
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, "reached self-signed root ca"); this->logger->log(this->logger, CONTROL|LEVEL1, "reached self-signed root ca");
/* set the definite status and trust interval of the end entity certificate */
end_cert->set_until(end_cert, until);
if (cert_copy)
{
cert_copy->set_status(cert_copy, end_cert->get_status(end_cert));
cert_copy->set_until(cert_copy, until);
}
return TRUE; return TRUE;
} }
else else
@@ -336,7 +415,7 @@ static bool verify(private_local_credential_store_t *this, const x509_t *cert, t
cert_status_t status; cert_status_t status;
certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert)); certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert));
certinfo->set_nextUpdate(certinfo, *until); certinfo->set_nextUpdate(certinfo, until);
/* first check certificate revocation using ocsp */ /* first check certificate revocation using ocsp */
status = verify_by_ocsp(this, cert, certinfo); status = verify_by_ocsp(this, cert, certinfo);
@@ -348,24 +427,27 @@ static bool verify(private_local_credential_store_t *this, const x509_t *cert, t
} }
nextUpdate = certinfo->get_nextUpdate(certinfo); nextUpdate = certinfo->get_nextUpdate(certinfo);
cert->set_status(cert, status);
switch (status) switch (status)
{ {
case CERT_GOOD: case CERT_GOOD:
/* set nextUpdate */
cert->set_until(cert, nextUpdate);
/* if status information is stale */ /* if status information is stale */
if (this->strict && nextUpdate < time(NULL)) if (this->strict && nextUpdate < time(NULL))
{ {
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good but status is stale"); this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good but status is stale");
remove_public_key(this, cert);
return FALSE; return FALSE;
} }
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good"); this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good");
/* with strict crl policy the public key must have the same /* with strict crl policy the public key must have the same
* lifetime as the validity of the ocsp status or crl lifetime * lifetime as the validity of the ocsp status or crl lifetime
*/ */
if (this->strict && nextUpdate < *until) if (this->strict && nextUpdate < until)
*until = nextUpdate; until = nextUpdate;
break; break;
case CERT_REVOKED: case CERT_REVOKED:
{ {
@@ -375,7 +457,23 @@ static bool verify(private_local_credential_store_t *this, const x509_t *cert, t
timetoa(buf, TIMETOA_BUF, &revocationTime, TRUE); timetoa(buf, TIMETOA_BUF, &revocationTime, TRUE);
this->logger->log(this->logger, ERROR, "certificate was revoked on %s, reason: %s", this->logger->log(this->logger, ERROR, "certificate was revoked on %s, reason: %s",
buf, certinfo->get_revocationReason(certinfo)); buf, certinfo->get_revocationReason(certinfo));
remove_public_key(this, cert);
/* set revocationTime */
cert->set_until(cert, revocationTime);
/* update status of end certificate in the credential store */
if (cert_copy)
{
if (pathlen > 0)
{
cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
}
else
{
cert_copy->set_status(cert_copy, CERT_REVOKED);
cert_copy->set_until(cert_copy, certinfo->get_revocationTime(certinfo));
}
}
return FALSE; return FALSE;
} }
case CERT_UNKNOWN: case CERT_UNKNOWN:
@@ -384,7 +482,11 @@ static bool verify(private_local_credential_store_t *this, const x509_t *cert, t
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate status unknown"); this->logger->log(this->logger, CONTROL|LEVEL1, "certificate status unknown");
if (this->strict) if (this->strict)
{ {
remove_public_key(this, cert); /* update status of end certificate in the credential store */
if (cert_copy)
{
cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
}
return FALSE; return FALSE;
} }
break; break;
@@ -403,30 +505,18 @@ static bool verify(private_local_credential_store_t *this, const x509_t *cert, t
*/ */
static x509_t* add_certificate(linked_list_t *certs, x509_t *cert) static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
{ {
bool found = FALSE; x509_t *found_cert = find_certificate_copy(certs, cert);
iterator_t *iterator = certs->create_iterator(certs, TRUE); if (found_cert)
while (iterator->has_next(iterator))
{ {
x509_t *current_cert; cert->destroy(cert);
return found_cert;
iterator->current(iterator, (void**)&current_cert);
if (cert->equals(cert, current_cert))
{
found = TRUE;
cert->destroy(cert);
cert = current_cert;
break;
}
} }
iterator->destroy(iterator); else
if (!found)
{ {
certs->insert_last(certs, (void*)cert); certs->insert_last(certs, (void*)cert);
return cert;
} }
return cert;
} }
/** /**
@@ -829,20 +919,22 @@ local_credential_store_t * local_credential_store_create(bool strict)
{ {
private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t); private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
this->public.credential_store.get_shared_secret = (status_t(*)(credential_store_t*,identification_t*,chunk_t*))get_shared_secret; this->public.credential_store.get_shared_secret = (status_t (*) (credential_store_t*,identification_t*,chunk_t*))get_shared_secret;
this->public.credential_store.get_rsa_private_key = (rsa_private_key_t*(*)(credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
this->public.credential_store.has_rsa_private_key = (bool(*)(credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key; this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
this->public.credential_store.verify = (bool(*)(credential_store_t*,const x509_t*,time_t*))verify; this->public.credential_store.get_rsa_private_key = (rsa_private_key_t* (*) (credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
this->public.credential_store.add_end_certificate = (x509_t*(*)(credential_store_t*,x509_t*))add_end_certificate; this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
this->public.credential_store.add_ca_certificate = (x509_t*(*)(credential_store_t*,x509_t*))add_ca_certificate; this->public.credential_store.get_trusted_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_trusted_public_key;
this->public.credential_store.log_certificates = (void(*)(credential_store_t*,logger_t*,bool))log_certificates; this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
this->public.credential_store.log_ca_certificates = (void(*)(credential_store_t*,logger_t*,bool))log_ca_certificates; this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
this->public.credential_store.log_crls = (void(*)(credential_store_t*,logger_t*,bool))log_crls; this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
this->public.credential_store.load_ca_certificates = (void(*)(credential_store_t*))load_ca_certificates; this->public.credential_store.add_ca_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_ca_certificate;
this->public.credential_store.load_crls = (void(*)(credential_store_t*))load_crls; this->public.credential_store.log_certificates = (void (*) (credential_store_t*,logger_t*,bool))log_certificates;
this->public.credential_store.load_private_keys = (void(*)(credential_store_t*))load_private_keys; this->public.credential_store.log_ca_certificates = (void (*) (credential_store_t*,logger_t*,bool))log_ca_certificates;
this->public.credential_store.destroy = (void(*)(credential_store_t*))destroy; this->public.credential_store.log_crls = (void (*) (credential_store_t*,logger_t*,bool))log_crls;
this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
this->public.credential_store.load_private_keys = (void (*) (credential_store_t*))load_private_keys;
this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy;
/* initialize mutexes */ /* initialize mutexes */
pthread_mutex_init(&(this->crls_mutex), NULL); pthread_mutex_init(&(this->crls_mutex), NULL);
+23
View File
@@ -67,6 +67,11 @@ struct private_policy_t {
*/ */
identification_t *other_ca; identification_t *other_ca;
/**
* updown script
*/
char *updown;
/** /**
* list for all proposals * list for all proposals
*/ */
@@ -303,6 +308,14 @@ static void add_authorities(private_policy_t *this, identification_t *my_ca, ide
this->other_ca = other_ca; this->other_ca = other_ca;
} }
/**
* Implementation of policy_t.add_updown
*/
static void add_updown(private_policy_t *this, char *updown)
{
this->updown = (updown == NULL)? NULL:strdup(updown);
}
/** /**
* Implementation of policy_t.add_my_traffic_selector * Implementation of policy_t.add_my_traffic_selector
*/ */
@@ -371,6 +384,9 @@ static policy_t *clone(private_policy_t *this)
{ {
clone->other_ca = this->other_ca->clone(this->other_ca); clone->other_ca = this->other_ca->clone(this->other_ca);
} }
/* clone updown script */
clone->updown = (this->updown == NULL)? NULL:strdup(this->updown);
/* clone all proposals */ /* clone all proposals */
iterator = this->proposals->create_iterator(this->proposals, TRUE); iterator = this->proposals->create_iterator(this->proposals, TRUE);
@@ -445,6 +461,12 @@ static status_t destroy(private_policy_t *this)
this->other_ca->destroy(this->other_ca); this->other_ca->destroy(this->other_ca);
} }
/* delete updown script */
if (this->updown)
{
free(this->updown);
}
/* delete ids */ /* delete ids */
this->my_id->destroy(this->my_id); this->my_id->destroy(this->my_id);
this->other_id->destroy(this->other_id); this->other_id->destroy(this->other_id);
@@ -481,6 +503,7 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
this->public.add_other_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_other_traffic_selector; this->public.add_other_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_other_traffic_selector;
this->public.add_proposal = (void(*)(policy_t*,proposal_t*))add_proposal; this->public.add_proposal = (void(*)(policy_t*,proposal_t*))add_proposal;
this->public.add_authorities = (void(*)(policy_t*,identification_t*, identification_t*))add_authorities; this->public.add_authorities = (void(*)(policy_t*,identification_t*, identification_t*))add_authorities;
this->public.add_updown = (void(*)(policy_t*,identification_t*,char*))add_updown;
this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime; this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime;
this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime; this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime;
this->public.clone = (policy_t*(*)(policy_t*))clone; this->public.clone = (policy_t*(*)(policy_t*))clone;
+8
View File
@@ -238,6 +238,14 @@ struct policy_t {
*/ */
void (*add_authorities) (policy_t *this, identification_t *my_ca, identification_t *other_ca); void (*add_authorities) (policy_t *this, identification_t *my_ca, identification_t *other_ca);
/**
* @brief Add updown script
*
* @param this calling object
* @param updown updown script
*/
void (*add_updown) (policy_t *this, char *updown);
/** /**
* @brief Get the lifetime of a policy, before rekeying starts. * @brief Get the lifetime of a policy, before rekeying starts.
* *
+29 -14
View File
@@ -28,22 +28,25 @@
/** /**
* String mappings for cert_encoding_t. * String mappings for cert_encoding_t.
*/ */
mapping_t cert_encoding_m[] = { static const char *const cert_encoding_name[] = {
{PKCS7_WRAPPED_X509_CERTIFICATE, "PKCS7_WRAPPED_X509_CERTIFICATE"}, "CERT_NONE",
{PGP_CERTIFICATE, "PGP_CERTIFICATE"}, "CERT_PKCS7_WRAPPED_X509",
{DNS_SIGNED_KEY, "DNS_SIGNED_KEY"}, "CERT_PGP",
{X509_CERTIFICATE_SIGNATURE, "X509_CERTIFICATE_SIGNATURE"}, "CERT_DNS_SIGNED_KEY",
{KERBEROS_TOKEN, "KERBEROS_TOKEN"}, "CERT_X509_SIGNATURE",
{CERTIFICATE_REVOCATION_LIST, "CERTIFICATE_REVOCATION_LIST"}, "CERT_X509_KEY_EXCHANGE",
{AUTHORITY_REVOCATION_LIST, "AUTHORITY_REVOCATION_LIST"}, "CERT_KERBEROS_TOKENS",
{SPKI_CERTIFICATE, "SPKI_CERTIFICATE"}, "CERT_CRL",
{X509_CERTIFICATE_ATTRIBUTE, "X509_CERTIFICATE_ATTRIBUTE"}, "CERT_ARL",
{RAW_SA_KEY, "RAW_SA_KEY"}, "CERT_SPKI",
{HASH_AND_URL_X509_CERTIFICATE, "HASH_AND_URL_X509_CERTIFICATE"}, "CERT_X509_ATTRIBUTE",
{HASH_AND_URL_X509_BUNDLE, "HASH_AND_URL_X509_BUNDLE"}, "CERT_RAW_RSA_KEY",
{MAPPING_END, NULL} "CERT_X509_HASH_AND_URL",
"CERT_X509_HASH_AND_URL_BUNDLE"
}; };
enum_names cert_encoding_names =
{ CERT_NONE, CERT_X509_HASH_AND_URL_BUNDLE, cert_encoding_name, NULL };
typedef struct private_cert_payload_t private_cert_payload_t; typedef struct private_cert_payload_t private_cert_payload_t;
@@ -277,3 +280,15 @@ cert_payload_t *cert_payload_create()
return (&(this->public)); return (&(this->public));
} }
/*
* Described in header
*/
cert_payload_t *cert_payload_create_from_x509(x509_t *cert)
{
cert_payload_t *this = cert_payload_create();
this->set_cert_encoding(this, CERT_X509_SIGNATURE);
this->set_data(this, cert->get_certificate(cert));
return this;
}
+25 -15
View File
@@ -24,6 +24,7 @@
#define CERT_PAYLOAD_H_ #define CERT_PAYLOAD_H_
#include <types.h> #include <types.h>
#include <crypto/x509.h>
#include <encoding/payloads/payload.h> #include <encoding/payloads/payload.h>
/** /**
@@ -42,18 +43,19 @@ typedef enum cert_encoding_t cert_encoding_t;
* @ingroup payloads * @ingroup payloads
*/ */
enum cert_encoding_t { enum cert_encoding_t {
PKCS7_WRAPPED_X509_CERTIFICATE = 1, CERT_NONE = 0,
PGP_CERTIFICATE = 2, CERT_PKCS7_WRAPPED_X509 = 1,
DNS_SIGNED_KEY = 3, CERT_PGP = 2,
X509_CERTIFICATE_SIGNATURE = 4, CERT_DNS_SIGNED_KEY = 3,
KERBEROS_TOKEN = 6, CERT_X509_SIGNATURE = 4,
CERTIFICATE_REVOCATION_LIST = 7, CERT_KERBEROS_TOKEN = 6,
AUTHORITY_REVOCATION_LIST = 8, CERT_CRL = 7,
SPKI_CERTIFICATE = 9, CERT_ARL = 8,
X509_CERTIFICATE_ATTRIBUTE = 10, CERT_SPKI = 9,
RAW_SA_KEY = 11, CERT_X509_ATTRIBUTE = 10,
HASH_AND_URL_X509_CERTIFICATE = 12, CERT_RAW_RSA_KEY = 11,
HASH_AND_URL_X509_BUNDLE = 13 CERT_X509_HASH_AND_URL = 12,
CERT_X509_HASH_AND_URL_BUNDLE = 13
}; };
/** /**
@@ -61,8 +63,7 @@ enum cert_encoding_t {
* *
* @ingroup payloads * @ingroup payloads
*/ */
extern mapping_t cert_encoding_m[]; extern enum_names cert_encoding_names;
typedef struct cert_payload_t cert_payload_t; typedef struct cert_payload_t cert_payload_t;
@@ -145,11 +146,20 @@ struct cert_payload_t {
/** /**
* @brief Creates an empty cert_payload_t object. * @brief Creates an empty cert_payload_t object.
* *
* @return cert_payload_t object * @return cert_payload_t object
* *
* @ingroup payloads * @ingroup payloads
*/ */
cert_payload_t *cert_payload_create(void); cert_payload_t *cert_payload_create(void);
/**
* @brief Creates a cert_payload_t object with an X.509 certificate.
*
* @param cert X.509 certificate
* @return cert_payload_t object
*
* @ingroup payloads
*/
cert_payload_t *cert_payload_create_from_x509(x509_t *cert);
#endif /* CERT_PAYLOAD_H_ */ #endif /* CERT_PAYLOAD_H_ */
+1 -1
View File
@@ -199,7 +199,7 @@ typedef struct payload_t payload_t;
* handling of all payloads. * handling of all payloads.
* *
* @b Constructors: * @b Constructors:
* - payload_create() with the payload to instanciate. * - payload_create() with the payload to instantiate.
* *
* @ingroup payloads * @ingroup payloads
*/ */
+7 -10
View File
@@ -243,15 +243,14 @@ static status_t verify_auth_data (private_authenticator_t *this,
} }
case RSA_DIGITAL_SIGNATURE: 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; status_t status;
chunk_t octets, auth_data; chunk_t octets;
chunk_t auth_data = auth_payload->get_data(auth_payload);
auth_data = auth_payload->get_data(auth_payload); identification_t *other_id = other_id_payload->get_identification(other_id_payload);
public_key = charon->credentials->get_rsa_public_key(charon->credentials, rsa_public_key_t *public_key =
other_id); charon->credentials->get_trusted_public_key(charon->credentials, other_id);
if (public_key == NULL) if (public_key == NULL)
{ {
this->logger->log(this->logger, ERROR, "no public key found for '%s'", 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)); other_id->get_string(other_id));
} }
public_key->destroy(public_key);
other_id->destroy(other_id); other_id->destroy(other_id);
chunk_free(&octets); chunk_free(&octets);
return status; 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); 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_key = charon->credentials->get_rsa_private_key(charon->credentials, my_pubkey);
my_pubkey->destroy(my_pubkey);
if (my_key == NULL) if (my_key == NULL)
{ {
char buf[BUF_LEN]; char buf[BUF_LEN];
+117 -93
View File
@@ -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); me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_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 = message_create();
new_message->set_source(new_message, me->clone(me)); new_message->set_source(new_message, me->clone(me));
new_message->set_destination(new_message, other->clone(other)); 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) 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, get_state(this)),
mapping_find(ike_sa_state_m, state->get_state(state))); mapping_find(ike_sa_state_m, state->get_state(state)));
this->current_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; 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); packet = this->last_requested_message->get_packet(this->last_requested_message);
charon->send_queue->add(charon->send_queue, packet); charon->send_queue->add(charon->send_queue, packet);
this->update_timestamp(this, FALSE); 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)) 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; return FAILED;
} }
this->prf = prf_create(algo->algorithm); 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) */ /* SKEYSEED = prf(Ni | Nr, g^ir) */
dh->get_shared_secret(dh, &secret); 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->set_key(this->prf, nonces);
this->prf->allocate_bytes(this->prf, secret, &skeyseed); this->prf->allocate_bytes(this->prf, secret, &skeyseed);
this->logger->log_chunk(this->logger, PRIVATE | LEVEL1, "SKEYSEED", 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 */ /* SK_ai/SK_ar used for integrity protection */
if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &algo)) 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; return FAILED;
} }
if (this->signer_initiator != NULL) 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 */ /* SK_ei/SK_er used for encryption */
if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &algo)) 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; return FAILED;
} }
if (this->crypter_initiator != NULL) 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)) if (0 > gettimeofday(tv, NULL))
{ {
this->logger->log(this->logger, ERROR|LEVEL1, 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) 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); message->get_message_id(message),this->message_id_out);
return FAILED; return FAILED;
} }
/* generate packet */ /* 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)) 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); status = message->generate(message, crypter,signer, &packet);
if (status != SUCCESS) 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; return FAILED;
} }
this->logger->log(this->logger, CONTROL|LEVEL3, 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); this->message_id_out);
charon->send_queue->add(charon->send_queue, packet); 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->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; this->last_requested_message = message;
/* schedule a job for retransmission */ /* schedule a job for retransmission */
status = charon->configuration->get_retransmit_timeout(charon->configuration, 0, &timeout); status = charon->configuration->get_retransmit_timeout(charon->configuration, 0, &timeout);
if (status != SUCCESS) 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 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); 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); charon->event_queue->add_relative(charon->event_queue, (job_t *)retransmit_job, timeout);
} }
/* message counter can now be increased */ /* message counter can now be increased */
this->logger->log(this->logger, CONTROL|LEVEL3, 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);
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) 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); message->get_message_id(message),this->message_id_in);
return FAILED; 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); status = message->generate(message, crypter,signer, &packet);
if (status != SUCCESS) 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; return FAILED;
} }
this->logger->log(this->logger, CONTROL|LEVEL3, 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); this->message_id_in);
charon->send_queue->add(charon->send_queue, packet); 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->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; this->last_responded_message = message;
/* message counter can now be increased */ /* 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->message_id_in++;
this->update_timestamp(this, FALSE); 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; packet_t *packet;
status_t status; 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 */ /* set up the reply */
build_message(this, exchange_type, FALSE, &response); build_message(this, exchange_type, FALSE, &response);
payload = notify_payload_create_from_protocol_and_type(PROTO_NONE, type); payload = notify_payload_create_from_protocol_and_type(PROTO_NONE, type);
if ((data.ptr != NULL) && (data.len > 0)) 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); 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); response->add_payload(response,(payload_t *) payload);
/* generate packet */ /* 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); status = response->generate(response, this->crypter_responder, this->signer_responder, &packet);
if (status != SUCCESS) 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); response->destroy(response);
return; 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); 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); response->destroy(response);
this->update_timestamp(this, FALSE); 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); is_request = message->get_request(message);
exchange_type = message->get_exchange_type(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", (is_request) ? "request" : "response",
mapping_find(exchange_type_m, exchange_type)); 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) if (this->last_responded_message)
{ {
packet_t *packet = this->last_responded_message->get_packet(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); charon->send_queue->add(charon->send_queue, packet);
this->update_timestamp(this, FALSE); this->update_timestamp(this, FALSE);
return SUCCESS; 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) if (message_id != this->message_id_in)
{ {
this->logger->log(this->logger, ERROR | LEVEL1, 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); message_id,this->message_id_in);
return FAILED; 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)) if (message_id != (this->message_id_out - 1))
{ {
this->logger->log(this->logger, ERROR | LEVEL1, 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); message_id,this->message_id_in);
return FAILED; 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) if (other_changes & HOST_DIFF_ADDR)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, 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)); old_other->get_address(old_other), other->get_address(other));
return DESTROY_ME; 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) if (this->current_state->get_state(this->current_state) != IKE_SA_ESTABLISHED)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, 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; 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) if (this->current_state->get_state(this->current_state) != IKE_SA_ESTABLISHED)
{ {
this->logger->log(this->logger, ERROR|LEVEL1, 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; return FAILED;
} }
@@ -1277,12 +1277,35 @@ static status_t rekey_child_sa(private_ike_sa_t *this, u_int32_t reqid)
return SUCCESS; return SUCCESS;
} }
/**
* 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. * Implementation of protected_ike_sa_t.reset_message_buffers.
*/ */
static void reset_message_buffers(private_ike_sa_t *this) 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 */ /* destroy stored requested message */
if (this->last_requested_message != NULL) if (this->last_requested_message != NULL)
{ {
@@ -1497,14 +1520,14 @@ static void destroy(private_ike_sa_t *this)
{ {
child_sa_t *child_sa; 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_initiator_spi(this->ike_sa_id),
this->ike_sa_id->get_responder_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"); this->ike_sa_id->is_initiator(this->ike_sa_id) ? "initiator" : "responder");
if (get_state(this) == IKE_SA_ESTABLISHED) 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) 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); private_ike_sa_t *this = malloc_thing(private_ike_sa_t);
/* Public functions */ /* Public functions */
this->protected.public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message; 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.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.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.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_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_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_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_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_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_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.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_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.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.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.log_status = (void (*) (ike_sa_t*,logger_t*,char*))log_status;
this->protected.public.delete = (status_t(*)(ike_sa_t*))delete_; this->protected.public.delete = (status_t (*) (ike_sa_t*))delete_;
this->protected.public.destroy = (void(*)(ike_sa_t*))destroy; 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_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_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.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_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.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.send_dpd_request = (status_t (*) (ike_sa_t*)) send_dpd_request;
/* protected functions */ /* protected functions */
this->protected.build_message = (void (*) (protected_ike_sa_t *, exchange_type_t,bool,message_t**)) build_message; 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_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_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_i = (prf_t* (*) (protected_ike_sa_t*)) get_prf_auth_i;
this->protected.get_prf_auth_r = (prf_t *(*) (protected_ike_sa_t *)) get_prf_auth_r; this->protected.get_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.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.establish = (void (*) (protected_ike_sa_t*)) establish;
this->protected.get_connection = (connection_t *(*) (protected_ike_sa_t *)) get_connection; this->protected.set_connection = (void (*) (protected_ike_sa_t*,connection_t*)) set_connection;
this->protected.set_policy = (void (*) (protected_ike_sa_t *,policy_t *)) set_policy; this->protected.get_connection = (connection_t* (*) (protected_ike_sa_t*)) get_connection;
this->protected.get_policy = (policy_t *(*) (protected_ike_sa_t *)) get_policy; this->protected.set_policy = (void (*) (protected_ike_sa_t *,policy_t*)) set_policy;
this->protected.get_randomizer = (randomizer_t *(*) (protected_ike_sa_t *)) get_randomizer; this->protected.get_policy = (policy_t* (*) (protected_ike_sa_t*)) get_policy;
this->protected.send_request = (status_t (*) (protected_ike_sa_t *,message_t *)) send_request; this->protected.get_randomizer = (randomizer_t* (*) (protected_ike_sa_t*)) get_randomizer;
this->protected.send_response = (status_t (*) (protected_ike_sa_t *,message_t *)) send_response; this->protected.send_request = (status_t (*) (protected_ike_sa_t*,message_t*)) send_request;
this->protected.send_notify = (void (*)(protected_ike_sa_t*,exchange_type_t,notify_message_type_t,chunk_t)) send_notify; this->protected.send_response = (status_t (*) (protected_ike_sa_t*,message_t*)) send_response;
this->protected.build_transforms = (status_t (*) (protected_ike_sa_t *,proposal_t*,diffie_hellman_t*,chunk_t,chunk_t)) build_transforms; this->protected.send_notify = (void (*) (protected_ike_sa_t*,exchange_type_t,notify_message_type_t,chunk_t)) send_notify;
this->protected.set_new_state = (void (*) (protected_ike_sa_t *,state_t *)) set_new_state; this->protected.build_transforms = (status_t (*) (protected_ike_sa_t*,proposal_t*,diffie_hellman_t*,chunk_t,chunk_t)) build_transforms;
this->protected.get_crypter_initiator = (crypter_t *(*) (protected_ike_sa_t *)) get_crypter_initiator; this->protected.set_new_state = (void (*) (protected_ike_sa_t*,state_t*)) set_new_state;
this->protected.get_signer_initiator = (signer_t *(*) (protected_ike_sa_t *)) get_signer_initiator; this->protected.get_crypter_initiator = (crypter_t* (*) (protected_ike_sa_t*)) get_crypter_initiator;
this->protected.get_crypter_responder = (crypter_t *(*) (protected_ike_sa_t *)) get_crypter_responder; this->protected.get_signer_initiator = (signer_t* (*) (protected_ike_sa_t*)) get_signer_initiator;
this->protected.get_signer_responder = (signer_t *(*) (protected_ike_sa_t *)) get_signer_responder; this->protected.get_crypter_responder = (crypter_t* (*) (protected_ike_sa_t*)) get_crypter_responder;
this->protected.reset_message_buffers = (void (*) (protected_ike_sa_t *)) reset_message_buffers; this->protected.get_signer_responder = (signer_t* (*) (protected_ike_sa_t*)) get_signer_responder;
this->protected.get_last_responded_message = (message_t * (*) (protected_ike_sa_t *)) get_last_responded_message; this->protected.reset_message_buffers = (void (*) (protected_ike_sa_t*)) reset_message_buffers;
this->protected.get_last_requested_message = (message_t * (*) (protected_ike_sa_t *)) get_last_requested_message; this->protected.get_last_responded_message = (message_t* (*) (protected_ike_sa_t*)) get_last_responded_message;
this->protected.set_last_replied_message_id = (void (*) (protected_ike_sa_t *,u_int32_t)) set_last_replied_message_id; this->protected.get_last_requested_message = (message_t* (*) (protected_ike_sa_t*)) get_last_requested_message;
this->protected.destroy_child_sa = (u_int32_t (*)(protected_ike_sa_t*,u_int32_t))destroy_child_sa; this->protected.set_last_replied_message_id = (void (*) (protected_ike_sa_t*,u_int32_t)) set_last_replied_message_id;
this->protected.get_child_sa = (child_sa_t* (*)(protected_ike_sa_t*,u_int32_t))get_child_sa_by_spi; this->protected.destroy_child_sa = (u_int32_t (*) (protected_ike_sa_t*,u_int32_t))destroy_child_sa;
this->protected.set_my_host_behind_nat = (void(*)(protected_ike_sa_t*, bool)) set_my_host_behind_nat; this->protected.get_child_sa = (child_sa_t* (*) (protected_ike_sa_t*,u_int32_t))get_child_sa_by_spi;
this->protected.set_other_host_behind_nat = (void(*)(protected_ike_sa_t*, bool)) set_other_host_behind_nat; this->protected.set_my_host_behind_nat = (void (*) (protected_ike_sa_t*,bool)) set_my_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.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.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 */ /* private functions */
this->update_timestamp = (void (*) (private_ike_sa_t*,bool))update_timestamp; 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 */ /* initialize private fields */
this->logger = logger_manager->get_logger(logger_manager, IKE_SA); 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 = NULL;
this->prf_auth_i = NULL; this->prf_auth_i = NULL;
this->prf_auth_r = NULL; this->prf_auth_r = NULL;
this->child_prf = NULL; this->child_prf = NULL;
this->connection = NULL; this->connection = NULL;
this->policy = NULL; this->policy = NULL;
this->nat_hasher = hasher_create(HASH_SHA1); 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 */ /* at creation time, IKE_SA is in a initiator state */
if (ike_sa_id->is_initiator(ike_sa_id)) 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)); this->current_state = (state_t *) initiator_init_create(&(this->protected));
} }
else 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)); this->current_state = (state_t *) responder_init_create(&(this->protected));
} }
return &(this->protected.public); return &(this->protected.public);
+8 -1
View File
@@ -539,7 +539,14 @@ struct protected_ike_sa_t {
* @return child_sa, or NULL if none found * @return child_sa, or NULL if none found
*/ */
child_sa_t* (*get_child_sa) (protected_ike_sa_t *this, u_int32_t spi); 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. * @brief Get the last responded message.
* *
+73 -50
View File
@@ -29,6 +29,7 @@
#include <encoding/payloads/ts_payload.h> #include <encoding/payloads/ts_payload.h>
#include <encoding/payloads/sa_payload.h> #include <encoding/payloads/sa_payload.h>
#include <encoding/payloads/id_payload.h> #include <encoding/payloads/id_payload.h>
#include <encoding/payloads/cert_payload.h>
#include <encoding/payloads/auth_payload.h> #include <encoding/payloads/auth_payload.h>
#include <encoding/payloads/notify_payload.h> #include <encoding/payloads/notify_payload.h>
#include <crypto/signers/signer.h> #include <crypto/signers/signer.h>
@@ -112,6 +113,17 @@ struct private_ike_auth_requested_t {
*/ */
status_t (*process_idr_payload) (private_ike_auth_requested_t *this, id_payload_t *idr_payload); 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) * Process the SA payload (check if selected proposals are valid, setup child sa)
* *
@@ -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) 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; id_payload_t *idr_payload = NULL;
cert_payload_t *cert_payload = NULL;
auth_payload_t *auth_payload = NULL; auth_payload_t *auth_payload = NULL;
sa_payload_t *sa_payload = NULL; sa_payload_t *sa_payload = NULL;
iterator_t *payloads = 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) 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))); mapping_find(exchange_type_m,ike_auth_reply->get_exchange_type(ike_auth_reply)));
return FAILED; 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)) switch (payload->get_type(payload))
{ {
case AUTHENTICATION: case AUTHENTICATION:
{
auth_payload = (auth_payload_t*)payload; auth_payload = (auth_payload_t*)payload;
break; 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: case ID_RESPONDER:
{
idr_payload = (id_payload_t*)payload; idr_payload = (id_payload_t*)payload;
break; break;
}
case SECURITY_ASSOCIATION: case SECURITY_ASSOCIATION:
{
sa_payload = (sa_payload_t*)payload; sa_payload = (sa_payload_t*)payload;
break; break;
}
case TRAFFIC_SELECTOR_INITIATOR: case TRAFFIC_SELECTOR_INITIATOR:
{
tsi_payload = (ts_payload_t*)payload; tsi_payload = (ts_payload_t*)payload;
break; break;
}
case TRAFFIC_SELECTOR_RESPONDER: case TRAFFIC_SELECTOR_RESPONDER:
{
tsr_payload = (ts_payload_t*)payload; tsr_payload = (ts_payload_t*)payload;
break; break;
}
case NOTIFY: case NOTIFY:
{ {
notify_payload_t *notify_payload = (notify_payload_t *) payload; notify_payload_t *notify_payload = (notify_payload_t *) payload;
/* handle the notify directly, abort if no further processing required */ /* handle the notify directly, abort if no further processing required */
status = this->process_notify_payload(this, notify_payload); status = this->process_notify_payload(this, notify_payload);
if (status != SUCCESS) if (status != SUCCESS)
@@ -265,16 +280,10 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i
return status; return status;
} }
} }
case CERTIFICATE:
{
/* TODO handle cert payloads */
}
default: 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)); mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
break; break;
}
} }
} }
/* iterator can be destroyed */ /* 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_destination(ike_auth_reply),
ike_auth_reply->get_source(ike_auth_reply)); ike_auth_reply->get_source(ike_auth_reply));
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
/* process all payloads */ /* process all payloads */
status = this->process_idr_payload(this, idr_payload); status = this->process_idr_payload(this, idr_payload);
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
status = this->process_auth_payload(this, auth_payload,idr_payload); status = this->process_auth_payload(this, auth_payload,idr_payload);
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
status = this->process_sa_payload(this, sa_payload); status = this->process_sa_payload(this, sa_payload);
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
status = this->process_ts_payload(this, TRUE, tsi_payload); status = this->process_ts_payload(this, TRUE, tsi_payload);
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
status = this->process_ts_payload(this, FALSE, tsr_payload); status = this->process_ts_payload(this, FALSE, tsr_payload);
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
/* install child SAs for AH and esp */ /* install child SAs for AH and esp */
if (!this->child_sa) 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) 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->destroy(this->child_sa);
this->child_sa = NULL; this->child_sa = NULL;
} }
else if (this->my_ts->get_count(this->my_ts) == 0 || this->other_ts->get_count(this->other_ts) == 0) 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->destroy(this->child_sa);
this->child_sa = NULL; 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); prf_plus->destroy(prf_plus);
if (status != SUCCESS) 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; return DESTROY_ME;
} }
status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts); status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts);
if (status != SUCCESS) 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; return DESTROY_ME;
} }
this->ike_sa->add_child_sa(this->ike_sa, this->child_sa); 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)); this->ike_sa->set_last_replied_message_id(this->ike_sa,ike_auth_reply->get_message_id(ike_auth_reply));
/* create new state */ /* 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); 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; return SUCCESS;
} }
@@ -407,6 +397,38 @@ static status_t process_idr_payload(private_ike_auth_requested_t *this, id_paylo
return SUCCESS; return SUCCESS;
} }
/**
* 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 * Implements private_ike_auth_requested_t.process_sa_payload
*/ */
@@ -472,7 +494,7 @@ static status_t process_auth_payload(private_ike_auth_requested_t *this, auth_pa
authenticator->destroy(authenticator); authenticator->destroy(authenticator);
if (status != SUCCESS) 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; 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); 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)); mapping_find(notify_message_type_m, notify_message_type));
switch (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 */ /* private functions */
this->process_idr_payload = process_idr_payload; this->process_idr_payload = process_idr_payload;
this->process_cert_payload = process_cert_payload;
this->process_sa_payload = process_sa_payload; this->process_sa_payload = process_sa_payload;
this->process_auth_payload = process_auth_payload; this->process_auth_payload = process_auth_payload;
this->process_ts_payload = process_ts_payload; this->process_ts_payload = process_ts_payload;
+14 -14
View File
@@ -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 */ /* get proposals from request, and select one with ours */
policy = this->ike_sa->get_policy(this->ike_sa); policy = this->ike_sa->get_policy(this->ike_sa);
proposal_list = request->get_proposals(request); 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); proposal = policy->select_proposal(policy, proposal_list);
/* list is not needed anymore */ /* list is not needed anymore */
while (proposal_list->remove_last(proposal_list, (void**)&proposal_tmp) == SUCCESS) 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.ptr, this->nonce_i.len);
memcpy(seed.ptr + this->nonce_i.len, this->nonce_r.ptr, this->nonce_r.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); 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(&seed);
chunk_free(&this->nonce_i); chunk_free(&this->nonce_i);
chunk_free(&this->nonce_r); 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); prf_plus->destroy(prf_plus);
if (status != SUCCESS) 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); sa_response->destroy(sa_response);
proposal->destroy(proposal); proposal->destroy(proposal);
return DESTROY_ME; return DESTROY_ME;
@@ -322,7 +322,7 @@ static status_t process_create_child_sa(private_ike_sa_established_t *this, mess
} }
default: 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)); mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
break; 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); u_int32_t spi = notify->get_spi(notify);
this->old_child_sa = this->ike_sa->get_child_sa(this->ike_sa, spi); 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 else
{ {
this->logger->log(this->logger, CONTROL, "Create new CHILD_SA"); this->logger->log(this->logger, CONTROL, "create new CHILD_SA");
} }
/* build response */ /* 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) */ /* message can now be sent (must not be destroyed) */
if (status != SUCCESS) 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); response->destroy(response);
return FAILED; return FAILED;
} }
@@ -390,11 +390,11 @@ static status_t process_create_child_sa(private_ike_sa_established_t *this, mess
/* install child SA policies */ /* install child SA policies */
if (!this->child_sa) 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) 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->destroy(this->child_sa);
this->child_sa = NULL; 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); status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts);
if (status != SUCCESS) 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) if (this->old_child_sa)
{ /* mark old child sa as rekeyed */ { /* mark old child sa as rekeyed */
@@ -443,7 +443,7 @@ static status_t process_informational(private_ike_sa_established_t *this, messag
} }
default: 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)), mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload)); payload->get_type(payload));
break; 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) if (this->ike_sa->send_response(this->ike_sa, response) != SUCCESS)
{ {
/* something is seriously wrong, kill connection */ /* 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); response->destroy(response);
return DESTROY_ME; return DESTROY_ME;
} }
@@ -529,7 +529,7 @@ static status_t process_informational_response(private_ike_sa_established_t *thi
{ {
default: 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)), mapping_find(payload_type_m, payload->get_type(payload)),
payload->get_type(payload)); payload->get_type(payload));
break; break;
@@ -619,7 +619,7 @@ static status_t process_message(private_ike_sa_established_t *this, message_t *m
break; break;
default: default:
this->logger->log(this->logger, ERROR | LEVEL1, 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))); mapping_find(exchange_type_m, message->get_exchange_type(message)));
status = NOT_SUPPORTED; status = NOT_SUPPORTED;
} }
+155 -112
View File
@@ -29,6 +29,8 @@
#include <encoding/payloads/nonce_payload.h> #include <encoding/payloads/nonce_payload.h>
#include <encoding/payloads/notify_payload.h> #include <encoding/payloads/notify_payload.h>
#include <encoding/payloads/id_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/auth_payload.h>
#include <encoding/payloads/ts_payload.h> #include <encoding/payloads/ts_payload.h>
#include <crypto/diffie_hellman.h> #include <crypto/diffie_hellman.h>
@@ -158,12 +160,34 @@ struct private_ike_sa_init_requested_t {
* *
* @param this calling object * @param this calling object
* @param[out] id_payload buildet ID payload * @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 * @return
* - SUCCESS * - SUCCESS
* - FAILED * - 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. * 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. * Only built when the ID of the responder contains no wildcards.
* *
* @param this calling object * @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 * @return
* - SUCCESS * - SUCCESS
* - FAILED * - 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. * Build AUTH payload for IKE_AUTH request.
* *
* @param this calling object * @param this calling object
* @param my_id_payload buildet ID payload * @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 * @return
* - SUCCESS * - SUCCESS
* - FAILED * - 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. * Build SA payload for IKE_AUTH request.
* *
* @param this calling object * @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 * @return
* - SUCCESS * - SUCCESS
* - FAILED * - 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. * Build TSi payload for IKE_AUTH request.
* *
* @param this calling object * @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 * @return
* - SUCCESS * - SUCCESS
* - FAILED * - 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. * Build TSr payload for IKE_AUTH request.
* *
* @param this calling object * @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 * @return
* - SUCCESS * - SUCCESS
* - FAILED * - 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. * 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) 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))); mapping_find(exchange_type_m,ike_sa_init_reply->get_exchange_type(ike_sa_init_reply)));
return FAILED; 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)) switch (payload->get_type(payload))
{ {
case SECURITY_ASSOCIATION: case SECURITY_ASSOCIATION:
{
sa_payload = (sa_payload_t*)payload; sa_payload = (sa_payload_t*)payload;
break; break;
}
case KEY_EXCHANGE: case KEY_EXCHANGE:
{
ke_payload = (ke_payload_t*)payload; ke_payload = (ke_payload_t*)payload;
break; break;
}
case NONCE: case NONCE:
{
nonce_payload = (nonce_payload_t*)payload; nonce_payload = (nonce_payload_t*)payload;
break; break;
}
case NOTIFY: case NOTIFY:
{ {
notify_payload_t *notify_payload = (notify_payload_t *) payload; 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; break;
} }
default: 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)); mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
break; 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); status = this->process_nonce_payload (this,nonce_payload);
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
status = this->process_sa_payload (this,sa_payload); status = this->process_sa_payload (this,sa_payload);
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
status = this->process_ke_payload (this,ke_payload); status = this->process_ke_payload (this,ke_payload);
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
/* derive all the keys used in the IKE_SA */ /* 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); status = this->ike_sa->build_transforms(this->ike_sa, this->proposal, this->diffie_hellman, this->sent_nonce, this->received_nonce);
if (status != SUCCESS) 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; 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) 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) 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); this->ike_sa->set_other_host_behind_nat(this->ike_sa, TRUE);
} }
if (this->natd_seen_r > 0 && !this->natd_hash_r_matched) 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); 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); me->set_port(me, IKEV2_NATT_PORT);
other->set_port(other, 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 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)) 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); status = this->ike_sa->update_connection_hosts(this->ike_sa, me, other);
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
policy = this->ike_sa->get_policy(this->ike_sa); policy = this->ike_sa->get_policy(this->ike_sa);
policy->update_my_ts(policy, me); 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); status = this->build_id_payload(this, &id_payload, request);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_request;
request->destroy(request);
return status; 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); status = this->build_idr_payload(this, request);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_request;
request->destroy(request);
return status;
}
status = this->build_auth_payload(this, (id_payload_t*)id_payload, request); status = this->build_auth_payload(this, (id_payload_t*)id_payload, request);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_request;
request->destroy(request);
return status;
}
status = this->build_sa_payload(this, request); status = this->build_sa_payload(this, request);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_request;
request->destroy(request);
return status;
}
status = this->build_tsi_payload(this, request); status = this->build_tsi_payload(this, request);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_request;
request->destroy(request);
return status;
}
status = this->build_tsr_payload(this, request); status = this->build_tsr_payload(this, request);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_request;
request->destroy(request);
return status;
}
/* message can now be sent (must not be destroyed) */ /* message can now be sent (must not be destroyed) */
status = this->ike_sa->send_request(this->ike_sa, request); status = this->ike_sa->send_request(this->ike_sa, request);
if (status != SUCCESS) 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); request->destroy(request);
return DESTROY_ME; 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); this->destroy_after_state_change(this);
return SUCCESS; return SUCCESS;
destroy_request:
request->destroy(request);
return status;
} }
@@ -590,41 +597,83 @@ 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. * 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; policy_t *policy;
identification_t *my_id;
id_payload_t *new_id_payload; id_payload_t *new_id_payload;
identification_t *identification;
policy = this->ike_sa->get_policy(this->ike_sa); policy = this->ike_sa->get_policy(this->ike_sa);
identification = policy->get_my_id(policy); my_id = policy->get_my_id(policy);
new_id_payload = id_payload_create_from_identification(TRUE, identification); new_id_payload = id_payload_create_from_identification(TRUE, my_id);
this->logger->log(this->logger, CONTROL|LEVEL2, "Add ID payload to message"); this->logger->log(this->logger, CONTROL|LEVEL2, "add ID payload to message");
request->add_payload(request,(payload_t *) new_id_payload); msg->add_payload(msg, (payload_t *) new_id_payload);
*id_payload = new_id_payload; *id_payload = new_id_payload;
return SUCCESS; return SUCCESS;
} }
/**
* 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. * 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; policy_t *policy = this->ike_sa->get_policy(this->ike_sa);
id_payload_t *idr_payload; identification_t *identification = policy->get_other_id(policy);
identification_t *identification;
policy = this->ike_sa->get_policy(this->ike_sa);
identification = policy->get_other_id(policy);
if (!identification->contains_wildcards(identification)) 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"); this->logger->log(this->logger, CONTROL|LEVEL2, "add IDr payload to message");
request->add_payload(request,(payload_t *) idr_payload); msg->add_payload(msg, (payload_t *) idr_payload);
} }
return SUCCESS; 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. * 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; authenticator_t *authenticator;
auth_payload_t *auth_payload; 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) 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; return DESTROY_ME;
} }
this->logger->log(this->logger, CONTROL|LEVEL2, "Add AUTH payload to message"); this->logger->log(this->logger, CONTROL|LEVEL2, "add AUTH payload to message");
request->add_payload(request,(payload_t *) auth_payload); msg->add_payload(msg, (payload_t *) auth_payload);
return SUCCESS; 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. * 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; linked_list_t *proposal_list;
sa_payload_t *sa_payload; 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)); this->ike_sa->public.is_any_host_behind_nat(&this->ike_sa->public));
if (this->child_sa->alloc(this->child_sa, proposal_list) != SUCCESS) 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; return DESTROY_ME;
} }
sa_payload = sa_payload_create_from_proposal_list(proposal_list); sa_payload = sa_payload_create_from_proposal_list(proposal_list);
this->logger->log(this->logger, CONTROL|LEVEL2, "Add SA payload to message"); 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);
return SUCCESS; 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. * 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; policy_t *policy = this->ike_sa->get_policy(this->ike_sa);
ts_payload_t *ts_payload; linked_list_t *ts_list = policy->get_my_traffic_selectors(policy);
policy_t *policy; ts_payload_t *ts_payload = ts_payload_create_from_traffic_selectors(TRUE, ts_list);
policy = this->ike_sa->get_policy(this->ike_sa); this->logger->log(this->logger, CONTROL|LEVEL2, "add TSi payload to message");
ts_list = policy->get_my_traffic_selectors(policy); msg->add_payload(msg, (payload_t *) ts_payload);
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);
return SUCCESS; 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. * 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; policy_t *policy = this->ike_sa->get_policy(this->ike_sa);
ts_payload_t *ts_payload; linked_list_t *ts_list = policy->get_other_traffic_selectors(policy);
policy_t *policy; ts_payload_t *ts_payload = ts_payload_create_from_traffic_selectors(FALSE, ts_list);
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);
this->logger->log(this->logger, CONTROL|LEVEL2, "Add TSr payload to message"); this->logger->log(this->logger, CONTROL|LEVEL2, "add TSr payload to message");
request->add_payload(request,(payload_t *) ts_payload); msg->add_payload(msg, (payload_t *) ts_payload);
return SUCCESS; return SUCCESS;
} }
@@ -735,7 +776,7 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no
chunk_t notification_data; chunk_t notification_data;
notify_message_type_t notify_message_type = notify_payload->get_notify_message_type(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)); mapping_find(notify_message_type_m, notify_message_type));
switch (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... * 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, old_dh_group),
mapping_find(diffie_hellman_group_m, dh_group)); mapping_find(diffie_hellman_group_m, dh_group));
/* check if we can accept this dh group */ /* check if we can accept this dh group */
if (!connection->check_dh_group(connection, dh_group)) if (!connection->check_dh_group(connection, dh_group))
{ {
this->logger->log(this->logger, AUDIT, 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)); mapping_find(diffie_hellman_group_m, dh_group));
return DESTROY_ME; return DESTROY_ME;
} }
/* Going to change state back to initiator_init_t */ /* 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); initiator_init_state = initiator_init_create(this->ike_sa);
/* buffer of sent and received messages has to get reseted */ /* 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); this->ike_sa->set_new_state(this->ike_sa,(state_t *) initiator_init_state);
/* state has NOW changed :-) */ /* state has NOW changed :-) */
this->logger->log(this->logger, CONTROL|LEVEL2, "Destroy old sate object"); 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, "going to retry initialization of connection");
this->public.state_interface.destroy(&(this->public.state_interface)); this->public.state_interface.destroy(&(this->public.state_interface));
if (initiator_init_state->retry_initiate_connection (initiator_init_state, dh_group) != SUCCESS) 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_tsr_payload = build_tsr_payload;
this->build_id_payload = build_id_payload; this->build_id_payload = build_id_payload;
this->build_idr_payload = build_idr_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->build_sa_payload = build_sa_payload;
this->process_notify_payload = process_notify_payload; this->process_notify_payload = process_notify_payload;
+186 -119
View File
@@ -31,6 +31,7 @@
#include <encoding/payloads/ts_payload.h> #include <encoding/payloads/ts_payload.h>
#include <encoding/payloads/sa_payload.h> #include <encoding/payloads/sa_payload.h>
#include <encoding/payloads/id_payload.h> #include <encoding/payloads/id_payload.h>
#include <encoding/payloads/cert_payload.h>
#include <encoding/payloads/auth_payload.h> #include <encoding/payloads/auth_payload.h>
#include <encoding/payloads/notify_payload.h> #include <encoding/payloads/notify_payload.h>
#include <crypto/signers/signer.h> #include <crypto/signers/signer.h>
@@ -108,23 +109,22 @@ struct private_ike_sa_init_responded_t {
* @param this calling object * @param this calling object
* @param request_idi ID payload representing initiator * @param request_idi ID payload representing initiator
* @param request_idr ID payload representing responder (May be zero) * @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 * @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, status_t (*build_idr_payload) (private_ike_sa_init_responded_t *this,
id_payload_t *request_idi, id_payload_t *request_idi,
id_payload_t *request_idr, id_payload_t *request_idr,
message_t *response, message_t *msg,
id_payload_t **response_idr); 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 this calling object
* @param request SA payload received in IKE_AUTH request * @param msg The created CERT payload is added to this message_t object
* @param response 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 *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. * 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 request AUTH payload received in IKE_AUTH request
* @param other_id_payload other ID payload needed to verify AUTH data * @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 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. * Process received TS payload and build TS payload for IKE_AUTH response.
* *
* @param this calling object * @param this calling object
* @param is_initiator type of TS payload. TRUE for TSi, FALSE for TSr * @param is_initiator type of TS payload. TRUE for TSi, FALSE for TSr
* @param request TS payload received in IKE_AUTH request * @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. * 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 * @param notify_payload payload to process
* @return * @return
* - DESTROY_ME if IKE_SA should be deleted * - 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); 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) 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; id_payload_t *idi_request = NULL;
ts_payload_t *tsi_request = NULL, *tsr_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; auth_payload_t *auth_request = NULL;
sa_payload_t *sa_request = NULL; sa_payload_t *sa_request = NULL;
cert_payload_t *cert_request = NULL;
iterator_t *payloads; iterator_t *payloads;
message_t *response; message_t *response;
crypter_t *crypter; 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) 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))); mapping_find(exchange_type_m,request->get_exchange_type(request)));
return FAILED; 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)) switch (payload->get_type(payload))
{ {
case ID_INITIATOR: case ID_INITIATOR:
{
idi_request = (id_payload_t*)payload; idi_request = (id_payload_t*)payload;
break; 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: case AUTHENTICATION:
{
auth_request = (auth_payload_t*)payload; auth_request = (auth_payload_t*)payload;
break; break;
}
case ID_RESPONDER: case ID_RESPONDER:
{
idr_request = (id_payload_t*)payload; idr_request = (id_payload_t*)payload;
break; break;
}
case SECURITY_ASSOCIATION: case SECURITY_ASSOCIATION:
{
sa_request = (sa_payload_t*)payload; sa_request = (sa_payload_t*)payload;
break; break;
}
case TRAFFIC_SELECTOR_INITIATOR: case TRAFFIC_SELECTOR_INITIATOR:
{
tsi_request = (ts_payload_t*)payload; tsi_request = (ts_payload_t*)payload;
break; break;
}
case TRAFFIC_SELECTOR_RESPONDER: case TRAFFIC_SELECTOR_RESPONDER:
{
tsr_request = (ts_payload_t*)payload; tsr_request = (ts_payload_t*)payload;
break; break;
}
case NOTIFY: case NOTIFY:
{ {
notify_payload_t *notify_payload = (notify_payload_t *) payload; 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; return status;
} }
} }
case CERTIFICATE:
{
/* TODO handle cert payloads */
}
case CERTIFICATE_REQUEST: case CERTIFICATE_REQUEST:
{ {
/* TODO handle certrequest payloads */ /* TODO handle certrequest payloads */
} }
default: 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)); mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
break; break;
}
} }
} }
/* iterator can be destroyed */ /* 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, status = this->ike_sa->update_connection_hosts(this->ike_sa,
request->get_destination(request), request->get_source(request)); request->get_destination(request), request->get_source(request));
if (status != SUCCESS) if (status != SUCCESS)
{
return status; return status;
}
/* build response */ /* build response */
this->ike_sa->build_message(this->ike_sa, IKE_AUTH, FALSE, &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 */ /* add payloads to it */
status = this->build_idr_payload(this, idi_request, idr_request, response, &idr_response); status = this->build_idr_payload(this, idi_request, idr_request, response, &idr_response);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_response;
response->destroy(response);
return status; 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); status = this->build_auth_payload(this, auth_request,idi_request, idr_response,response);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_response;
response->destroy(response);
return status;
}
status = this->build_sa_payload(this, sa_request, response); status = this->build_sa_payload(this, sa_request, response);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_response;
response->destroy(response);
return status;
}
status = this->build_ts_payload(this, TRUE, tsi_request, response); status = this->build_ts_payload(this, TRUE, tsi_request, response);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_response;
response->destroy(response);
return status;
}
status = this->build_ts_payload(this, FALSE, tsr_request, response); status = this->build_ts_payload(this, FALSE, tsr_request, response);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_response;
response->destroy(response);
return status;
}
status = this->ike_sa->send_response(this->ike_sa, response); status = this->ike_sa->send_response(this->ike_sa, response);
/* message can now be sent (must not be destroyed) */ /* message can now be sent (must not be destroyed) */
if (status != SUCCESS) 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); response->destroy(response);
return DESTROY_ME; 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 */ /* install child SA policies */
if (!this->child_sa) 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) 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->destroy(this->child_sa);
this->child_sa = NULL; 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); status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts);
if (status != SUCCESS) 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; return DESTROY_ME;
} }
this->ike_sa->add_child_sa(this->ike_sa, this->child_sa); this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
} }
/* create new state */ /* 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); 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; return SUCCESS;
destroy_response:
response->destroy(response);
return status;
} }
/** /**
* Implementation of private_ike_sa_init_responded_t.build_idr_payload. * 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; identification_t *other_id, *my_id;
id_payload_t *idr_response; 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); this->policy = charon->policies->get_policy_by_ids(charon->policies, my_id, other_id);
if (this->policy == NULL) 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->get_string(my_id), other_id->get_string(other_id));
my_id->destroy(my_id); my_id->destroy(my_id);
other_id->destroy(other_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); my_id = this->policy->get_my_id(this->policy);
/* update others traffic selectors with actually used address */ /* update others traffic selectors with actually used address */
this->policy->update_my_ts(this->policy, response->get_source(response)); this->policy->update_my_ts(this->policy, msg->get_source(msg));
this->policy->update_other_ts(this->policy, response->get_destination(response)); this->policy->update_other_ts(this->policy, msg->get_destination(msg));
/* set policy in ike_sa for other states */ /* set policy in ike_sa for other states */
this->ike_sa->set_policy(this->ike_sa, this->policy); this->ike_sa->set_policy(this->ike_sa, this->policy);
/* build response */ /* build response */
idr_response = id_payload_create_from_identification(FALSE, my_id); 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; *response_idr = idr_response;
return SUCCESS; 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. * 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; proposal_t *proposal, *proposal_tmp;
linked_list_t *proposal_list; 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 */ /* get proposals from request, and select one with ours */
proposal_list = request->get_proposals(request); 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); proposal = this->policy->select_proposal(this->policy, proposal_list);
/* list is not needed anymore */ /* list is not needed anymore */
while (proposal_list->remove_last(proposal_list, (void**)&proposal_tmp) == SUCCESS) 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"); "Adding NO_PROPOSAL_CHOSEN notify");
/* add NO_PROPOSAL_CHOSEN and an empty SA payload */ /* add NO_PROPOSAL_CHOSEN and an empty SA payload */
notify = notify_payload_create_from_protocol_and_type(PROTO_IKE, NO_PROPOSAL_CHOSEN); 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 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); prf_plus->destroy(prf_plus);
if (status != SUCCESS) 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? */ /* TODO: how do we handle this cleanly? */
sa_response->destroy(sa_response); sa_response->destroy(sa_response);
proposal->destroy(proposal); 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); sa_response->add_proposal(sa_response, proposal);
proposal->destroy(proposal); proposal->destroy(proposal);
} }
response->add_payload(response, (payload_t*)sa_response); msg->add_payload(msg, (payload_t*)sa_response);
return SUCCESS; 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. * 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; linked_list_t *ts_received, *ts_selected;
traffic_selector_t *ts; 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); 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 */ /* add notify if traffic selectors do not match */
if (!ts_initiator && 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"); "Adding TS_UNACCEPTABLE notify");
notify = notify_payload_create_from_protocol_and_type(0, TS_UNACCEPTABLE); 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 */ /* cleanup */
@@ -595,11 +626,45 @@ static status_t build_ts_payload(private_ike_sa_init_responded_t *this, bool ts_
return status; 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) 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); 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)); mapping_find(notify_message_type_m, notify_message_type));
switch (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 */ /* private functions */
this->build_idr_payload = build_idr_payload; 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_auth_payload = build_auth_payload;
this->build_sa_payload = build_sa_payload;
this->build_ts_payload = build_ts_payload; this->build_ts_payload = build_ts_payload;
this->process_cert_payload = process_cert_payload;
this->process_notify_payload = process_notify_payload; this->process_notify_payload = process_notify_payload;
this->destroy_after_state_change = destroy_after_state_change; this->destroy_after_state_change = destroy_after_state_change;
+26 -26
View File
@@ -75,43 +75,43 @@ struct private_initiator_init_t {
* Builds the SA payload for this state. * Builds the SA payload for this state.
* *
* @param this calling object * @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. * Builds the KE payload for this state.
* *
* @param this calling object * @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. * Builds the NONCE payload for this state.
* *
* @param this calling object * @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 * Builds the NAT-T Notify(NAT_DETECTION_SOURCE_IP) and
* Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state. * Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state.
* *
* @param this calling object * @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 * Builds the NAT-T Notify(NAT_DETECTION_SOURCE_IP) and
* Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state. * Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state.
* *
* @param this calling object * @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 * 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. * 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; sa_payload_t* sa_payload;
linked_list_t *proposal_list; 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); sa_payload = sa_payload_create_from_proposal_list(proposal_list);
this->logger->log(this->logger, CONTROL|LEVEL2, "add SA payload to message"); 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. * 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; ke_payload_t *ke_payload;
chunk_t key_data; 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); chunk_free(&key_data);
this->logger->log(this->logger, CONTROL|LEVEL2, "add KE payload to message"); 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. * 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; nonce_payload_t *nonce_payload;
randomizer_t *randomizer; 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); nonce_payload->set_nonce(nonce_payload, this->sent_nonce);
this->logger->log(this->logger, CONTROL|LEVEL2, "add NONCE payload to message"); 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; return SUCCESS;
} }
/** /**
* Implementation of private_initiator_init_t.build_natd_payload. * 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; 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_t *notify_payload;
notify_payload = notify_payload_create(); notify_payload = notify_payload_create();
/*notify_payload->set_protocol_id(notify_payload, NULL);*/ /*notify_payload->set_protocol_id(notify_payload, NULL);*/
/*notify_payload->set_spi(notify_payload, NULL);*/ /*notify_payload->set_spi(notify_payload, NULL);*/
notify_payload->set_notify_message_type(notify_payload, type); notify_payload->set_notify_message_type(notify_payload, type);
hash = this->ike_sa->generate_natd_hash(this->ike_sa, hash = this->ike_sa->generate_natd_hash(this->ike_sa,
request->get_initiator_spi(request), msg->get_initiator_spi(msg),
request->get_responder_spi(request), msg->get_responder_spi(msg),
host); host);
notify_payload->set_notification_data(notify_payload, hash); notify_payload->set_notification_data(notify_payload, hash);
chunk_free(&hash); chunk_free(&hash);
this->logger->log(this->logger, CONTROL|LEVEL2, "Add Notify(NAT-D) payload to message"); this->logger->log(this->logger, CONTROL|LEVEL2, "add Notify(NAT-D) payload to message");
request->add_payload(request, (payload_t *) notify_payload); msg->add_payload(msg, (payload_t *) notify_payload);
} }
/** /**
* Implementation of private_initiator_init_t.build_natd_payloads. * 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; connection_t *connection;
linked_list_t *hostlist; 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); hostlist = charon->interfaces->get_addresses(charon->interfaces);
hostiter = hostlist->create_iterator(hostlist, TRUE); hostiter = hostlist->create_iterator(hostlist, TRUE);
while(hostiter->iterate(hostiter, (void**)&host)) { 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); host);
} }
hostiter->destroy(hostiter); 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) * N(NAT_DETECTION_DESTINATION_IP)
*/ */
connection = this->ike_sa->get_connection(this->ike_sa); 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)); connection->get_other_host(connection));
} }
+75 -45
View File
@@ -29,6 +29,7 @@
#include <encoding/payloads/sa_payload.h> #include <encoding/payloads/sa_payload.h>
#include <encoding/payloads/ke_payload.h> #include <encoding/payloads/ke_payload.h>
#include <encoding/payloads/nonce_payload.h> #include <encoding/payloads/nonce_payload.h>
#include <encoding/payloads/certreq_payload.h>
#include <encoding/payloads/notify_payload.h> #include <encoding/payloads/notify_payload.h>
#include <crypto/diffie_hellman.h> #include <crypto/diffie_hellman.h>
#include <queues/jobs/send_keepalive_job.h> #include <queues/jobs/send_keepalive_job.h>
@@ -128,52 +129,66 @@ struct private_responder_init_t {
* *
* @param this calling object * @param this calling object
* @param sa_request The received SA payload * @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 * @return
* - DESTROY_ME * - DESTROY_ME
* - SUCCESS * - 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. * 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 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 * - DESTROY_ME
* - SUCCESS * - 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. * Handles received NONCE payload and builds the NONCE payload for the response.
* *
* @param this calling object * @param this calling object
* @param nonce_request The received NONCE payload * @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 * - DESTROY_ME
* - SUCCESS * - 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 * Builds the NAT-T Notify(NAT_DETECTION_SOURCE_IP) and
* Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state. * Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state.
* *
* @param this calling object * @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 * Builds the NAT-T Notify(NAT_DETECTION_SOURCE_IP) and
* Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state. * Notify(NAT_DETECTION_DESTINATION_IP) payloads for this state.
* *
* @param this calling object * @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. * 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) 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) 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); this->ike_sa->set_other_host_behind_nat(this->ike_sa, TRUE);
} }
if (this->natd_seen_r > 0 && !this->natd_hash_r_matched) 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); this->ike_sa->set_my_host_behind_nat(this->ike_sa, TRUE);
charon->event_queue->add_relative(charon->event_queue, 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)), (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)) 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); this->ike_sa->build_message(this->ike_sa, IKE_SA_INIT, FALSE, &response);
status = this->build_sa_payload(this, sa_request, response); status = this->build_sa_payload(this, sa_request, response);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_response;
response->destroy(response);
return status;
}
status = this->build_ke_payload(this, ke_request, response); status = this->build_ke_payload(this, ke_request, response);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_response;
response->destroy(response);
return status;
}
status = this->build_nonce_payload(this, nonce_request, response); status = this->build_nonce_payload(this, nonce_request, response);
if (status != SUCCESS) if (status != SUCCESS)
{ goto destroy_response;
response->destroy(response);
return status; status = this->build_certreq_payload(this, response);
} if (status != SUCCESS)
goto destroy_response;
/* build Notify(NAT-D) payloads */ /* build Notify(NAT-D) payloads */
this->build_natd_payloads(this, response); 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 */ /* state can now be changed */
this->ike_sa->set_new_state(this->ike_sa, (state_t *) next_state); this->ike_sa->set_new_state(this->ike_sa, (state_t *) next_state);
this->destroy_after_state_change(this); this->destroy_after_state_change(this);
return SUCCESS; return SUCCESS;
destroy_response:
response->destroy(response);
return status;
} }
/** /**
* Implementation of private_initiator_init_t.build_sa_payload. * 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; proposal_t *proposal;
linked_list_t *proposal_list; 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"); this->logger->log(this->logger, CONTROL|LEVEL2, "building SA payload");
sa_payload = sa_payload_create_from_proposal(this->proposal); sa_payload = sa_payload_create_from_proposal(this->proposal);
this->logger->log(this->logger, CONTROL|LEVEL2, "add SA payload to message"); 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; 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. * 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; diffie_hellman_group_t group;
ke_payload_t *ke_payload; 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); chunk_free(&key_data);
this->logger->log(this->logger, CONTROL|LEVEL2, "add KE payload to message"); 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; 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. * 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; nonce_payload_t *nonce_payload;
randomizer_t *randomizer; 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); nonce_payload->set_nonce(nonce_payload, this->sent_nonce);
this->logger->log(this->logger, CONTROL|LEVEL2, "add NONCE payload to message"); 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; 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. * 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; 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_t *notify_payload;
notify_payload = notify_payload_create(); notify_payload = notify_payload_create();
/*notify_payload->set_protocol_id(notify_payload, NULL);*/ /*notify_payload->set_protocol_id(notify_payload, NULL);*/
/*notify_payload->set_spi(notify_payload, NULL);*/ /*notify_payload->set_spi(notify_payload, NULL);*/
notify_payload->set_notify_message_type(notify_payload, type); notify_payload->set_notify_message_type(notify_payload, type);
hash = this->ike_sa->generate_natd_hash(this->ike_sa, hash = this->ike_sa->generate_natd_hash(this->ike_sa,
request->get_initiator_spi(request), msg->get_initiator_spi(msg),
request->get_responder_spi(request), msg->get_responder_spi(msg),
host); host);
notify_payload->set_notification_data(notify_payload, hash); notify_payload->set_notification_data(notify_payload, hash);
chunk_free(&hash); chunk_free(&hash);
this->logger->log(this->logger, CONTROL|LEVEL2, "Add Notify(NAT-D) payload to message"); this->logger->log(this->logger, CONTROL|LEVEL2, "add Notify(NAT-D) payload to message");
request->add_payload(request, (payload_t *) notify_payload); msg->add_payload(msg, (payload_t *) notify_payload);
} }
/** /**
* Implementation of private_initiator_init_t.build_natd_payloads. * 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_t *connection;
connection = this->ike_sa->get_connection(this->ike_sa); 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)); 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)); 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_sa_payload = build_sa_payload;
this->build_ke_payload = build_ke_payload; this->build_ke_payload = build_ke_payload;
this->build_nonce_payload = build_nonce_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->destroy_after_state_change = destroy_after_state_change;
this->process_notify_payload = process_notify_payload; this->process_notify_payload = process_notify_payload;
this->build_natd_payload = build_natd_payload; this->build_natd_payload = build_natd_payload;
+2 -2
View File
@@ -996,7 +996,7 @@ void test_generator_with_cert_payload(protected_tester_t *tester)
cert.ptr = "123456789012"; cert.ptr = "123456789012";
cert.len = strlen(cert.ptr); cert.len = strlen(cert.ptr);
cert_payload->set_cert_encoding(cert_payload,PGP_CERTIFICATE); cert_payload->set_cert_encoding(cert_payload, CERT_PGP);
cert_payload->set_data(cert_payload,cert); cert_payload->set_data(cert_payload,cert);
generator->generate_payload(generator,(payload_t *)cert_payload); generator->generate_payload(generator,(payload_t *)cert_payload);
@@ -1046,7 +1046,7 @@ void test_generator_with_certreq_payload(protected_tester_t *tester)
certreq.ptr = "123456789012"; certreq.ptr = "123456789012";
certreq.len = strlen(certreq.ptr); certreq.len = strlen(certreq.ptr);
certreq_payload->set_cert_encoding(certreq_payload,PGP_CERTIFICATE); certreq_payload->set_cert_encoding(certreq_payload, CERT_PGP);
certreq_payload->set_data(certreq_payload,certreq); certreq_payload->set_data(certreq_payload,certreq);
generator->generate_payload(generator,(payload_t *)certreq_payload); generator->generate_payload(generator,(payload_t *)certreq_payload);
+3 -3
View File
@@ -727,7 +727,7 @@ void test_parser_with_cert_payload(protected_tester_t *tester)
return; return;
} }
result = cert_payload->get_data_clone(cert_payload); result = cert_payload->get_data_clone(cert_payload);
tester->assert_true(tester,(cert_payload->get_cert_encoding(cert_payload) == DNS_SIGNED_KEY), "is DNS_SIGNED_KEY encoding"); tester->assert_true(tester,(cert_payload->get_cert_encoding(cert_payload) == CERT_DNS_SIGNED_KEY), "is DNS_SIGNED_KEY encoding");
tester->assert_true(tester,(result.len == 12), "parsed data lenght"); tester->assert_true(tester,(result.len == 12), "parsed data lenght");
tester->assert_false(tester,(memcmp(cert_bytes + 5, result.ptr, result.len)), "parsed data"); tester->assert_false(tester,(memcmp(cert_bytes + 5, result.ptr, result.len)), "parsed data");
cert_payload->destroy(cert_payload); cert_payload->destroy(cert_payload);
@@ -766,8 +766,8 @@ void test_parser_with_certreq_payload(protected_tester_t *tester)
return; return;
} }
result = certreq_payload->get_data_clone(certreq_payload); result = certreq_payload->get_data_clone(certreq_payload);
tester->assert_true(tester,(certreq_payload->get_cert_encoding(certreq_payload) == DNS_SIGNED_KEY), "is DNS_SIGNED_KEY encoding"); tester->assert_true(tester,(certreq_payload->get_cert_encoding(certreq_payload) == CERT_DNS_SIGNED_KEY), "is DNS_SIGNED_KEY encoding");
tester->assert_true(tester,(result.len == 12), "parsed data lenght"); tester->assert_true(tester,(result.len == 12), "parsed data length");
tester->assert_false(tester,(memcmp(certreq_bytes + 5, result.ptr, result.len)), "parsed data"); tester->assert_false(tester,(memcmp(certreq_bytes + 5, result.ptr, result.len)), "parsed data");
certreq_payload->destroy(certreq_payload); certreq_payload->destroy(certreq_payload);
chunk_free(&result); chunk_free(&result);
-2
View File
@@ -177,7 +177,6 @@ void test_rsa(protected_tester_t *tester)
// free(signature.ptr); // free(signature.ptr);
// //
// private_key->destroy(private_key); // private_key->destroy(private_key);
// public_key->destroy(public_key);
/* key setting */ /* key setting */
private_key = rsa_private_key_create_from_chunk(der_private_key); private_key = rsa_private_key_create_from_chunk(der_private_key);
@@ -220,7 +219,6 @@ void test_rsa(protected_tester_t *tester)
free(signature.ptr); free(signature.ptr);
certificate->destroy(certificate); certificate->destroy(certificate);
public_key->destroy(public_key);
private_key->destroy(private_key); private_key->destroy(private_key);
} }
+33 -48
View File
@@ -134,9 +134,9 @@ static x509_t* load_end_certificate(const char *filename, identification_t **idp
if (cert) if (cert)
{ {
bool found;
identification_t *id = *idp; identification_t *id = *idp;
identification_t *subject = cert->get_subject(cert); identification_t *subject = cert->get_subject(cert);
time_t until;
err_t ugh = cert->is_valid(cert, NULL); err_t ugh = cert->is_valid(cert, NULL);
@@ -150,20 +150,6 @@ static x509_t* load_end_certificate(const char *filename, identification_t **idp
id = subject; id = subject;
*idp = id->clone(id); *idp = id->clone(id);
} }
/* test output */
if (charon->credentials->verify(charon->credentials, cert, &until))
{
char buf[TIMETOA_BUF];
timetoa(buf, TIMETOA_BUF, &until, TRUE);
logger->log(logger, CONTROL, " end entity certificate is trusted until %s", buf);
cert->set_until(cert, until);
}
else
{
logger->log(logger, ERROR, " end entity certificate is not trusted");
}
/* end of test output */
return charon->credentials->add_end_certificate(charon->credentials, cert); return charon->credentials->add_end_certificate(charon->credentials, cert);
} }
return NULL; return NULL;
@@ -196,6 +182,8 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
pop_string(msg, &msg->add_conn.other.cert); pop_string(msg, &msg->add_conn.other.cert);
pop_string(msg, &msg->add_conn.me.ca); pop_string(msg, &msg->add_conn.me.ca);
pop_string(msg, &msg->add_conn.other.ca); pop_string(msg, &msg->add_conn.other.ca);
pop_string(msg, &msg->add_conn.me.updown);
pop_string(msg, &msg->add_conn.other.updown);
pop_string(msg, &msg->add_conn.algorithms.ike); pop_string(msg, &msg->add_conn.algorithms.ike);
pop_string(msg, &msg->add_conn.algorithms.esp); pop_string(msg, &msg->add_conn.algorithms.esp);
@@ -236,10 +224,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
else if (!charon->interfaces->is_local_address(charon->interfaces, my_host)) else if (!charon->interfaces->is_local_address(charon->interfaces, my_host))
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, "left nor right host is our side, aborting"); this->stroke_logger->log(this->stroke_logger, ERROR, "left nor right host is our side, aborting");
goto destroy_hosts;
my_host->destroy(my_host);
other_host->destroy(other_host);
return;
} }
my_id = identification_create_from_string(msg->add_conn.me.id ? my_id = identification_create_from_string(msg->add_conn.me.id ?
@@ -247,45 +232,33 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
if (my_id == NULL) if (my_id == NULL)
{ {
this->stroke_logger->log(this->stroke_logger, ERROR, "invalid id: %s", msg->add_conn.me.id); this->stroke_logger->log(this->stroke_logger, ERROR, "invalid id: %s", msg->add_conn.me.id);
my_host->destroy(my_host); goto destroy_hosts;
other_host->destroy(other_host);
return;
} }
other_id = identification_create_from_string(msg->add_conn.other.id ? other_id = identification_create_from_string(msg->add_conn.other.id ?
msg->add_conn.other.id : msg->add_conn.other.address); msg->add_conn.other.id : msg->add_conn.other.address);
if (other_id == NULL) if (other_id == NULL)
{ {
my_host->destroy(my_host);
other_host->destroy(other_host);
my_id->destroy(my_id);
this->stroke_logger->log(this->stroke_logger, ERROR, "invalid id: %s", msg->add_conn.other.id); this->stroke_logger->log(this->stroke_logger, ERROR, "invalid id: %s", msg->add_conn.other.id);
return; my_id->destroy(my_id);
goto destroy_hosts;
} }
my_subnet = host_create(AF_INET, msg->add_conn.me.subnet ? my_subnet = host_create(AF_INET, msg->add_conn.me.subnet ?
msg->add_conn.me.subnet : msg->add_conn.me.address, IKE_PORT); msg->add_conn.me.subnet : msg->add_conn.me.address, IKE_PORT);
if (my_subnet == NULL) if (my_subnet == NULL)
{ {
my_host->destroy(my_host);
other_host->destroy(other_host);
my_id->destroy(my_id);
other_id->destroy(other_id);
this->stroke_logger->log(this->stroke_logger, ERROR, "invalid subnet: %s", msg->add_conn.me.subnet); this->stroke_logger->log(this->stroke_logger, ERROR, "invalid subnet: %s", msg->add_conn.me.subnet);
return; goto destroy_ids;
} }
other_subnet = host_create(AF_INET, msg->add_conn.other.subnet ? other_subnet = host_create(AF_INET, msg->add_conn.other.subnet ?
msg->add_conn.other.subnet : msg->add_conn.other.address, IKE_PORT); msg->add_conn.other.subnet : msg->add_conn.other.address, IKE_PORT);
if (other_subnet == NULL) if (other_subnet == NULL)
{ {
my_host->destroy(my_host);
other_host->destroy(other_host);
my_id->destroy(my_id);
other_id->destroy(other_id);
my_subnet->destroy(my_subnet);
this->stroke_logger->log(this->stroke_logger, ERROR, "invalid subnet: %s", msg->add_conn.me.subnet); this->stroke_logger->log(this->stroke_logger, ERROR, "invalid subnet: %s", msg->add_conn.me.subnet);
return; my_subnet->destroy(my_subnet);
goto destroy_ids;
} }
my_ts = traffic_selector_create_from_subnet(my_subnet, msg->add_conn.me.subnet ? my_ts = traffic_selector_create_from_subnet(my_subnet, msg->add_conn.me.subnet ?
@@ -358,23 +331,26 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
} }
this->logger->log(this->logger, CONTROL|LEVEL1, " my ca: '%s'", my_ca->get_string(my_ca)); this->logger->log(this->logger, CONTROL|LEVEL1, " my ca: '%s'", my_ca->get_string(my_ca));
this->logger->log(this->logger, CONTROL|LEVEL1, " other ca:'%s'", other_ca->get_string(other_ca)); this->logger->log(this->logger, CONTROL|LEVEL1, " other ca:'%s'", other_ca->get_string(other_ca));
this->logger->log(this->logger, CONTROL|LEVEL1, " updown:'%s'", msg->add_conn.me.updown);
connection = connection_create(msg->add_conn.name, msg->add_conn.ikev2, connection = connection_create(msg->add_conn.name,
msg->add_conn.me.sendcert, msg->add_conn.other.sendcert, msg->add_conn.ikev2,
msg->add_conn.me.sendcert,
msg->add_conn.other.sendcert,
my_host, other_host, my_host, other_host,
RSA_DIGITAL_SIGNATURE); RSA_DIGITAL_SIGNATURE
);
if (msg->add_conn.algorithms.ike) if (msg->add_conn.algorithms.ike)
{ {
char *proposal_string; char *proposal_string;
char *strict = msg->add_conn.algorithms.ike + strlen(msg->add_conn.algorithms.ike) - 1; char *strict = msg->add_conn.algorithms.ike + strlen(msg->add_conn.algorithms.ike) - 1;
if (*strict == '!') if (*strict == '!')
{
*strict = '\0'; *strict = '\0';
}
else else
{
strict = NULL; strict = NULL;
}
while ((proposal_string = strsep(&msg->add_conn.algorithms.ike, ","))) while ((proposal_string = strsep(&msg->add_conn.algorithms.ike, ",")))
{ {
proposal = proposal_create_from_string(PROTO_IKE, proposal_string); proposal = proposal_create_from_string(PROTO_IKE, proposal_string);
@@ -411,19 +387,17 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
policy->add_my_traffic_selector(policy, my_ts); policy->add_my_traffic_selector(policy, my_ts);
policy->add_other_traffic_selector(policy, other_ts); policy->add_other_traffic_selector(policy, other_ts);
policy->add_authorities(policy, my_ca, other_ca); policy->add_authorities(policy, my_ca, other_ca);
policy->add_updown(policy, msg->add_conn.me.updown);
if (msg->add_conn.algorithms.esp) if (msg->add_conn.algorithms.esp)
{ {
char *proposal_string; char *proposal_string;
char *strict = msg->add_conn.algorithms.esp + strlen(msg->add_conn.algorithms.esp) - 1; char *strict = msg->add_conn.algorithms.esp + strlen(msg->add_conn.algorithms.esp) - 1;
if (*strict == '!') if (*strict == '!')
{
*strict = '\0'; *strict = '\0';
}
else else
{
strict = NULL; strict = NULL;
}
while ((proposal_string = strsep(&msg->add_conn.algorithms.esp, ","))) while ((proposal_string = strsep(&msg->add_conn.algorithms.esp, ",")))
{ {
@@ -460,6 +434,17 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
other_id->get_string(other_id)); other_id->get_string(other_id));
/* add to global policy list */ /* add to global policy list */
charon->policies->add_policy(charon->policies, policy); charon->policies->add_policy(charon->policies, policy);
return;
/* mopping up after parsing errors */
destroy_ids:
my_id->destroy(my_id);
other_id->destroy(other_id);
destroy_hosts:
my_host->destroy(my_host);
other_host->destroy(other_host);
} }
/** /**
+4 -4
View File
@@ -149,10 +149,10 @@ enum ipsec_id_type {
* RFC 2408 ISAKMP, chapter 3.9 * RFC 2408 ISAKMP, chapter 3.9
*/ */
enum ipsec_cert_type { enum ipsec_cert_type {
CERT_NONE= 0, CERT_NONE= 0,
CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */ CERT_PKCS7_WRAPPED_X509= 1,
CERT_PGP= 2, CERT_PGP= 2,
CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */ CERT_DNS_SIGNED_KEY= 3,
CERT_X509_SIGNATURE= 4, CERT_X509_SIGNATURE= 4,
CERT_X509_KEY_EXCHANGE= 5, CERT_X509_KEY_EXCHANGE= 5,
CERT_KERBEROS_TOKENS= 6, CERT_KERBEROS_TOKENS= 6,
@@ -160,7 +160,7 @@ enum ipsec_cert_type {
CERT_ARL= 8, CERT_ARL= 8,
CERT_SPKI= 9, CERT_SPKI= 9,
CERT_X509_ATTRIBUTE= 10, CERT_X509_ATTRIBUTE= 10,
CERT_RAW_RSA= 11, /* raw RSA from config file */ CERT_RAW_RSA_KEY= 11
}; };
/* a SIG record in ASCII */ /* a SIG record in ASCII */
+14
View File
@@ -69,6 +69,20 @@ struct private_certinfo_t {
crl_reason_t revocationReason; crl_reason_t revocationReason;
}; };
/**
* RFC 2560 OCSP - certificate status
*/
static const char *const cert_status_name[] = {
"good",
"revoked",
"unknown",
"unknown",
"untrusted"
};
enum_names cert_status_names =
{ CERT_GOOD, CERT_UNTRUSTED, cert_status_name, NULL};
/** /**
* RFC 2459 CRL reason codes * RFC 2459 CRL reason codes
*/ */
+4 -1
View File
@@ -29,11 +29,14 @@
/** /**
* RFC 2560 OCSP - certificate status * RFC 2560 OCSP - certificate status
*/ */
extern enum_names cert_status_names;
typedef enum { typedef enum {
CERT_GOOD = 0, CERT_GOOD = 0,
CERT_REVOKED = 1, CERT_REVOKED = 1,
CERT_UNKNOWN = 2, CERT_UNKNOWN = 2,
CERT_UNDEFINED = 3 CERT_UNDEFINED = 3,
CERT_UNTRUSTED = 4 /* private use */
} cert_status_t; } cert_status_t;
/** /**
+68 -10
View File
@@ -78,6 +78,11 @@ struct private_x509_t {
*/ */
time_t until; time_t until;
/**
* Certificate status
*/
cert_status_t status;
/** /**
* X.509 Certificate in DER format * X.509 Certificate in DER format
*/ */
@@ -956,12 +961,20 @@ static bool is_issuer(const private_x509_t *this, const private_x509_t *issuer)
&& chunk_equals_or_null(this->authKeySerialNumber, issuer->serialNumber)); && chunk_equals_or_null(this->authKeySerialNumber, issuer->serialNumber));
} }
/**
* Implements x509_t.get_certificate
*/
static chunk_t get_certificate(const private_x509_t *this)
{
return this->certificate;
}
/** /**
* Implements x509_t.get_public_key * Implements x509_t.get_public_key
*/ */
static rsa_public_key_t *get_public_key(const private_x509_t *this) static rsa_public_key_t *get_public_key(const private_x509_t *this)
{ {
return this->public_key->clone(this->public_key); return this->public_key;
} }
/** /**
@@ -1004,6 +1017,30 @@ static void set_until(private_x509_t *this, time_t until)
this->until = until; this->until = until;
} }
/**
* Implements x509_t.get_until
*/
static time_t get_until(const private_x509_t *this)
{
return this->until;
}
/**
* Implements x509_t.set_status
*/
static void set_status(private_x509_t *this, cert_status_t status)
{
this->status = status;
}
/**
* Implements x509_t.get_status
*/
static cert_status_t get_status(const private_x509_t *this)
{
return this->status;
}
/** /**
* Implements x509_t.verify * Implements x509_t.verify
*/ */
@@ -1096,30 +1133,46 @@ static void log_certificate(const private_x509_t *this, logger_t *logger, bool u
rsa_public_key_t *pubkey = this->public_key; rsa_public_key_t *pubkey = this->public_key;
char buf[BUF_LEN]; char buf[BUF_LEN];
char time_buf[TIMETOA_BUF];
/* determine the current time */ /* determine the current time */
time_t now = time(NULL); time_t now = time(NULL);
timetoa(buf, BUF_LEN, &this->installed, utc); timetoa(time_buf, TIMETOA_BUF, &this->installed, utc);
logger->log(logger, CONTROL, "%s", buf); logger->log(logger, CONTROL, "%s", time_buf);
logger->log(logger, CONTROL, " subject: '%s'", subject->get_string(subject)); logger->log(logger, CONTROL, " subject: '%s'", subject->get_string(subject));
logger->log(logger, CONTROL, " issuer: '%s'", issuer->get_string(issuer)); logger->log(logger, CONTROL, " issuer: '%s'", issuer->get_string(issuer));
chunk_to_hex(buf, BUF_LEN, this->serialNumber); chunk_to_hex(buf, BUF_LEN, this->serialNumber);
logger->log(logger, CONTROL, " serial: %s", buf); logger->log(logger, CONTROL, " serial: %s", buf);
timetoa(buf, BUF_LEN, &this->notBefore, utc); timetoa(time_buf, TIMETOA_BUF, &this->notBefore, utc);
logger->log(logger, CONTROL, " validity: not before %s %s", buf, logger->log(logger, CONTROL, " validity: not before %s %s", time_buf,
(this->notBefore < now)? "ok":"fatal (not valid yet)"); (this->notBefore < now)? "ok":"fatal (not valid yet)");
timetoa(buf, BUF_LEN, &this->notAfter, utc); timetoa(time_buf, TIMETOA_BUF, &this->notAfter, utc);
logger->log(logger, CONTROL, " not after %s %s", buf, logger->log(logger, CONTROL, " not after %s %s", time_buf,
check_expiry(this->notAfter, CERT_WARNING_INTERVAL, TRUE)); check_expiry(this->notAfter, CERT_WARNING_INTERVAL, TRUE));
timetoa(buf, BUF_LEN, &this->until, utc); timetoa(time_buf, TIMETOA_BUF, &this->until, utc);
logger->log(logger, CONTROL, " pubkey: RSA %d bits%s, until %s", switch (this->status)
{
case CERT_GOOD:
snprintf(buf, BUF_LEN, " until %s", time_buf);
break;
case CERT_REVOKED:
snprintf(buf, BUF_LEN, " on %s", time_buf);
break;
case CERT_UNKNOWN:
case CERT_UNDEFINED:
case CERT_UNTRUSTED:
default:
*buf = '\0';
}
logger->log(logger, CONTROL, " pubkey: RSA %d bits%s, status %s%s",
BITS_PER_BYTE * pubkey->get_keysize(pubkey), BITS_PER_BYTE * pubkey->get_keysize(pubkey),
has_key? ", has private key":"", buf); has_key? ", has private key":"",
enum_name(&cert_status_names, this->status), buf);
chunk_to_hex(buf, BUF_LEN, pubkey->get_keyid(pubkey)); chunk_to_hex(buf, BUF_LEN, pubkey->get_keyid(pubkey));
logger->log(logger, CONTROL, " keyid: %s", buf); logger->log(logger, CONTROL, " keyid: %s", buf);
@@ -1166,12 +1219,16 @@ x509_t *x509_create_from_chunk(chunk_t chunk)
this->public.is_valid = (err_t (*) (const x509_t*,time_t*))is_valid; this->public.is_valid = (err_t (*) (const x509_t*,time_t*))is_valid;
this->public.is_ca = (bool (*) (const x509_t*))is_ca; this->public.is_ca = (bool (*) (const x509_t*))is_ca;
this->public.is_self_signed = (bool (*) (const x509_t*))is_self_signed; this->public.is_self_signed = (bool (*) (const x509_t*))is_self_signed;
this->public.get_certificate = (chunk_t (*) (const x509_t*))get_certificate;
this->public.get_public_key = (rsa_public_key_t* (*) (const x509_t*))get_public_key; this->public.get_public_key = (rsa_public_key_t* (*) (const x509_t*))get_public_key;
this->public.get_serialNumber = (chunk_t (*) (const x509_t*))get_serialNumber; this->public.get_serialNumber = (chunk_t (*) (const x509_t*))get_serialNumber;
this->public.get_subjectKeyID = (chunk_t (*) (const x509_t*))get_subjectKeyID; this->public.get_subjectKeyID = (chunk_t (*) (const x509_t*))get_subjectKeyID;
this->public.get_issuer = (identification_t* (*) (const x509_t*))get_issuer; this->public.get_issuer = (identification_t* (*) (const x509_t*))get_issuer;
this->public.get_subject = (identification_t* (*) (const x509_t*))get_subject; this->public.get_subject = (identification_t* (*) (const x509_t*))get_subject;
this->public.set_until = (void (*) (x509_t*,time_t))set_until; this->public.set_until = (void (*) (x509_t*,time_t))set_until;
this->public.get_until = (time_t (*) (const x509_t*))get_until;
this->public.set_status = (void (*) (x509_t*,cert_status_t))set_status;
this->public.get_status = (cert_status_t (*) (const x509_t*))get_status;
this->public.verify = (bool (*) (const x509_t*,const rsa_public_key_t*))verify; this->public.verify = (bool (*) (const x509_t*,const rsa_public_key_t*))verify;
this->public.destroy = (void (*) (x509_t*))destroy; this->public.destroy = (void (*) (x509_t*))destroy;
this->public.log_certificate = (void (*) (const x509_t*,logger_t*,bool,bool))log_certificate; this->public.log_certificate = (void (*) (const x509_t*,logger_t*,bool,bool))log_certificate;
@@ -1193,6 +1250,7 @@ x509_t *x509_create_from_chunk(chunk_t chunk)
return NULL; return NULL;
} }
/* set trusted lifetime of public key to notAfter */ /* set trusted lifetime of public key to notAfter */
this->status = is_self_signed(this)? CERT_GOOD:CERT_UNDEFINED;
this->until = this->notAfter; this->until = this->notAfter;
return &this->public; return &this->public;
} }
+33
View File
@@ -26,6 +26,7 @@
#include <types.h> #include <types.h>
#include <definitions.h> #include <definitions.h>
#include <crypto/rsa/rsa_public_key.h> #include <crypto/rsa/rsa_public_key.h>
#include <crypto/certinfo.h>
#include <utils/identification.h> #include <utils/identification.h>
#include <utils/iterator.h> #include <utils/iterator.h>
#include <utils/logger.h> #include <utils/logger.h>
@@ -56,6 +57,38 @@ struct x509_t {
*/ */
void (*set_until) (x509_t *this, time_t until); void (*set_until) (x509_t *this, time_t until);
/**
* @brief Get trusted public key life.
*
* @param this calling object
* @return time until public key is trusted
*/
time_t (*get_until) (const x509_t *this);
/**
* @brief Set the certificate status
*
* @param this calling object
* @param status certificate status
*/
void (*set_status) (x509_t *this, cert_status_t status);
/**
* @brief Get the certificate status
*
* @param this calling object
* @return certificate status
*/
cert_status_t (*get_status) (const x509_t *this);
/**
* @brief Get the DER-encoded X.509 certificate body
*
* @param this calling object
* @return DER-encoded X.509 certificate
*/
chunk_t (*get_certificate) (const x509_t *this);
/** /**
* @brief Get the RSA public key from the certificate. * @brief Get the RSA public key from the certificate.
* *