added support for leftsendcert= and left|rightca= parameters
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 9 Jun 2006 05:50:41 +0000 (05:50 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 9 Jun 2006 05:50:41 +0000 (05:50 -0000)
src/charon/config/policies/policy.c
src/charon/config/policies/policy.h
src/charon/threads/stroke_interface.c
src/libstrongswan/types.h
src/starter/confread.c
src/starter/starterstroke.c
src/stroke/stroke.c
src/stroke/stroke.h

index 3e58377..f30d596 100644 (file)
@@ -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();
index b9d4e94..44ed192 100644 (file)
@@ -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
index a0e0112..33de801 100755 (executable)
@@ -73,7 +73,7 @@ struct private_stroke_t {
        int socket;
        
        /**
-        * Thread which reads from the socket
+        * Thread which reads from the \ 1ocket
         */
        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);
index cb4d4ec..74f0cbf 100644 (file)
@@ -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[];
index e9912f8..3bb8373 100644 (file)
@@ -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);
index d271d40..16d911f 100644 (file)
@@ -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);
 }
index 9bcc39a..3e2c473 100644 (file)
@@ -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);
 }
index a5e26af..fd7870f 100644 (file)
 
 #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 {