sync CRLs if one in the cache is out of date

This commit is contained in:
dandds
2019-02-26 11:12:29 -05:00
parent b420ff2e5b
commit 22af868557
3 changed files with 145 additions and 97 deletions

View File

@@ -50,10 +50,10 @@ def make_app(config):
app.config.update({"SESSION_REDIS": app.redis})
make_flask_callbacks(app)
make_crl_validator(app)
register_filters(app)
make_eda_client(app)
make_csp_provider(app)
make_crl_validator(app)
make_mailer(app)
queue.init_app(app)
@@ -203,7 +203,10 @@ def make_crl_validator(app):
for filename in pathlib.Path(app.config["CRL_CONTAINER"]).glob("*.crl"):
crl_locations.append(filename.absolute())
app.crl_cache = CRLCache(
app.config["CA_CHAIN"], crl_locations, logger=app.logger
app.config["CA_CHAIN"],
crl_locations,
logger=app.logger,
crl_update_func=app.csp.crls.sync_crls,
)

View File

@@ -2,6 +2,7 @@ import sys
import os
import re
import hashlib
from datetime import datetime
from OpenSSL import crypto, SSL
@@ -56,13 +57,20 @@ class CRLCache(CRLInterface):
)
def __init__(
self, root_location, crl_locations=[], store_class=crypto.X509Store, logger=None
self,
root_location,
crl_locations=[],
store_class=crypto.X509Store,
logger=None,
crl_update_func=None,
):
self._crl_locations = crl_locations
self.logger = logger
self.store_class = store_class
self.certificate_authorities = {}
self._crl_update_func = crl_update_func
self._load_roots(root_location)
self._build_crl_cache(crl_locations)
self._build_crl_cache()
def _get_store(self, cert):
return self._build_store(cert.get_issuer())
@@ -76,9 +84,9 @@ class CRLCache(CRLInterface):
def _parse_roots(self, root_str):
return [match.group(0) for match in self._PEM_RE.finditer(root_str)]
def _build_crl_cache(self, crl_locations):
def _build_crl_cache(self):
self.crl_cache = {}
for crl_location in crl_locations:
for crl_location in self._crl_locations:
crl = self._load_crl(crl_location)
if crl:
issuer_der = crl.get_issuer().der()
@@ -109,6 +117,8 @@ class CRLCache(CRLInterface):
)
)
self._manage_expiring(crl_info["expires"])
crl = self._load_crl(crl_info["location"])
store.add_crl(crl)
@@ -121,6 +131,17 @@ class CRLCache(CRLInterface):
store = self._add_certificate_chain_to_store(store, crl.get_issuer())
return store
def _manage_expiring(self, crl_expiry):
"""
If a CRL is expired and CRLCache has been given a function for updating
the physical CRL locations, run the update function and then rebuild
the CRL cache.
"""
current = datetime.now(crl_expiry.tzinfo)
if self._crl_update_func and current > crl_expiry:
self._crl_update_func()
self._build_crl_cache()
# this _should_ happen just twice for the DoD PKI (intermediary, root) but
# theoretically it can build a longer certificate chain