support cachecrls=yes
This commit is contained in:
@@ -92,9 +92,10 @@ struct private_ca_info_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* static value set by ca_info_set_crl()
|
||||
* static options set by ca_info_set_options()
|
||||
*/
|
||||
static crl_check_interval = 0;
|
||||
static bool cache_crls = FALSE;
|
||||
static u_int crl_check_interval = 0;
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.equals
|
||||
@@ -378,11 +379,63 @@ static x509_t* get_certificate(private_ca_info_t* this)
|
||||
return this->cacert;
|
||||
}
|
||||
|
||||
/**
|
||||
* caches a crl by saving it to a given crl directory
|
||||
*/
|
||||
void cache_crl(private_ca_info_t* this, const char *crl_dir, crl_t *crl)
|
||||
{
|
||||
char buffer[BUF_LEN];
|
||||
char *path;
|
||||
char *pos = buffer;
|
||||
int len = BUF_LEN;
|
||||
int n;
|
||||
|
||||
chunk_t authKeyID = this->cacert->get_subjectKeyID(this->cacert);
|
||||
chunk_t uri;
|
||||
|
||||
uri.ptr = buffer;
|
||||
uri.len = 7 + strlen(crl_dir) + 1 + 2*authKeyID.len + 4;
|
||||
|
||||
if (uri.len >= BUF_LEN)
|
||||
{
|
||||
DBG1("file uri exceeds buffer length of %d bytes - crl not saved", BUF_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
/* print the file uri prefix */
|
||||
n = snprintf(pos, len, "file://");
|
||||
pos += n; len -= n;
|
||||
|
||||
/* remember the start of the path string */
|
||||
path = pos;
|
||||
|
||||
/* print the default crl directory path */
|
||||
n = snprintf(pos, len, "%s/", crl_dir);
|
||||
pos += n; len -= n;
|
||||
|
||||
/* create and print a unique crl filename derived from the authKeyID */
|
||||
while (authKeyID.len-- > 0)
|
||||
{
|
||||
n = snprintf(pos, len, "%02x", *authKeyID.ptr++);
|
||||
pos += n; len -= n;
|
||||
}
|
||||
|
||||
/* add the file suffix */
|
||||
n = snprintf(pos, len, ".crl");
|
||||
|
||||
if (crl->write_to_file(crl, path, 0022, TRUE))
|
||||
{
|
||||
identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
|
||||
|
||||
add_identification(this->crluris, crluri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.verify_by_crl.
|
||||
*/
|
||||
static cert_status_t verify_by_crl(private_ca_info_t* this,
|
||||
certinfo_t *certinfo)
|
||||
static cert_status_t verify_by_crl(private_ca_info_t* this, certinfo_t *certinfo,
|
||||
const char *crl_dir)
|
||||
{
|
||||
rsa_public_key_t *issuer_public_key = this->cacert->get_public_key(this->cacert);
|
||||
bool stale;
|
||||
@@ -448,20 +501,25 @@ static cert_status_t verify_by_crl(private_ca_info_t* this,
|
||||
this->crl->destroy(this->crl);
|
||||
this->crl = crl;
|
||||
DBG1(" thisUpdate is newer - existing crl replaced");
|
||||
if (this->crl->is_valid(this->crl))
|
||||
{
|
||||
/* we found a valid crl and exit the fetch loop */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("fetched crl is stale");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
crl->destroy(crl);
|
||||
DBG1("thisUpdate is not newer - existing crl retained");
|
||||
continue;
|
||||
}
|
||||
if (crl->is_valid(crl))
|
||||
{
|
||||
if (cache_crls && strncasecmp(uri_string, "file", 4) != 0)
|
||||
{
|
||||
cache_crl(this, crl_dir, crl);
|
||||
}
|
||||
/* we found a valid crl and therefore exit the fetch loop */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("fetched crl is stale");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -682,8 +740,9 @@ static void __attribute__ ((constructor))print_register()
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
void ca_info_set_crlcheckinterval(u_int interval)
|
||||
void ca_info_set_options(bool cache, u_int interval)
|
||||
{
|
||||
cache_crls = cache;
|
||||
crl_check_interval = interval;
|
||||
}
|
||||
|
||||
@@ -720,7 +779,7 @@ ca_info_t *ca_info_create(const char *name, x509_t *cacert)
|
||||
this->public.add_crluri = (void (*) (ca_info_t*,chunk_t))add_crluri;
|
||||
this->public.add_ocspuri = (void (*) (ca_info_t*,chunk_t))add_ocspuri;
|
||||
this->public.get_certificate = (x509_t* (*) (ca_info_t*))get_certificate;
|
||||
this->public.verify_by_crl = (cert_status_t (*) (ca_info_t*,certinfo_t*))verify_by_crl;
|
||||
this->public.verify_by_crl = (cert_status_t (*) (ca_info_t*,certinfo_t*, const char*))verify_by_crl;
|
||||
this->public.verify_by_ocsp = (cert_status_t (*) (ca_info_t*,certinfo_t*,credential_store_t*))verify_by_ocsp;
|
||||
this->public.purge_ocsp = (void (*) (ca_info_t*))purge_ocsp;
|
||||
this->public.destroy = (void (*) (ca_info_t*))destroy;
|
||||
|
||||
@@ -161,9 +161,10 @@ struct ca_info_t {
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param certinfo detailed certificate status information
|
||||
* @param crl_dir directory where fetched crls should be stored
|
||||
* @return certificate status
|
||||
*/
|
||||
cert_status_t (*verify_by_crl) (ca_info_t* this, certinfo_t* certinfo);
|
||||
cert_status_t (*verify_by_crl) (ca_info_t *this, certinfo_t *certinfo, const char *crl_dir);
|
||||
|
||||
/**
|
||||
* @brief Verify the status of a certificate by OCSP
|
||||
@@ -191,13 +192,14 @@ struct ca_info_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a ca info record
|
||||
* @brief Set ca info options
|
||||
*
|
||||
* @param cache TRUE if crls shall be cached by storing them
|
||||
* @param interval crl_check_interval to be set in seconds
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
void ca_info_set_crlcheckinterval(u_int interval);
|
||||
void ca_info_set_options(bool cache, u_int interval);
|
||||
|
||||
/**
|
||||
* @brief Create a ca info record
|
||||
|
||||
@@ -394,6 +394,14 @@ static void get_status(const private_crl_t *this, certinfo_t *certinfo)
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.write_to_file.
|
||||
*/
|
||||
static bool write_to_file(private_crl_t *this, const char *path, mode_t mask, bool force)
|
||||
{
|
||||
return chunk_write(this->certificateList, path, "crl", mask, force);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.destroy
|
||||
*/
|
||||
@@ -493,6 +501,7 @@ crl_t *crl_create_from_chunk(chunk_t chunk)
|
||||
this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer;
|
||||
this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify;
|
||||
this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
|
||||
this->public.write_to_file = (bool (*) (const crl_t*,const char*,mode_t,bool))write_to_file;
|
||||
this->public.destroy = (void (*) (crl_t*))destroy;
|
||||
|
||||
if (!parse_x509crl(chunk, 0, this))
|
||||
|
||||
@@ -105,6 +105,17 @@ struct crl_t {
|
||||
*/
|
||||
void (*get_status) (const crl_t *this, certinfo_t *certinfo);
|
||||
|
||||
/**
|
||||
* @brief Write a der-encoded crl to a file
|
||||
*
|
||||
* @param this calling object
|
||||
* @param path path where the file is to be stored
|
||||
* @param mask file access control rights
|
||||
* @param force overwrite the file if it already exists
|
||||
* @return TRUE if successfully written
|
||||
*/
|
||||
bool (*write_to_file) (const crl_t *this, const char *path, mode_t mask, bool force);
|
||||
|
||||
/**
|
||||
* @brief Destroys the crl.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user