From: Andreas Steffen Date: Fri, 21 Apr 2023 14:04:26 +0000 (+0200) Subject: cert_cache: Replace cached stale OCSP responses in-place X-Git-Tag: 5.9.11dr3~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=47e8b21c76366dcdfb1064fb4e1fdb619e684684;p=thirdparty%2Fstrongswan.git cert_cache: Replace cached stale OCSP responses in-place --- diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c index d2ea0630cf..b5b1b29642 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.c +++ b/src/libstrongswan/credentials/sets/cert_cache.c @@ -23,6 +23,7 @@ #include #include #include +#include /** cache size, a power of 2 for fast modulo */ #define CACHE_SIZE 32 @@ -128,6 +129,55 @@ static void cache(private_cert_cache_t *this, } } } + else if (subject->get_type(subject) == CERT_X509_OCSP_RESPONSE) + { + ocsp_response_t *response, *cached_response; + enumerator_t *e, *e1; + chunk_t serial, serial_cached; + + response = (ocsp_response_t*)subject; + + /* we only check OCSP responses containing one single response */ + e = response->create_response_enumerator(response); + if (e->enumerate(e, &serial, NULL, NULL, NULL) && + !e->enumerate(e, NULL, NULL, NULL, NULL)) + { + for (i = 0; i < CACHE_SIZE; i++) + { + rel = &this->relations[i]; + + if (rel->subject && + rel->subject->get_type(rel->subject) == CERT_X509_OCSP_RESPONSE && + rel->lock->try_write_lock(rel->lock)) + { + /* double-check having lock */ + if (rel->subject->get_type(rel->subject) == CERT_X509_OCSP_RESPONSE && + rel->issuer->equals(rel->issuer, issuer) && + certificate_is_newer(subject, rel->subject)) + { + cached_response = (ocsp_response_t*)rel->subject; + + e1 = cached_response->create_response_enumerator(cached_response); + if (e1->enumerate(e1, &serial_cached, NULL, NULL, NULL) && + !e1->enumerate(e1, NULL, NULL, NULL, NULL) && + chunk_equals(serial_cached, serial)) + { + e1->destroy(e1); + e->destroy(e); + rel->subject->destroy(rel->subject); + rel->subject = subject->get_ref(subject); + signature_params_destroy(rel->scheme); + rel->scheme = signature_params_clone(scheme); + return rel->lock->unlock(rel->lock); + } + e1->destroy(e1); + } + rel->lock->unlock(rel->lock); + } + } + } + e->destroy(e); + } /* check for a unused relation slot first */ for (i = 0; i < CACHE_SIZE; i++)