mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-08 00:02:03 -04:00
implemented dynamic http-based CRL fetching
This commit is contained in:
parent
f166af2c0a
commit
a8f02ad5f5
@ -36,6 +36,7 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <utils/linked_list.h>
|
#include <utils/linked_list.h>
|
||||||
#include <utils/identification.h>
|
#include <utils/identification.h>
|
||||||
|
#include <utils/fetcher.h>
|
||||||
|
|
||||||
typedef struct private_ca_info_t private_ca_info_t;
|
typedef struct private_ca_info_t private_ca_info_t;
|
||||||
|
|
||||||
@ -375,35 +376,95 @@ static x509_t* get_certificate(private_ca_info_t* this)
|
|||||||
/**
|
/**
|
||||||
* Implements ca_info_t.verify_by_crl.
|
* Implements ca_info_t.verify_by_crl.
|
||||||
*/
|
*/
|
||||||
static cert_status_t verify_by_crl(private_ca_info_t* this, const x509_t *cert,
|
static cert_status_t verify_by_crl(private_ca_info_t* this,
|
||||||
certinfo_t *certinfo)
|
certinfo_t *certinfo)
|
||||||
{
|
{
|
||||||
bool valid_signature;
|
bool stale;
|
||||||
rsa_public_key_t *issuer_public_key;
|
|
||||||
|
|
||||||
|
|
||||||
pthread_mutex_lock(&(this->mutex));
|
pthread_mutex_lock(&(this->mutex));
|
||||||
|
|
||||||
if (this->crl == NULL)
|
if (this->crl == NULL)
|
||||||
{
|
{
|
||||||
|
stale = TRUE;
|
||||||
DBG1("crl not found");
|
DBG1("crl not found");
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
DBG2("crl found");
|
else
|
||||||
|
|
||||||
issuer_public_key = this->cacert->get_public_key(this->cacert);
|
|
||||||
valid_signature = this->crl->verify(this->crl, issuer_public_key);
|
|
||||||
|
|
||||||
if (!valid_signature)
|
|
||||||
{
|
{
|
||||||
DBG1("crl signature is invalid");
|
stale = !this->crl->is_valid(this->crl);
|
||||||
goto err;
|
DBG1("crl is %s", stale? "stale":"valid");
|
||||||
}
|
}
|
||||||
DBG2("crl signature is valid");
|
|
||||||
|
|
||||||
|
if (stale)
|
||||||
|
{
|
||||||
|
iterator_t *iterator = this->crluris->create_iterator(this->crluris, TRUE);
|
||||||
|
identification_t *uri;
|
||||||
|
|
||||||
|
while (iterator->iterate(iterator, (void**)&uri))
|
||||||
|
{
|
||||||
|
fetcher_t *fetcher;
|
||||||
|
char uri_string[BUF_LEN];
|
||||||
|
chunk_t uri_chunk = uri->get_encoding(uri);
|
||||||
|
chunk_t response_chunk;
|
||||||
|
|
||||||
|
snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
|
||||||
|
fetcher = fetcher_create(uri_string);
|
||||||
|
|
||||||
|
response_chunk = fetcher->get(fetcher);
|
||||||
|
fetcher->destroy(fetcher);
|
||||||
|
if (response_chunk.ptr != NULL)
|
||||||
|
{
|
||||||
|
crl_t *crl = crl_create_from_chunk(response_chunk);
|
||||||
|
|
||||||
|
if (crl)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1("fetched crl is stale");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crl->destroy(crl);
|
||||||
|
DBG1(" thisUpdate is not newer - existing crl retained");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(response_chunk.ptr);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
DBG1("crl signature is invalid");
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
DBG2("crl signature is valid");
|
||||||
|
}
|
||||||
this->crl->get_status(this->crl, certinfo);
|
this->crl->get_status(this->crl, certinfo);
|
||||||
|
|
||||||
err:
|
ret:
|
||||||
pthread_mutex_unlock(&(this->mutex));
|
pthread_mutex_unlock(&(this->mutex));
|
||||||
return certinfo->get_status(certinfo);
|
return certinfo->get_status(certinfo);
|
||||||
}
|
}
|
||||||
@ -412,7 +473,6 @@ err:
|
|||||||
* Implements ca_info_t.verify_by_ocsp.
|
* Implements ca_info_t.verify_by_ocsp.
|
||||||
*/
|
*/
|
||||||
static cert_status_t verify_by_ocsp(private_ca_info_t* this,
|
static cert_status_t verify_by_ocsp(private_ca_info_t* this,
|
||||||
const x509_t *cert,
|
|
||||||
certinfo_t *certinfo,
|
certinfo_t *certinfo,
|
||||||
credential_store_t *credentials)
|
credential_store_t *credentials)
|
||||||
{
|
{
|
||||||
@ -636,8 +696,8 @@ 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_crluri = (void (*) (ca_info_t*,chunk_t))add_crluri;
|
||||||
this->public.add_ocspuri = (void (*) (ca_info_t*,chunk_t))add_ocspuri;
|
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.get_certificate = (x509_t* (*) (ca_info_t*))get_certificate;
|
||||||
this->public.verify_by_crl = (cert_status_t (*) (ca_info_t*,const x509_t*,certinfo_t*))verify_by_crl;
|
this->public.verify_by_crl = (cert_status_t (*) (ca_info_t*,certinfo_t*))verify_by_crl;
|
||||||
this->public.verify_by_ocsp = (cert_status_t (*) (ca_info_t*,const x509_t*,certinfo_t*,credential_store_t*))verify_by_ocsp;
|
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.purge_ocsp = (void (*) (ca_info_t*))purge_ocsp;
|
||||||
this->public.destroy = (void (*) (ca_info_t*))destroy;
|
this->public.destroy = (void (*) (ca_info_t*))destroy;
|
||||||
|
|
||||||
|
@ -160,22 +160,20 @@ struct ca_info_t {
|
|||||||
* @brief Verify the status of a certificate by CRL
|
* @brief Verify the status of a certificate by CRL
|
||||||
*
|
*
|
||||||
* @param this ca info object
|
* @param this ca info object
|
||||||
* @param cert certificate to be verified
|
|
||||||
* @param certinfo detailed certificate status information
|
* @param certinfo detailed certificate status information
|
||||||
* @return certificate status
|
* @return certificate status
|
||||||
*/
|
*/
|
||||||
cert_status_t (*verify_by_crl) (ca_info_t* this, const x509_t* cert, certinfo_t* certinfo);
|
cert_status_t (*verify_by_crl) (ca_info_t* this, certinfo_t* certinfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Verify the status of a certificate by OCSP
|
* @brief Verify the status of a certificate by OCSP
|
||||||
*
|
*
|
||||||
* @param this ca info object
|
* @param this ca info object
|
||||||
* @param cert certificate to be verified
|
|
||||||
* @param certinfo detailed certificate status information
|
* @param certinfo detailed certificate status information
|
||||||
* @param credentials credential store needed for trust path verification
|
* @param credentials credential store needed for trust path verification
|
||||||
* @return certificate status
|
* @return certificate status
|
||||||
*/
|
*/
|
||||||
cert_status_t (*verify_by_ocsp) (ca_info_t* this, const x509_t* cert, certinfo_t* certinfo, credential_store_t* credentials);
|
cert_status_t (*verify_by_ocsp) (ca_info_t* this, certinfo_t* certinfo, credential_store_t* credentials);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Purge the OCSP certinfos of a ca info record
|
* @brief Purge the OCSP certinfos of a ca info record
|
||||||
|
@ -311,7 +311,7 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
|
|||||||
/**
|
/**
|
||||||
* Implements crl_t.is_valid
|
* Implements crl_t.is_valid
|
||||||
*/
|
*/
|
||||||
static err_t is_valid(const private_crl_t *this, time_t *until, bool strict)
|
static bool is_valid(const private_crl_t *this)
|
||||||
{
|
{
|
||||||
time_t current_time = time(NULL);
|
time_t current_time = time(NULL);
|
||||||
|
|
||||||
@ -319,17 +319,7 @@ static err_t is_valid(const private_crl_t *this, time_t *until, bool strict)
|
|||||||
DBG2(" current time: %T", ¤t_time);
|
DBG2(" current time: %T", ¤t_time);
|
||||||
DBG2(" next update: %T", &this->nextUpdate);
|
DBG2(" next update: %T", &this->nextUpdate);
|
||||||
|
|
||||||
if (strict && until != NULL &&
|
return current_time < this->nextUpdate;
|
||||||
(*until == UNDEFINED_TIME || this->nextUpdate < *until))
|
|
||||||
{
|
|
||||||
*until = this->nextUpdate;
|
|
||||||
}
|
|
||||||
if (current_time > this->nextUpdate)
|
|
||||||
{
|
|
||||||
return "has expired";
|
|
||||||
}
|
|
||||||
DBG2(" crl is valid");
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -499,7 +489,7 @@ crl_t *crl_create_from_chunk(chunk_t chunk)
|
|||||||
this->public.get_issuer = (identification_t* (*) (const crl_t*))get_issuer;
|
this->public.get_issuer = (identification_t* (*) (const crl_t*))get_issuer;
|
||||||
this->public.equals_issuer = (bool (*) (const crl_t*,const crl_t*))equals_issuer;
|
this->public.equals_issuer = (bool (*) (const crl_t*,const crl_t*))equals_issuer;
|
||||||
this->public.is_issuer = (bool (*) (const crl_t*,const x509_t*))is_issuer;
|
this->public.is_issuer = (bool (*) (const crl_t*,const x509_t*))is_issuer;
|
||||||
this->public.is_valid = (err_t (*) (const crl_t*,time_t*,bool))is_valid;
|
this->public.is_valid = (bool (*) (const crl_t*))is_valid;
|
||||||
this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer;
|
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.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.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
|
||||||
|
@ -75,11 +75,9 @@ struct crl_t {
|
|||||||
* @brief Checks the validity interval of the crl
|
* @brief Checks the validity interval of the crl
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @param until until = min(until, nextUpdate) if strict == TRUE
|
* @return TRUE if the crl is valid
|
||||||
* @param strict nextUpdate restricts the validity
|
|
||||||
* @return NULL if the crl is valid
|
|
||||||
*/
|
*/
|
||||||
err_t (*is_valid) (const crl_t *this, time_t *until, bool strict);
|
bool (*is_valid) (const crl_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if this crl is newer (thisUpdate) than the other crl
|
* @brief Checks if this crl is newer (thisUpdate) than the other crl
|
||||||
|
Loading…
x
Reference in New Issue
Block a user