From 1a4272f11a8a0c46eba496c172f0742e2eb76d38 Mon Sep 17 00:00:00 2001 From: Kishi85 Date: Fri, 21 Jun 2019 10:45:43 +0200 Subject: [PATCH] authority.v2: invalidate nonces after 2 minutes and re-request Boulder seems to invalidate older nonces after some time. Therefore we allow nonces from the cache to be used for up to 2 minutes and after those they will be considered invalid (and re-requested with an extra request to the nonce endpoint when necessary) --- acertmgr/authority/v2.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/acertmgr/authority/v2.py b/acertmgr/authority/v2.py index 763c293..4031887 100644 --- a/acertmgr/authority/v2.py +++ b/acertmgr/authority/v2.py @@ -14,6 +14,9 @@ from acertmgr import tools from acertmgr.authority.acme import ACMEAuthority as AbstractACMEAuthority from acertmgr.tools import log +# Maximum age for nonce values (Boulder invalidates them after some time, so we use a low value of 2 minutes here) +MAX_NONCE_AGE = 120 + class ACMEAuthority(AbstractACMEAuthority): # @brief Init class with config @@ -45,6 +48,7 @@ class ACMEAuthority(AbstractACMEAuthority): log("API directory retrieval failed ({}). Guessed necessary values: {}".format(code, self.directory), warning=True) self.nonce = None + self.nonce_time = 0 self.algorithm, jwk = tools.get_key_alg_and_jwk(key) self.account_protected = { @@ -71,6 +75,7 @@ class ACMEAuthority(AbstractACMEAuthority): # Store next Replay-Nonce if it is in the header if 'Replay-Nonce' in resp.headers: self.nonce = resp.headers['Replay-Nonce'] + self.nonce_time = time.time() body = resp.read() if getattr(body, 'decode', None): @@ -95,7 +100,7 @@ class ACMEAuthority(AbstractACMEAuthority): payload64 = "" # for POST-as-GET # Request a new nonce if there is none in cache - if not self.nonce: + if not self.nonce or time.time() > self.nonce_time + MAX_NONCE_AGE: self._request_url(self.directory['newNonce']) # Set request nonce to current cache value protected["nonce"] = self.nonce