aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2007-04-03 21:09:11 +0000
committerAndreas Steffen <andreas.steffen@strongswan.org>2007-04-03 21:09:11 +0000
commita8f02ad5f5f9a15c22cc2371818022a3c1b5e41c (patch)
tree46d7f9d6f37e91de6e144950f77d65314e63c7ac
parentf166af2c0a6503a1304e79d8c169ade35e9ebfb6 (diff)
downloadstrongswan-a8f02ad5f5f9a15c22cc2371818022a3c1b5e41c.tar.bz2
strongswan-a8f02ad5f5f9a15c22cc2371818022a3c1b5e41c.tar.xz
implemented dynamic http-based CRL fetching
-rw-r--r--src/libstrongswan/crypto/ca.c94
-rw-r--r--src/libstrongswan/crypto/ca.h6
-rwxr-xr-xsrc/libstrongswan/crypto/crl.c16
-rwxr-xr-xsrc/libstrongswan/crypto/crl.h6
4 files changed, 84 insertions, 38 deletions
diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c
index 36c8530ca..f437b6ba5 100644
--- a/src/libstrongswan/crypto/ca.c
+++ b/src/libstrongswan/crypto/ca.c
@@ -36,6 +36,7 @@
#include <debug.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
+#include <utils/fetcher.h>
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.
*/
-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)
{
- bool valid_signature;
- rsa_public_key_t *issuer_public_key;
-
+ bool stale;
pthread_mutex_lock(&(this->mutex));
if (this->crl == NULL)
{
+ stale = TRUE;
DBG1("crl not found");
- goto err;
}
- DBG2("crl found");
-
- issuer_public_key = this->cacert->get_public_key(this->cacert);
- valid_signature = this->crl->verify(this->crl, issuer_public_key);
+ else
+ {
+ stale = !this->crl->is_valid(this->crl);
+ DBG1("crl is %s", stale? "stale":"valid");
+ }
- if (!valid_signature)
+ if (stale)
{
- DBG1("crl signature is invalid");
- goto err;
+ 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);
}
- DBG2("crl signature is valid");
+ {
+ 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);
-err:
+ret:
pthread_mutex_unlock(&(this->mutex));
return certinfo->get_status(certinfo);
}
@@ -412,7 +473,6 @@ err:
* Implements ca_info_t.verify_by_ocsp.
*/
static cert_status_t verify_by_ocsp(private_ca_info_t* this,
- const x509_t *cert,
certinfo_t *certinfo,
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_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*,const x509_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_crl = (cert_status_t (*) (ca_info_t*,certinfo_t*))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;
diff --git a/src/libstrongswan/crypto/ca.h b/src/libstrongswan/crypto/ca.h
index da51673f7..440ac4f0b 100644
--- a/src/libstrongswan/crypto/ca.h
+++ b/src/libstrongswan/crypto/ca.h
@@ -160,22 +160,20 @@ struct ca_info_t {
* @brief Verify the status of a certificate by CRL
*
* @param this ca info object
- * @param cert certificate to be verified
* @param certinfo detailed certificate status information
* @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
*
* @param this ca info object
- * @param cert certificate to be verified
* @param certinfo detailed certificate status information
* @param credentials credential store needed for trust path verification
* @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
diff --git a/src/libstrongswan/crypto/crl.c b/src/libstrongswan/crypto/crl.c
index 685ccfc8a..0b9fdaf4f 100755
--- a/src/libstrongswan/crypto/crl.c
+++ b/src/libstrongswan/crypto/crl.c
@@ -311,7 +311,7 @@ bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
/**
* 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);
@@ -319,17 +319,7 @@ static err_t is_valid(const private_crl_t *this, time_t *until, bool strict)
DBG2(" current time: %T", &current_time);
DBG2(" next update: %T", &this->nextUpdate);
- if (strict && until != NULL &&
- (*until == UNDEFINED_TIME || this->nextUpdate < *until))
- {
- *until = this->nextUpdate;
- }
- if (current_time > this->nextUpdate)
- {
- return "has expired";
- }
- DBG2(" crl is valid");
- return NULL;
+ return current_time < this->nextUpdate;
}
/**
@@ -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.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_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.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify;
this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
diff --git a/src/libstrongswan/crypto/crl.h b/src/libstrongswan/crypto/crl.h
index 216cafad0..48953ba78 100755
--- a/src/libstrongswan/crypto/crl.h
+++ b/src/libstrongswan/crypto/crl.h
@@ -75,11 +75,9 @@ struct crl_t {
* @brief Checks the validity interval of the crl
*
* @param this calling object
- * @param until until = min(until, nextUpdate) if strict == TRUE
- * @param strict nextUpdate restricts the validity
- * @return NULL if the crl is valid
+ * @return TRUE 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