aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2007-04-20 11:12:08 +0000
committerAndreas Steffen <andreas.steffen@strongswan.org>2007-04-20 11:12:08 +0000
commit4841189b725ca4112cd183f7d71b37a468f5ddb5 (patch)
treed13fdccca5268615708ec71eb7bce724ba124a8d /src
parentab58c17445a1122010fa23e338e60c971e08fef8 (diff)
downloadstrongswan-4841189b725ca4112cd183f7d71b37a468f5ddb5.tar.bz2
strongswan-4841189b725ca4112cd183f7d71b37a468f5ddb5.tar.xz
implementation of strictcrlpolicy=ifuri
Diffstat (limited to 'src')
-rw-r--r--src/charon/config/credentials/local_credential_store.c99
-rw-r--r--src/charon/config/credentials/local_credential_store.h3
-rw-r--r--src/charon/daemon.c17
-rw-r--r--src/libstrongswan/crypto/ca.c22
-rw-r--r--src/libstrongswan/crypto/ca.h11
-rw-r--r--src/libstrongswan/library.h9
-rw-r--r--src/starter/args.c8
-rw-r--r--src/starter/confread.h40
-rw-r--r--src/starter/invokecharon.c1
9 files changed, 134 insertions, 76 deletions
diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c
index bee7fce4b..82ea78768 100644
--- a/src/charon/config/credentials/local_credential_store.c
+++ b/src/charon/config/credentials/local_credential_store.c
@@ -171,11 +171,6 @@ struct private_local_credential_store_t {
* list of X.509 CA information records
*/
linked_list_t *ca_infos;
-
- /**
- * enforce strict crl policy
- */
- bool strict;
};
@@ -304,6 +299,29 @@ static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *th
}
/**
+ * Implementation of credential_store_t.get_issuer.
+ */
+static ca_info_t* get_issuer(private_local_credential_store_t *this, const x509_t *cert)
+{
+ ca_info_t *found = NULL;
+ ca_info_t *ca_info;
+
+ iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
+
+ while (iterator->iterate(iterator, (void**)&ca_info))
+ {
+ if (ca_info->is_cert_issuer(ca_info, cert))
+ {
+ found = ca_info;
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+
+ return found;
+}
+
+/**
* 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,
@@ -324,18 +342,30 @@ static rsa_public_key_t *get_trusted_public_key(private_local_credential_store_t
return NULL;
}
- status = cert->get_status(cert);
- if (status == CERT_REVOKED || status == CERT_UNTRUSTED || (this->strict && status != CERT_GOOD))
- {
- DBG1(DBG_CFG, "certificate status: %N", cert_status_names, status);
- return NULL;
- }
- if (status == CERT_GOOD && cert->get_until(cert) < time(NULL))
+ if (!cert->is_self_signed(cert))
{
- DBG1(DBG_CFG, "certificate is good but crl is stale");
- return NULL;
- }
+ ca_info_t *issuer = get_issuer(this, cert);
+ if (issuer == NULL)
+ {
+ DBG1(DBG_CFG, "issuer of public key not found");
+ return NULL;
+ }
+ status = cert->get_status(cert);
+
+ if (status == CERT_REVOKED
+ || status == CERT_UNTRUSTED
+ || (issuer->is_strict(issuer) && status != CERT_GOOD))
+ {
+ DBG1(DBG_CFG, "certificate status: %N", cert_status_names, status);
+ return NULL;
+ }
+ if (status == CERT_GOOD && cert->get_until(cert) < time(NULL))
+ {
+ DBG1(DBG_CFG, "certificate is good but crl is stale");
+ return NULL;
+ }
+ }
return cert->get_public_key(cert);
}
@@ -437,29 +467,6 @@ static x509_t* get_ca_certificate_by_keyid(private_local_credential_store_t *thi
}
/**
- * Implementation of credential_store_t.get_issuer.
- */
-static ca_info_t* get_issuer(private_local_credential_store_t *this, const x509_t *cert)
-{
- ca_info_t *found = NULL;
- ca_info_t *ca_info;
-
- iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
-
- while (iterator->iterate(iterator, (void**)&ca_info))
- {
- if (ca_info->is_cert_issuer(ca_info, cert))
- {
- found = ca_info;
- break;
- }
- }
- iterator->destroy(iterator);
-
- return found;
-}
-
-/**
* Find an exact copy of a certificate in a linked list
*/
static x509_t* find_certificate(linked_list_t *certs, x509_t *cert)
@@ -649,6 +656,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
}
else
{
+ bool strict;
time_t nextUpdate;
cert_status_t status;
certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert));
@@ -661,11 +669,15 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
add_uris(issuer, cert);
}
+ strict = issuer->is_strict(issuer);
+ DBG1(DBG_CFG, "issuer %s a strict crl policy",
+ strict ? "enforces":"does not enforce");
+
/* first check certificate revocation using ocsp */
status = issuer->verify_by_ocsp(issuer, certinfo, &this->public.credential_store);
/* if ocsp service is not available then fall back to crl */
- if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && this->strict))
+ if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && strict))
{
status = issuer->verify_by_crl(issuer, certinfo, CRL_DIR);
}
@@ -680,7 +692,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
cert->set_until(cert, nextUpdate);
/* if status information is stale */
- if (this->strict && nextUpdate < time(NULL))
+ if (strict && nextUpdate < time(NULL))
{
DBG2(DBG_CFG, "certificate is good but status is stale");
certinfo->destroy(certinfo);
@@ -691,7 +703,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
/* with strict crl policy the public key must have the same
* lifetime as the validity of the ocsp status or crl lifetime
*/
- if (this->strict && nextUpdate < until)
+ if (strict && nextUpdate < until)
until = nextUpdate;
break;
case CERT_REVOKED:
@@ -726,7 +738,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
case CERT_UNDEFINED:
default:
DBG1(DBG_CFG, "certificate status unknown");
- if (this->strict)
+ if (strict)
{
/* update status of end certificate in the credential store */
if (cert_copy)
@@ -1391,7 +1403,7 @@ static void destroy(private_local_credential_store_t *this)
/**
* Described in header.
*/
-local_credential_store_t * local_credential_store_create(bool strict)
+local_credential_store_t * local_credential_store_create(void)
{
private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
@@ -1429,7 +1441,6 @@ local_credential_store_t * local_credential_store_create(bool strict)
this->certs = linked_list_create();
this->auth_certs = linked_list_create();
this->ca_infos = linked_list_create();
- this->strict = strict;
return (&this->public);
}
diff --git a/src/charon/config/credentials/local_credential_store.h b/src/charon/config/credentials/local_credential_store.h
index 88a94d6f9..87a12663a 100644
--- a/src/charon/config/credentials/local_credential_store.h
+++ b/src/charon/config/credentials/local_credential_store.h
@@ -54,11 +54,10 @@ struct local_credential_store_t {
/**
* @brief Creates a local_credential_store_t instance.
*
- * @param strict enforce a strict crl policy
* @return credential store instance.
*
* @ingroup config
*/
-local_credential_store_t *local_credential_store_create(bool strict);
+local_credential_store_t *local_credential_store_create(void);
#endif /* LOCAL_CREDENTIAL_H_ */
diff --git a/src/charon/daemon.c b/src/charon/daemon.c
index fb8acc54c..d2b8d346e 100644
--- a/src/charon/daemon.c
+++ b/src/charon/daemon.c
@@ -220,8 +220,7 @@ static void kill_daemon(private_daemon_t *this, char *reason)
/**
* Initialize the daemon, optional with a strict crl policy
*/
-static void initialize(private_daemon_t *this, bool strict, bool syslog,
- level_t levels[])
+static void initialize(private_daemon_t *this, bool syslog, level_t levels[])
{
credential_store_t* credentials;
signal_t signal;
@@ -262,7 +261,7 @@ static void initialize(private_daemon_t *this, bool strict, bool syslog,
this->public.ike_sa_manager = ike_sa_manager_create();
this->public.job_queue = job_queue_create();
this->public.event_queue = event_queue_create();
- this->public.credentials = (credential_store_t*)local_credential_store_create(strict);
+ this->public.credentials = (credential_store_t*)local_credential_store_create();
this->public.cfg_store = cfg_store_create();
this->public.local_backend = local_backend_create();
this->public.cfg_store->register_backend(this->public.cfg_store,
@@ -402,7 +401,7 @@ static void usage(const char *msg)
int main(int argc, char *argv[])
{
u_int crl_check_interval = 0;
- bool strict_crl_policy = FALSE;
+ strict_t strict_crl_policy = STRICT_NO;
bool cache_crls = FALSE;
bool use_syslog = FALSE;
char *eapdir = IPSEC_EAPDIR;
@@ -428,7 +427,7 @@ int main(int argc, char *argv[])
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "use-syslog", no_argument, NULL, 'l' },
- { "strictcrlpolicy", no_argument, NULL, 'r' },
+ { "strictcrlpolicy", required_argument, NULL, 'r' },
{ "cachecrls", no_argument, NULL, 'C' },
{ "crlcheckinterval", required_argument, NULL, 'x' },
{ "eapdir", required_argument, NULL, 'e' },
@@ -461,7 +460,7 @@ int main(int argc, char *argv[])
use_syslog = TRUE;
continue;
case 'r':
- strict_crl_policy = TRUE;
+ strict_crl_policy = atoi(optarg);
continue;
case 'C':
cache_crls = TRUE;
@@ -487,13 +486,13 @@ int main(int argc, char *argv[])
charon = (daemon_t*)private_charon;
/* initialize daemon */
- initialize(private_charon, strict_crl_policy, use_syslog, levels);
+ initialize(private_charon, use_syslog, levels);
/* load pluggable EAP modules */
eap_method_load(eapdir);
- /* set cache_crls and crl_check_interval options */
- ca_info_set_options(cache_crls, crl_check_interval);
+ /* set strict_crl_policy, cache_crls and crl_check_interval options */
+ ca_info_set_options(strict_crl_policy, cache_crls, crl_check_interval);
/* check/setup PID file */
if (stat(PID_FILE, &stb) == 0)
diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c
index f08dba057..bb35b37f2 100644
--- a/src/libstrongswan/crypto/ca.c
+++ b/src/libstrongswan/crypto/ca.c
@@ -100,6 +100,7 @@ struct private_ca_info_t {
/**
* static options set by ca_info_set_options()
*/
+static strict_t strict_crl_policy = STRICT_NO;
static bool cache_crls = FALSE;
static u_int crl_check_interval = 0;
@@ -157,6 +158,23 @@ static bool is_crl_issuer(private_ca_info_t *this, const crl_t *crl)
}
/**
+ * Implements ca_info_t.is_strict
+ */
+static bool is_strict(private_ca_info_t *this)
+{
+ bool strict = strict_crl_policy != STRICT_NO;
+
+ if (strict_crl_policy == STRICT_IFURI)
+ {
+ pthread_mutex_lock(&(this->mutex));
+ strict = this->crluris->get_count(this->crluris) > 0 ||
+ this->ocspuris->get_count(this->ocspuris) > 0;
+ pthread_mutex_unlock(&(this->mutex));
+ }
+ return strict;
+}
+
+/**
* Implements ca_info_t.has_crl
*/
static bool has_crl(private_ca_info_t *this)
@@ -728,8 +746,9 @@ static void list(private_ca_info_t* this, FILE* out, bool utc)
/*
* Described in header.
*/
-void ca_info_set_options(bool cache, u_int interval)
+void ca_info_set_options(strict_t strict, bool cache, u_int interval)
{
+ strict_crl_policy = strict;
cache_crls = cache;
crl_check_interval = interval;
}
@@ -759,6 +778,7 @@ ca_info_t *ca_info_create(const char *name, x509_t *cacert)
this->public.equals_name_release_info = (bool (*) (ca_info_t*,const char*))equals_name_release_info;
this->public.is_cert_issuer = (bool (*) (ca_info_t*,const x509_t*))is_cert_issuer;
this->public.is_crl_issuer = (bool (*) (ca_info_t*,const crl_t*))is_crl_issuer;
+ this->public.is_strict = (bool (*) (ca_info_t*))is_strict;
this->public.add_info = (void (*) (ca_info_t*,const ca_info_t*))add_info;
this->public.add_crl = (void (*) (ca_info_t*,crl_t*))add_crl;
this->public.has_crl = (bool (*) (ca_info_t*))has_crl;
diff --git a/src/libstrongswan/crypto/ca.h b/src/libstrongswan/crypto/ca.h
index 46a10378b..bce39fb95 100644
--- a/src/libstrongswan/crypto/ca.h
+++ b/src/libstrongswan/crypto/ca.h
@@ -26,7 +26,6 @@
typedef struct ca_info_t ca_info_t;
#include <library.h>
-#include <chunk.h>
#include <credential_store.h>
@@ -81,6 +80,14 @@ struct ca_info_t {
bool (*is_crl_issuer) (ca_info_t *this, const crl_t *crl);
/**
+ * @brief Checks if the ca enforces a strict crl policy
+ *
+ * @param this ca info object
+ * @return TRUE if the crl policy is strict
+ */
+ bool (*is_strict) (ca_info_t *this);
+
+ /**
* @brief Merges info from a secondary ca info object
*
* @param this primary ca info object
@@ -209,7 +216,7 @@ struct ca_info_t {
*
* @ingroup crypto
*/
-void ca_info_set_options(bool cache, u_int interval);
+void ca_info_set_options(strict_t strict, bool cache, u_int interval);
/**
* @brief Create a ca info record
diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h
index 7c7f087f0..67a05f118 100644
--- a/src/libstrongswan/library.h
+++ b/src/libstrongswan/library.h
@@ -234,6 +234,15 @@ enum status_t {
};
/**
+ * used by strict_crl_policy
+ */
+typedef enum {
+ STRICT_NO,
+ STRICT_YES,
+ STRICT_IFURI
+} strict_t;
+
+/**
* enum_names for type status_t.
*/
extern enum_name_t *status_names;
diff --git a/src/starter/args.c b/src/starter/args.c
index 82e957f59..fb8424841 100644
--- a/src/starter/args.c
+++ b/src/starter/args.c
@@ -61,6 +61,12 @@ static const char *LST_sendcert[] = {
NULL
};
+static const char *LST_strict[] = {
+ "no",
+ "yes",
+ "ifuri",
+ NULL
+};
static const char *LST_dpd_action[] = {
"none",
"clear",
@@ -160,7 +166,7 @@ static const token_info_t token_info[] =
{ ARG_UINT, offsetof(starter_config_t, setup.overridemtu), NULL },
{ ARG_TIME, offsetof(starter_config_t, setup.crlcheckinterval), NULL },
{ ARG_ENUM, offsetof(starter_config_t, setup.cachecrls), LST_bool },
- { ARG_ENUM, offsetof(starter_config_t, setup.strictcrlpolicy), LST_bool },
+ { ARG_ENUM, offsetof(starter_config_t, setup.strictcrlpolicy), LST_strict },
{ ARG_ENUM, offsetof(starter_config_t, setup.nocrsend), LST_bool },
{ ARG_ENUM, offsetof(starter_config_t, setup.nat_traversal), LST_bool },
{ ARG_TIME, offsetof(starter_config_t, setup.keep_alive), NULL },
diff --git a/src/starter/confread.h b/src/starter/confread.h
index e0de68376..2fe75fcc6 100644
--- a/src/starter/confread.h
+++ b/src/starter/confread.h
@@ -46,6 +46,12 @@ typedef enum {
KEY_EXCHANGE_IKEV2
} keyexchange_t;
+typedef enum {
+ STRICT_NO,
+ STRICT_YES,
+ STRICT_IFURI
+} strict_t;
+
typedef struct starter_end starter_end_t;
struct starter_end {
@@ -156,23 +162,23 @@ struct starter_config {
bool plutostart;
/* pluto/charon keywords */
- char **plutodebug;
- char *charondebug;
- char *prepluto;
- char *postpluto;
- bool uniqueids;
- u_int overridemtu;
- u_int crlcheckinterval;
- bool cachecrls;
- bool strictcrlpolicy;
- bool nocrsend;
- bool nat_traversal;
- u_int keep_alive;
- char *virtual_private;
- char *eapdir;
- char *pkcs11module;
- bool pkcs11keepstate;
- bool pkcs11proxy;
+ char **plutodebug;
+ char *charondebug;
+ char *prepluto;
+ char *postpluto;
+ bool uniqueids;
+ u_int overridemtu;
+ u_int crlcheckinterval;
+ bool cachecrls;
+ strict_t strictcrlpolicy;
+ bool nocrsend;
+ bool nat_traversal;
+ u_int keep_alive;
+ char *virtual_private;
+ char *eapdir;
+ char *pkcs11module;
+ bool pkcs11keepstate;
+ bool pkcs11proxy;
/* KLIPS keywords */
char **klipsdebug;
diff --git a/src/starter/invokecharon.c b/src/starter/invokecharon.c
index 94d046d35..7e93b9ac6 100644
--- a/src/starter/invokecharon.c
+++ b/src/starter/invokecharon.c
@@ -116,6 +116,7 @@ starter_start_charon (starter_config_t *cfg, bool debug)
if (cfg->setup.strictcrlpolicy)
{
arg[argc++] = "--strictcrlpolicy";
+ arg[argc++] = cfg->setup.strictcrlpolicy == STRICT_IFURI ? "2":"1";
}
if (cfg->setup.cachecrls)
{