Newer CRLs replace older versions of the CRL in the cache
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 26 Oct 2016 10:48:54 +0000 (12:48 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 26 Oct 2016 10:48:54 +0000 (12:48 +0200)
src/libstrongswan/credentials/sets/cert_cache.c

index 60720dc..9770c96 100644 (file)
@@ -20,6 +20,7 @@
 #include <library.h>
 #include <threading/rwlock.h>
 #include <collections/linked_list.h>
+#include <credentials/certificates/crl.h>
 
 /** cache size, a power of 2 for fast modulo */
 #define CACHE_SIZE 32
@@ -88,6 +89,44 @@ static void cache(private_cert_cache_t *this,
        int i, offset, try;
        u_int total_hits = 0;
 
+       /* cache a CRL by replacing a previous CRL cache entry if present */
+       if (subject->get_type(subject) == CERT_X509_CRL)
+       {
+               bool is_delta_crl;
+               crl_t *crl, *cached_crl;
+
+               /* cache a delta CRL ? */
+               crl = (crl_t*)subject;
+               is_delta_crl = crl->is_delta_crl(crl, NULL);
+
+               for (i = 0; i < CACHE_SIZE; i++)
+               {
+                       rel = &this->relations[i];
+
+                       if (rel->subject &&
+                               rel->subject->get_type(rel->subject) == CERT_X509_CRL &&
+                               rel->lock->try_write_lock(rel->lock))
+                       {
+                               /* double-check having lock */
+                               if (rel->subject->get_type(rel->subject) == CERT_X509_CRL &&
+                                       rel->issuer->equals(rel->issuer, issuer))
+                               {
+                                       cached_crl = (crl_t*)rel->subject;
+
+                                       if (cached_crl->is_delta_crl(crl, NULL) == is_delta_crl &&
+                                               crl_is_newer(crl, cached_crl))
+                                       {
+                                               rel->subject->destroy(rel->subject);
+                                               rel->subject = subject->get_ref(subject);
+                                               rel->scheme = scheme;
+                                               return rel->lock->unlock(rel->lock);
+                                       }
+                               }
+                               rel->lock->unlock(rel->lock);
+                       }
+               }
+       }
+
        /* check for a unused relation slot first */
        for (i = 0; i < CACHE_SIZE; i++)
        {