diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/config/policies/policy.c | 34 | ||||
-rw-r--r-- | src/charon/config/policies/policy.h | 9 | ||||
-rwxr-xr-x | src/charon/threads/stroke_interface.c | 33 | ||||
-rw-r--r-- | src/libstrongswan/types.h | 12 | ||||
-rw-r--r-- | src/starter/confread.c | 3 | ||||
-rw-r--r-- | src/starter/starterstroke.c | 24 | ||||
-rw-r--r-- | src/stroke/stroke.c | 6 | ||||
-rw-r--r-- | src/stroke/stroke.h | 23 |
8 files changed, 114 insertions, 30 deletions
diff --git a/src/charon/config/policies/policy.c b/src/charon/config/policies/policy.c index 3e5837714..f30d59670 100644 --- a/src/charon/config/policies/policy.c +++ b/src/charon/config/policies/policy.c @@ -57,6 +57,16 @@ struct private_policy_t { identification_t *other_id; /** + * we have a cert issued by this CA + */ + identification_t *my_ca; + + /** + * we require the other end to have a cert issued by this CA + */ + identification_t *other_ca; + + /** * list for all proposals */ linked_list_t *proposals; @@ -268,6 +278,15 @@ static proposal_t *select_proposal(private_policy_t *this, linked_list_t *propos } /** + * Implementation of policy_t.add_authorities + */ +static void add_authorities(private_policy_t *this, identification_t *my_ca, identification_t *other_ca) +{ + this->my_ca = my_ca; + this->other_ca = other_ca; +} + +/** * Implementation of policy_t.add_my_traffic_selector */ static void add_my_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector) @@ -320,6 +339,10 @@ static policy_t *clone(private_policy_t *this) proposal_t *proposal; traffic_selector_t *ts; + /* clone the certification authorities */ + clone->my_ca = this->my_ca->clone(this->my_ca); + clone->other_ca = this->other_ca->clone(this->other_ca); + /* clone all proposals */ iterator = this->proposals->create_iterator(this->proposals, TRUE); while (iterator->has_next(iterator)) @@ -383,6 +406,10 @@ static status_t destroy(private_policy_t *this) } this->other_ts->destroy(this->other_ts); + /* delete certification authorities */ + this->my_ca->destroy(this->my_ca); + this->other_ca->destroy(this->other_ca); + /* delete ids */ this->my_id->destroy(this->my_id); this->other_id->destroy(this->other_id); @@ -416,17 +443,20 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o this->public.add_my_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_my_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_authorities = (void(*)(policy_t*,identification_t*, identification_t*))add_authorities; 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.clone = (policy_t*(*)(policy_t*))clone; this->public.destroy = (void(*)(policy_t*))destroy; /* apply init values */ + this->name = strdup(name); this->my_id = my_id; this->other_id = other_id; - this->name = strdup(name); - /* init private members*/ + /* initialize private members*/ + this->my_ca = NULL; + this->other_ca = NULL; this->select_traffic_selectors = select_traffic_selectors; this->proposals = linked_list_create(); this->my_ts = linked_list_create(); diff --git a/src/charon/config/policies/policy.h b/src/charon/config/policies/policy.h index b9d4e94a6..44ed1922c 100644 --- a/src/charon/config/policies/policy.h +++ b/src/charon/config/policies/policy.h @@ -230,6 +230,15 @@ struct policy_t { void (*add_proposal) (policy_t *this, proposal_t *proposal); /** + * @brief Add certification authorities + * + * @param this calling object + * @param my_ca issuer of my certificate + * @param other_ca required issuer of the peer's certificate + */ + void (*add_authorities) (policy_t *this, identification_t *my_ca, identification_t *other_ca); + + /** * @brief Get the lifetime of a policy, before rekeying starts. * * A call to this function automatically adds a jitter to diff --git a/src/charon/threads/stroke_interface.c b/src/charon/threads/stroke_interface.c index a0e0112b4..33de8012a 100755 --- a/src/charon/threads/stroke_interface.c +++ b/src/charon/threads/stroke_interface.c @@ -73,7 +73,7 @@ struct private_stroke_t { int socket; /** - * Thread which reads from the socket + * Thread which reads from the ocket */ pthread_t assigned_thread; @@ -112,7 +112,7 @@ static void pop_string(stroke_msg_t *msg, char **string) /** * Load end entitity certificate */ -static void load_end_certificate(const char *filename, identification_t **idp) +static void load_end_certificate(const char *filename, identification_t **idp, logger_t *logger) { char path[PATH_BUF]; x509_t *cert; @@ -135,6 +135,12 @@ static void load_end_certificate(const char *filename, identification_t **idp) identification_t *id = *idp; identification_t *subject = cert->get_subject(cert); + err_t ugh = cert->is_valid(cert, NULL); + + if (ugh != NULL) + { + logger->log(logger, ERROR, "warning: certificate %s", ugh); + } if (!id->equals(id, subject) && !cert->equals_subjectAltName(cert, id)) { id->destroy(id); @@ -152,7 +158,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg) { connection_t *connection; policy_t *policy; - identification_t *my_id, *other_id; + identification_t *my_id, *other_id, *my_ca, *other_ca; host_t *my_host, *other_host, *my_subnet, *other_subnet; proposal_t *proposal; traffic_selector_t *my_ts, *other_ts; @@ -160,12 +166,14 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg) pop_string(msg, &msg->add_conn.name); pop_string(msg, &msg->add_conn.me.address); pop_string(msg, &msg->add_conn.other.address); + pop_string(msg, &msg->add_conn.me.subnet); + pop_string(msg, &msg->add_conn.other.subnet); pop_string(msg, &msg->add_conn.me.id); pop_string(msg, &msg->add_conn.other.id); pop_string(msg, &msg->add_conn.me.cert); pop_string(msg, &msg->add_conn.other.cert); - pop_string(msg, &msg->add_conn.me.subnet); - pop_string(msg, &msg->add_conn.other.subnet); + pop_string(msg, &msg->add_conn.me.ca); + pop_string(msg, &msg->add_conn.other.ca); this->logger->log(this->logger, CONTROL, "received stroke: add connection \"%s\"", msg->add_conn.name); @@ -232,6 +240,10 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg) return; } + /* TODO check for %same */ + my_ca = identification_create_from_string(msg->add_conn.me.ca); + other_ca = identification_create_from_string(msg->add_conn.other.ca); + my_ts = traffic_selector_create_from_subnet(my_subnet, msg->add_conn.me.subnet ? msg->add_conn.me.subnet_mask : 32); my_subnet->destroy(my_subnet); @@ -245,7 +257,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg) this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "left is other host, switching"); host_t *tmp_host; - identification_t *tmp_id; + identification_t *tmp_id, *tmp_ca; traffic_selector_t *tmp_ts; char *tmp_cert; @@ -257,6 +269,10 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg) my_id = other_id; other_id = tmp_id; + tmp_ca = my_ca; + my_ca = other_ca; + other_ca = tmp_ca; + tmp_ts = my_ts; my_ts = other_ts; other_ts = tmp_ts; @@ -284,11 +300,11 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg) if (msg->add_conn.me.cert) { - load_end_certificate(msg->add_conn.me.cert, &my_id); + load_end_certificate(msg->add_conn.me.cert, &my_id, this->stroke_logger); } if (msg->add_conn.other.cert) { - load_end_certificate(msg->add_conn.other.cert, &other_id); + load_end_certificate(msg->add_conn.other.cert, &other_id, this->stroke_logger); } connection = connection_create(msg->add_conn.name, msg->add_conn.ikev2, @@ -323,6 +339,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg) policy->add_proposal(policy, proposal); policy->add_my_traffic_selector(policy, my_ts); policy->add_other_traffic_selector(policy, other_ts); + policy->add_authorities(policy, my_ca, other_ca); /* add to global policy list */ charon->policies->add_policy(charon->policies, policy); diff --git a/src/libstrongswan/types.h b/src/libstrongswan/types.h index cb4d4ecd6..74f0cbf7a 100644 --- a/src/libstrongswan/types.h +++ b/src/libstrongswan/types.h @@ -111,6 +111,18 @@ enum status_t { /** + * Certificate sending policy + */ +typedef enum certpolicy { + CERT_ALWAYS_SEND = 0, + CERT_SEND_IF_ASKED = 1, + CERT_NEVER_SEND = 2, + + CERT_YES_SEND = 3, /* synonym for CERT_ALWAYS_SEND */ + CERT_NO_SEND = 4 /* synonym for CERT_NEVER_SEND */ +} certpolicy_t; + +/** * String mappings for type status_t. */ extern mapping_t status_m[]; diff --git a/src/starter/confread.c b/src/starter/confread.c index e9912f8b8..3bb837346 100644 --- a/src/starter/confread.c +++ b/src/starter/confread.c @@ -82,6 +82,9 @@ static void default_values(starter_config_t *cfg) cfg->conn_default.left.seen = LEMPTY; cfg->conn_default.right.seen = LEMPTY; + cfg->conn_default.left.sendcert = CERT_SEND_IF_ASKED; + cfg->conn_default.right.sendcert = CERT_SEND_IF_ASKED; + anyaddr(AF_INET, &cfg->conn_default.left.addr); anyaddr(AF_INET, &cfg->conn_default.left.nexthop); anyaddr(AF_INET, &cfg->conn_default.left.srcip); diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c index d271d4018..16d911f93 100644 --- a/src/starter/starterstroke.c +++ b/src/starter/starterstroke.c @@ -106,6 +106,17 @@ static char* connection_name(starter_conn_t *conn) return conn->name; } +static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, starter_end_t *conn_end) +{ + msg_end->id = push_string(msg, conn_end->id); + msg_end->cert = push_string(msg, conn_end->cert); + msg_end->cert = push_string(msg, conn_end->cert); + msg_end->address = push_string(msg, inet_ntoa(conn_end->addr.u.v4.sin_addr)); + msg_end->subnet = push_string(msg, inet_ntoa(conn_end->subnet.addr.u.v4.sin_addr)); + msg_end->subnet_mask = conn_end->subnet.maskbits; + msg_end->sendcert = conn_end->sendcert; +} + int starter_stroke_add_conn(starter_conn_t *conn) { stroke_msg_t msg; @@ -115,17 +126,8 @@ int starter_stroke_add_conn(starter_conn_t *conn) msg.add_conn.ikev2 = conn->keyexchange == KEY_EXCHANGE_IKEV2; msg.add_conn.name = push_string(&msg, connection_name(conn)); - msg.add_conn.me.id = push_string(&msg, conn->left.id); - msg.add_conn.me.cert = push_string(&msg, conn->left.cert); - msg.add_conn.me.address = push_string(&msg, inet_ntoa(conn->left.addr.u.v4.sin_addr)); - msg.add_conn.me.subnet = push_string(&msg, inet_ntoa(conn->left.subnet.addr.u.v4.sin_addr)); - msg.add_conn.me.subnet_mask = conn->left.subnet.maskbits; - - msg.add_conn.other.id = push_string(&msg, conn->right.id); - msg.add_conn.other.cert = push_string(&msg, conn->right.cert); - msg.add_conn.other.address = push_string(&msg, inet_ntoa(conn->right.addr.u.v4.sin_addr)); - msg.add_conn.other.subnet = push_string(&msg, inet_ntoa(conn->right.subnet.addr.u.v4.sin_addr)); - msg.add_conn.other.subnet_mask = conn->right.subnet.maskbits; + starter_stroke_add_end(&msg, &msg.add_conn.me, &conn->right); + starter_stroke_add_end(&msg, &msg.add_conn.other, &conn->left); return send_stroke_msg(&msg); } diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c index 9bcc39ad4..3e2c473eb 100644 --- a/src/stroke/stroke.c +++ b/src/stroke/stroke.c @@ -24,6 +24,8 @@ #include <stdio.h> #include <linux/stddef.h> +#include <types.h> + #include "stroke.h" #define streq(a, b) (strcmp((a), (b)) == 0) /* clearer shorthand */ @@ -106,12 +108,16 @@ static int add_connection(char *name, msg.add_conn.me.subnet = push_string(&msg, my_net); msg.add_conn.me.subnet_mask = my_netmask; msg.add_conn.me.cert = NULL; + msg.add_conn.me.ca = NULL; + msg.add_conn.me.sendcert = CERT_SEND_IF_ASKED; msg.add_conn.other.id = push_string(&msg, other_id); msg.add_conn.other.address = push_string(&msg, other_addr); msg.add_conn.other.subnet = push_string(&msg, other_net); msg.add_conn.other.subnet_mask = other_netmask; msg.add_conn.other.cert = NULL; + msg.add_conn.other.ca = NULL; + msg.add_conn.other.sendcert = CERT_SEND_IF_ASKED; return send_stroke_msg(&msg); } diff --git a/src/stroke/stroke.h b/src/stroke/stroke.h index a5e26af4a..fd7870f6c 100644 --- a/src/stroke/stroke.h +++ b/src/stroke/stroke.h @@ -30,6 +30,18 @@ #define STROKE_BUF_LEN 2048 +typedef struct stroke_end_t stroke_end_t; + +struct stroke_end_t { + char *id; + char *cert; + char *ca; + char *address; + char *subnet; + int subnet_mask; + certpolicy_t sendcert; +}; + typedef struct stroke_msg_t stroke_msg_t; /** @@ -73,15 +85,8 @@ struct stroke_msg_t { /* data for STR_ADD_CONN */ struct { char *name; - /* is this connection handled by charon? */ - int ikev2; - struct { - char *id; - char *cert; - char *address; - char *subnet; - int subnet_mask; - } me, other; + bool ikev2; + stroke_end_t me, other; } add_conn; struct { |