implementation of strictcrlpolicy=ifuri
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -303,6 +298,29 @@ static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *th
|
||||
return (cert == NULL)? NULL:cert->get_public_key(cert);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@@ -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))
|
||||
if (!cert->is_self_signed(cert))
|
||||
{
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -436,29 +466,6 @@ static x509_t* get_ca_certificate_by_keyid(private_local_credential_store_t *thi
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
+8
-9
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -156,6 +157,23 @@ static bool is_crl_issuer(private_ca_info_t *this, const crl_t *crl)
|
||||
return crl->is_issuer(crl, this->cacert);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@@ -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;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
typedef struct ca_info_t ca_info_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <chunk.h>
|
||||
|
||||
#include <credential_store.h>
|
||||
|
||||
@@ -80,6 +79,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
|
||||
*
|
||||
@@ -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
|
||||
|
||||
@@ -233,6 +233,15 @@ enum status_t {
|
||||
NEED_MORE,
|
||||
};
|
||||
|
||||
/**
|
||||
* used by strict_crl_policy
|
||||
*/
|
||||
typedef enum {
|
||||
STRICT_NO,
|
||||
STRICT_YES,
|
||||
STRICT_IFURI
|
||||
} strict_t;
|
||||
|
||||
/**
|
||||
* enum_names for type status_t.
|
||||
*/
|
||||
|
||||
+7
-1
@@ -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 },
|
||||
|
||||
+23
-17
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user