support of ca info records
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 23 Feb 2007 15:15:31 +0000 (15:15 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 23 Feb 2007 15:15:31 +0000 (15:15 -0000)
src/charon/config/credentials/credential_store.h
src/charon/config/credentials/local_credential_store.c
src/charon/threads/stroke_interface.c

index 59fc4a0..f46e2c9 100755 (executable)
@@ -28,6 +28,7 @@ typedef struct credential_store_t credential_store_t;
 
 #include <library.h>
 #include <crypto/x509.h>
+#include <crypto/ca.h>
 #include <crypto/rsa/rsa_private_key.h>
 #include <crypto/rsa/rsa_public_key.h>
 #include <utils/identification.h>
@@ -162,6 +163,15 @@ struct credential_store_t {
        x509_t* (*add_ca_certificate) (credential_store_t *this, x509_t *cert);
 
        /**
+        * @brief If a ca info record does not already exists in the credential store then add it.
+        *
+        * @param this          calling object
+        * @param cert          ca info record to be added
+        * @return                      pointer to the added or already existing ca info record
+        */
+       ca_info_t* (*add_ca_info) (credential_store_t *this, ca_info_t *ca_info);
+
+       /**
         * @brief Create an iterator over all end certificates.
         *
         * @param this          calling object
@@ -178,6 +188,14 @@ struct credential_store_t {
        iterator_t* (*create_cacert_iterator) (credential_store_t *this);
 
        /**
+        * @brief Create an iterator over all CA info records
+        *
+        * @param this          calling object
+        * @return                      iterator
+        */
+       iterator_t* (*create_cainfo_iterator) (credential_store_t *this);
+
+       /**
         * @brief Create an iterator over all CRLs.
         *
         * @param this          calling object
index eaf3b17..c46f117 100644 (file)
@@ -31,6 +31,7 @@
 #include <crypto/certinfo.h>
 #include <crypto/rsa/rsa_public_key.h>
 #include <crypto/x509.h>
+#include <crypto/ca.h>
 #include <crypto/crl.h>
 #include <asn1/ttodata.h>
 
@@ -121,6 +122,11 @@ struct private_local_credential_store_t {
        linked_list_t *ca_certs;
 
        /**
+        * list of X.509 CA information records
+        */
+       linked_list_t *ca_infos;
+
+       /**
         * list of X.509 CRLs
         */
        linked_list_t *crls;
@@ -681,6 +687,15 @@ static x509_t* add_ca_certificate(private_local_credential_store_t *this, x509_t
 }
 
 /**
+ * Add a unique ca info record to a linked list
+ */
+static ca_info_t* add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_info)
+{
+       this->ca_infos->insert_last(this->ca_infos, (void*)ca_info);
+       return ca_info;
+}
+
+/**
  * Implements local_credential_store_t.create_cert_iterator
  */
 static iterator_t* create_cert_iterator(private_local_credential_store_t *this)
@@ -697,6 +712,14 @@ static iterator_t* create_cacert_iterator(private_local_credential_store_t *this
 }
 
 /**
+ * Implements local_credential_store_t.create_cainfo_iterator
+ */
+static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this)
+{
+       return this->ca_infos->create_iterator(this->ca_infos, TRUE);
+}
+
+/**
  * Implements local_credential_store_t.create_crl_iterator
  */
 static iterator_t* create_crl_iterator(private_local_credential_store_t *this)
