diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-04-20 11:12:08 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-04-20 11:12:08 +0000 |
commit | 4841189b725ca4112cd183f7d71b37a468f5ddb5 (patch) | |
tree | d13fdccca5268615708ec71eb7bce724ba124a8d /src | |
parent | ab58c17445a1122010fa23e338e60c971e08fef8 (diff) | |
download | strongswan-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.c | 99 | ||||
-rw-r--r-- | src/charon/config/credentials/local_credential_store.h | 3 | ||||
-rw-r--r-- | src/charon/daemon.c | 17 | ||||
-rw-r--r-- | src/libstrongswan/crypto/ca.c | 22 | ||||
-rw-r--r-- | src/libstrongswan/crypto/ca.h | 11 | ||||
-rw-r--r-- | src/libstrongswan/library.h | 9 | ||||
-rw-r--r-- | src/starter/args.c | 8 | ||||
-rw-r--r-- | src/starter/confread.h | 40 | ||||
-rw-r--r-- | src/starter/invokecharon.c | 1 |
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) { |