support of crlcheckinterval=0 to disable IKEv2 CRL fetching
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 4 Apr 2007 07:49:05 +0000 (07:49 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 4 Apr 2007 07:49:05 +0000 (07:49 -0000)
src/charon/daemon.c
src/libstrongswan/crypto/ca.c
src/libstrongswan/crypto/ca.h
src/pluto/plutomain.c
src/starter/invokecharon.c

index b3adf3e..6d91587 100644 (file)
@@ -39,6 +39,7 @@
 #include "daemon.h"
 
 #include <library.h>
+#include <crypto/ca.h>
 #include <utils/fetcher.h>
 #include <config/credentials/local_credential_store.h>
 #include <config/connections/local_connection_store.h>
@@ -379,6 +380,8 @@ static void usage(const char *msg)
                                        "         [--help]\n"
                                        "         [--version]\n"
                                        "         [--strictcrlpolicy]\n"
+                                       "         [--crlcheckinterval <interval>]\n"
+                                       "         [--eapdir <dir>]\n"
                                        "         [--use-syslog]\n"
                                        "         [--debug-<type> <level>]\n"
                                        "           <type>:  log context type (dmn|mgr|ike|chd|job|cfg|knl|net|enc|lib)\n"
@@ -394,6 +397,7 @@ static void usage(const char *msg)
  */
 int main(int argc, char *argv[])
 {
+       u_int crl_check_interval = 0;
        bool strict_crl_policy = FALSE;
        bool use_syslog = FALSE;
        char *eapdir = IPSEC_EAPDIR;
@@ -420,6 +424,7 @@ int main(int argc, char *argv[])
                        { "version", no_argument, NULL, 'v' },
                        { "use-syslog", no_argument, NULL, 'l' },
                        { "strictcrlpolicy", no_argument, NULL, 'r' },
+                       { "crlcheckinterval", required_argument, NULL, 'x' },
                        { "eapdir", required_argument, NULL, 'e' },
                        /* TODO: handle "debug-all" */
                        { "debug-dmn", required_argument, &signal, DBG_DMN },
@@ -452,6 +457,9 @@ int main(int argc, char *argv[])
                        case 'r':
                                strict_crl_policy = TRUE;
                                continue;
+                       case 'x':
+                               crl_check_interval = atoi(optarg);
+                               continue;
                        case 'e':
                                eapdir = optarg;
                                continue;
@@ -471,9 +479,13 @@ int main(int argc, char *argv[])
        
        /* initialize daemon */
        initialize(private_charon, strict_crl_policy, use_syslog, levels);
+
        /* load pluggable EAP modules */
        eap_method_load(eapdir);
        
+       /* set crl_check_interval */
+       ca_info_set_crlcheckinterval(crl_check_interval);
+
        /* check/setup PID file */
        if (stat(PID_FILE, &stb) == 0)
        {
index 765bae4..cf3d0ee 100644 (file)
@@ -92,6 +92,11 @@ struct private_ca_info_t {
 };
 
 /**
+ * static value set by ca_info_set_crl()
+ */
+static crl_check_interval = 0;
+
+/**
  * Implements ca_info_t.equals
  */
 static bool equals(const private_ca_info_t *this, const private_ca_info_t *that)
@@ -379,14 +384,14 @@ static x509_t* get_certificate(private_ca_info_t* this)
 static cert_status_t verify_by_crl(private_ca_info_t* this,
                                                                   certinfo_t *certinfo)
 {
+       rsa_public_key_t *issuer_public_key = this->cacert->get_public_key(this->cacert);
        bool stale;
 
        pthread_mutex_lock(&(this->mutex));
-
        if (this->crl == NULL)
        {
                stale = TRUE;
-               DBG1("crl is not locally available");
+               DBG1("no crl is locally available");
        }
        else
        {
@@ -394,7 +399,7 @@ static cert_status_t verify_by_crl(private_ca_info_t* this,
                DBG1("crl is %s", stale? "stale":"valid");
        }
 
-       if (stale)
+       if (stale && crl_check_interval > 0)
        {
                iterator_t *iterator = this->crluris->create_iterator(this->crluris, TRUE);
                identification_t *uri;
@@ -414,37 +419,50 @@ static cert_status_t verify_by_crl(private_ca_info_t* this,
                        if (response_chunk.ptr != NULL)
                        {
                                crl_t *crl = crl_create_from_chunk(response_chunk);
-                               
-                               if (crl)
+               
+                               if (crl == NULL)
                                {
-                                       if (this->crl == NULL)
-                                       {
-                                               this->crl = crl;
-                                       }
-                                       else if (crl->is_newer(crl, this->crl))
+                                       free(response_chunk.ptr);
+                                       continue;
+                               }
+                               if (!is_crl_issuer(this, crl))
+                               {
+                                       DBG1("  fetched crl has wrong issuer");
+                                       crl->destroy(crl);
+                                       continue;
+                               }
+                               if (!crl->verify(crl, issuer_public_key))
+                               {
+                                       DBG1("fetched crl signature is invalid");
+                                       crl->destroy(crl);
+                                       continue;
+                               }
+                               DBG2("fetched crl signature is valid");
+
+                               if (this->crl == NULL)
+                               {
+                                       this->crl = crl;
+                               }
+                               else if (crl->is_newer(crl, this->crl))
+                               {
+                                       this->crl->destroy(this->crl);
+                                       this->crl = crl;
+                                       DBG1(" thisUpdate is newer - existing crl replaced");
+                                       if (this->crl->is_valid(this->crl))
                                        {
-                                               this->crl->destroy(this->crl);
-                                               this->crl = crl;
-                                               DBG1("  thisUpdate is newer - existing crl replaced");
-                                               if (this->crl->is_valid(this->crl))
-                                               {
-                                                       break;
-                                               }
-                                               else
-                                               {
-                                                       DBG1("fetched crl is stale");
-                                               }
+                                               /* we found a valid crl and exit the fetch loop */
+                                               break;
                                        }
                                        else
                                        {
-                                               crl->destroy(crl);
-                                               DBG1("  thisUpdate is not newer - existing crl retained");
+                                               DBG1("fetched crl is stale");
                                        }
                                }
                                else
                                {
-                                       free(response_chunk.ptr);
-                               };
+                                       crl->destroy(crl);
+                                       DBG1("thisUpdate is not newer - existing crl retained");
+                               }
                        }
                }
                iterator->destroy(iterator);
@@ -452,12 +470,7 @@ static cert_status_t verify_by_crl(private_ca_info_t* this,
 
        if (this->crl)
        {
-               rsa_public_key_t *issuer_public_key;
-               bool valid_signature;
-
-               issuer_public_key = this->cacert->get_public_key(this->cacert);
-               valid_signature = this->crl->verify(this->crl, issuer_public_key);
-               if (!valid_signature)
+               if (!this->crl->verify(this->crl, issuer_public_key))
                {
                        DBG1("crl signature is invalid");
                        goto ret;
@@ -669,6 +682,14 @@ static void __attribute__ ((constructor))print_register()
 /*
  * Described in header.
  */
+void ca_info_set_crlcheckinterval(u_int interval)
+{
+       crl_check_interval = interval;
+}
+
+/*
+ * Described in header.
+ */
 ca_info_t *ca_info_create(const char *name, x509_t *cacert)
 {
        private_ca_info_t *this = malloc_thing(private_ca_info_t);
index 440ac4f..832fa98 100644 (file)
@@ -193,11 +193,20 @@ struct ca_info_t {
 /**
  * @brief Create a ca info record
  * 
+ * @param interval     crl_check_interval to be set in seconds
+ * 
+ * @ingroup crypto
+ */
+void ca_info_set_crlcheckinterval(u_int interval);
+
+/**
+ * @brief Create a ca info record
+ * 
  * @param name                 name of the ca info record
  * @param cacert       path to the ca certificate
  * @return                     created ca_info_t, or NULL if invalid.
  * 
- * @ingroup transforms
+ * @ingroup crypto
  */
 ca_info_t *ca_info_create(const char *name, x509_t *cacert);
 
index 09f8c61..e235ff7 100644 (file)
@@ -81,7 +81,7 @@ usage(const char *mess)
            " [--nocrsend]"
            " \\\n\t"
            "[--strictcrlpolicy]"
-           " [--crlcheckinterval]"
+           " [--crlcheckinterval <interval>]"
            " [--cachecrls]"
            " [--uniqueids]"
            " \\\n\t"
index 1fceae7..a490882 100644 (file)
@@ -116,6 +116,14 @@ starter_start_charon (starter_config_t *cfg, bool debug)
     {
        arg[argc++] = "--strictcrlpolicy";
     }
+    if (cfg->setup.crlcheckinterval > 0)
+    {
+       char buffer[BUF_LEN];
+
+       snprintf(buffer, BUF_LEN, "%u", cfg->setup.crlcheckinterval);
+       arg[argc++] = "--crlcheckinterval";
+       arg[argc++] = buffer;
+    }
     if (cfg->setup.eapdir)
     {
        arg[argc++] = "--eapdir";
@@ -123,7 +131,7 @@ starter_start_charon (starter_config_t *cfg, bool debug)
     }
 
     {   /* parse debug string */
-       char *pos, *level, *buf_pos, type[4], buffer[512];
+       char *pos, *level, *buf_pos, type[4], buffer[BUF_LEN];
        pos = cfg->setup.charondebug;
        buf_pos = buffer;
        while (pos && sscanf(pos, "%4s %d,", type, &level) == 2)