@@ -1102,6 +1125,7 @@ static void destroy(private_local_credential_store_t *this)
 {
        this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
        this->ca_certs->destroy_offset(this->ca_certs, offsetof(x509_t, destroy));
+       this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
        this->crls->destroy_offset(this->crls, offsetof(crl_t, destroy));
        this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
        this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
@@ -1127,8 +1151,10 @@ local_credential_store_t * local_credential_store_create(bool strict)
        this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
        this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
        this->public.credential_store.add_ca_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_ca_certificate;
+       this->public.credential_store.add_ca_info = (ca_info_t* (*) (credential_store_t*,ca_info_t*))add_ca_info;
        this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
        this->public.credential_store.create_cacert_iterator = (iterator_t* (*) (credential_store_t*))create_cacert_iterator;
+       this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator;
        this->public.credential_store.create_crl_iterator = (iterator_t* (*) (credential_store_t*))create_crl_iterator;
        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;
@@ -1143,6 +1169,7 @@ local_credential_store_t * local_credential_store_create(bool strict)
        this->private_keys = linked_list_create();
        this->certs = linked_list_create();
        this->ca_certs = linked_list_create();
+       this->ca_infos = linked_list_create();
        this->crls = linked_list_create();
        this->strict = strict;
 
index 63770cf..a9d3b0e 100755 (executable)
@@ -38,6 +38,7 @@
 #include <stroke.h>
 #include <daemon.h>
 #include <crypto/x509.h>
+#include <crypto/ca.h>
 #include <crypto/crl.h>
 #include <queues/jobs/initiate_job.h>
 #include <queues/jobs/route_job.h>
@@ -148,6 +149,42 @@ static x509_t* load_end_certificate(const char *filename, identification_t **idp
 }
 
 /**
+ * Load ca certificate
+ */
+static x509_t* load_ca_certificate(const char *filename)
+{
+       char path[PATH_BUF];
+       x509_t *cert;
+
+       if (*filename == '/')
+       {
+               /* absolute path name */
+               snprintf(path, sizeof(path), "%s", filename);
+       }
+       else
+       {
+               /* relative path name */
+               snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
+       }
+
+       cert = x509_create_from_file(path, "ca certificate");
+
+       if (cert)
+       {
+               if (cert->is_ca(cert))
+               {
+                       return charon->credentials->add_ca_certificate(charon->credentials, cert);
+               }
+               else
+               {
+                       DBG1(DBG_CFG, "  CA basic constraints flag not set, cert discarded");
+                       cert->destroy(cert);
+               }
+       }
+       return NULL;
+}
+
+/**
  * Add a connection to the configuration list
  */
 static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
@@ -158,7 +195,7 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
        identification_t *my_ca = NULL;
        identification_t *other_ca = NULL;
        bool my_ca_same = FALSE;
-    bool other_ca_same =FALSE;
+       bool other_ca_same =FALSE;
        host_t *my_host, *other_host, *my_subnet, *other_subnet;
        proposal_t *proposal;
        traffic_selector_t *my_ts, *other_ts;
@@ -638,7 +675,43 @@ static void stroke_terminate(stroke_msg_t *msg, FILE *out)
  */
 static void stroke_add_ca(stroke_msg_t *msg, FILE *out)
 {
-       /* TODO add code */
+       x509_t *cacert;
+       ca_info_t *ca_info;
+
+       pop_string(msg, &msg->add_ca.name);
+       pop_string(msg, &msg->add_ca.cacert);
+       pop_string(msg, &msg->add_ca.crluri);
+       pop_string(msg, &msg->add_ca.crluri2);
+       pop_string(msg, &msg->add_ca.ocspuri);
+       pop_string(msg, &msg->add_ca.ocspuri2);
+       
+       DBG1(DBG_CFG, "received stroke: add ca info '%s'", msg->add_ca.name);
+       
+       DBG2(DBG_CFG, "ca %s",        msg->add_ca.name);
+       DBG2(DBG_CFG, "  cacert=%s",  msg->add_ca.cacert);
+       DBG2(DBG_CFG, "  crluri=%s",  msg->add_ca.crluri);
+       DBG2(DBG_CFG, "  crluri2=%s", msg->add_ca.crluri2);
+       DBG2(DBG_CFG, "  ocspuri=%s", msg->add_ca.ocspuri);
+       DBG2(DBG_CFG, "  ocspuri2=%s", msg->add_ca.ocspuri2);
+
+       if (msg->add_ca.cacert == NULL)
+       {
+               DBG1(DBG_CFG, "missing cacert parameter\n");
+               return;
+       }
+
+       cacert = load_ca_certificate(msg->add_ca.cacert);
+
+       if (cacert == NULL)
+       {
+               return;
+       }
+       ca_info = ca_info_create(msg->add_ca.name, cacert);
+       ca_info->add_crluri(ca_info, msg->add_ca.crluri);
+       ca_info->add_crluri(ca_info, msg->add_ca.crluri2);
+       ca_info->add_ocspuri(ca_info, msg->add_ca.ocspuri);
+       ca_info->add_ocspuri(ca_info, msg->add_ca.ocspuri2);
+       charon->credentials->add_ca_info(charon->credentials, ca_info);
 }
 
 /**
@@ -864,6 +937,23 @@ static void stroke_list(stroke_msg_t *msg, FILE *out)
                }
                iterator->destroy(iterator);
        }
+       if (msg->list.flags & LIST_CAINFOS)
+       {
+               ca_info_t *ca_info;
+
+               iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
+               if (iterator->get_count(iterator))
+               {
+                       fprintf(out, "\n");
+                       fprintf(out, "List of X.509 CA Information Records:\n");
+                       fprintf(out, "\n");
+               }
+               while (iterator->iterate(iterator, (void**)&ca_info))
+               {
+                       fprintf(out, "%#C\n", ca_info, msg->list.utc);
+               }
+               iterator->destroy(iterator);
+       }
        if (msg->list.flags & LIST_CRLS)
        {
                crl_t *crl;