diff options
Diffstat (limited to 'src/libstrongswan/crypto/ca.c')
-rw-r--r-- | src/libstrongswan/crypto/ca.c | 89 |
1 files changed, 74 insertions, 15 deletions
diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c index cf3d0eea6..4ec8c8430 100644 --- a/src/libstrongswan/crypto/ca.c +++ b/src/libstrongswan/crypto/ca.c @@ -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 @@ -379,10 +380,62 @@ static x509_t* get_certificate(private_ca_info_t* this) } /** + * 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; |