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):
help='The remaining certificate validity period, in days, under '
'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(
'--key-len',
default=2048,
......@@ -783,6 +790,7 @@ def updater(argv=None, until=utils.until):
MODE_USER: args.ca_url + '/cau',
}[args.mode]
threshold = datetime.timedelta(args.threshold, 0)
crl_threshold = datetime.timedelta(args.crl_threshold, 0)
max_sleep = datetime.timedelta(args.max_sleep, 0)
updated = RetryingCaucaseClient.updateCAFile(
cas_url,
......@@ -846,11 +854,14 @@ def updater(argv=None, until=utils.until):
if RetryingCaucaseClient.updateCRLFile(ca_url, args.crl, ca_crt_list):
print(b'Got new CRL')
updated = True
with open(args.crl, 'rb') as crl_file:
next_deadline = min(
next_deadline,
utils.load_crl(crl_file.read(), ca_crt_list).next_update,
)
with open(args.crl, 'rb') as crl_file:
next_deadline = min(
next_deadline,
utils.load_crl(
crl_file.read(),
ca_crt_list,
).next_update - crl_threshold,
)
if args.crt:
crt_pem, key_pem, key_path = utils.getKeyPair(args.crt, args.key)
crt = utils.load_certificate(crt_pem, ca_crt_list, None)
......
......@@ -233,6 +233,7 @@ class UntilEvent(object):
self._action = ON_EVENT_RAISE
self._wait_event = threading.Event()
self._wait_event.clear()
self._deadline = None
@property
def action(self):
......@@ -250,6 +251,17 @@ class UntilEvent(object):
raise ValueError # pragma: no cover
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):
"""
Wait for event to be waited upon at least once.
......@@ -268,8 +280,10 @@ class UntilEvent(object):
"""
now = datetime.datetime.utcnow()
if now < deadline:
self._deadline = deadline
self._wait_event.set()
assert self._event.wait(10)
self._deadline = None
self._event.clear()
if self._action is ON_EVENT_EXPIRE:
now = deadline
......@@ -2812,6 +2826,17 @@ class CaucaseTest(unittest.TestCase):
until_updater.wait()
# It must have retrieved the certificate now.
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:
until_updater.action = ON_EVENT_RAISE
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