Commit cfb83640 authored by Vincent Pelletier's avatar Vincent Pelletier

cli: Fix CRL renewal.

Load CRL expiration date even when it has not just been renewed.
Also, request a newer CRL before local one expires (7 days by
default).
parent 2e401b99
Pipeline #9764 passed with stage
in 0 seconds
...@@ -707,6 +707,13 @@ def updater(argv=None, until=utils.until): ...@@ -707,6 +707,13 @@ def updater(argv=None, until=utils.until):
help='The remaining certificate validity period, in days, under ' help='The remaining certificate validity period, in days, under '
'which a renew is desired. default: %(default)s', 'which a renew is desired. default: %(default)s',
) )
parser.add_argument(
'--crl-threshold',
default=7,
type=float,
help='The remaining certificate revocation validity period, in days, '
'under which a new one is requested. default: %(default)s',
)
parser.add_argument( parser.add_argument(
'--key-len', '--key-len',
default=2048, default=2048,
...@@ -783,6 +790,7 @@ def updater(argv=None, until=utils.until): ...@@ -783,6 +790,7 @@ def updater(argv=None, until=utils.until):
MODE_USER: args.ca_url + '/cau', MODE_USER: args.ca_url + '/cau',
}[args.mode] }[args.mode]
threshold = datetime.timedelta(args.threshold, 0) threshold = datetime.timedelta(args.threshold, 0)
crl_threshold = datetime.timedelta(args.crl_threshold, 0)
max_sleep = datetime.timedelta(args.max_sleep, 0) max_sleep = datetime.timedelta(args.max_sleep, 0)
updated = RetryingCaucaseClient.updateCAFile( updated = RetryingCaucaseClient.updateCAFile(
cas_url, cas_url,
...@@ -846,11 +854,14 @@ def updater(argv=None, until=utils.until): ...@@ -846,11 +854,14 @@ def updater(argv=None, until=utils.until):
if RetryingCaucaseClient.updateCRLFile(ca_url, args.crl, ca_crt_list): if RetryingCaucaseClient.updateCRLFile(ca_url, args.crl, ca_crt_list):
print(b'Got new CRL') print(b'Got new CRL')
updated = True updated = True
with open(args.crl, 'rb') as crl_file: with open(args.crl, 'rb') as crl_file:
next_deadline = min( next_deadline = min(
next_deadline, next_deadline,
utils.load_crl(crl_file.read(), ca_crt_list).next_update, utils.load_crl(
) crl_file.read(),
ca_crt_list,
).next_update - crl_threshold,
)
if args.crt: if args.crt:
crt_pem, key_pem, key_path = utils.getKeyPair(args.crt, args.key) crt_pem, key_pem, key_path = utils.getKeyPair(args.crt, args.key)
crt = utils.load_certificate(crt_pem, ca_crt_list, None) crt = utils.load_certificate(crt_pem, ca_crt_list, None)
......
...@@ -233,6 +233,7 @@ class UntilEvent(object): ...@@ -233,6 +233,7 @@ class UntilEvent(object):
self._action = ON_EVENT_RAISE self._action = ON_EVENT_RAISE
self._wait_event = threading.Event() self._wait_event = threading.Event()
self._wait_event.clear() self._wait_event.clear()
self._deadline = None
@property @property
def action(self): def action(self):
...@@ -250,6 +251,17 @@ class UntilEvent(object): ...@@ -250,6 +251,17 @@ class UntilEvent(object):
raise ValueError # pragma: no cover raise ValueError # pragma: no cover
self._action = value self._action = value
@property
def deadline(self):
"""
Retrieve the deadline parameter given to latest call.
Only valid after a "wait" call returned successfully, and before wakeup
event gets set.
"""
result = self._deadline
assert result is not None
return result
def wait(self, timeout=10): def wait(self, timeout=10):
""" """
Wait for event to be waited upon at least once. Wait for event to be waited upon at least once.
...@@ -268,8 +280,10 @@ class UntilEvent(object): ...@@ -268,8 +280,10 @@ class UntilEvent(object):
""" """
now = datetime.datetime.utcnow() now = datetime.datetime.utcnow()
if now < deadline: if now < deadline:
self._deadline = deadline
self._wait_event.set() self._wait_event.set()
assert self._event.wait(10) assert self._event.wait(10)
self._deadline = None
self._event.clear() self._event.clear()
if self._action is ON_EVENT_EXPIRE: if self._action is ON_EVENT_EXPIRE:
now = deadline now = deadline
...@@ -2812,6 +2826,17 @@ class CaucaseTest(unittest.TestCase): ...@@ -2812,6 +2826,17 @@ class CaucaseTest(unittest.TestCase):
until_updater.wait() until_updater.wait()
# It must have retrieved the certificate now. # It must have retrieved the certificate now.
self.assertTrue(os.path.exists(re_crt_path)) self.assertTrue(os.path.exists(re_crt_path))
# Next wakeup should be 7 days before CRL expiration (default delay)
crl_renewal = self._getClientCRL().next_update - datetime.timedelta(7, 0)
# Give +/-5 seconds of leeway.
crl_tolerance = datetime.timedelta(0, 5)
self.assertGreater(
until_updater.deadline, crl_renewal - crl_tolerance,
)
self.assertLess(
until_updater.deadline, crl_renewal + crl_tolerance,
)
finally: finally:
until_updater.action = ON_EVENT_RAISE until_updater.action = ON_EVENT_RAISE
updater_event.set() updater_event.set()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment