Commit ba693499 authored by Vincent Pelletier's avatar Vincent Pelletier

ca: Add clock desynchronisation tolerance.

Issue certificates and revocation lists a few seconds in the past of the
true issuance time, to allow the client to be a bit in the past compared
to the server. Otherwise, the client would receive a "not valid yet"
certificate or CRL, which could crash it (es: caucase-update). Which
normally is intended (so time attacks are noticed), but in this case is
counter-productive.
parent ad67ffb2
Pipeline #24404 failed with stage
in 0 seconds
......@@ -2,6 +2,7 @@
==================
* Janitorial: make updated code checkers happier.
* Explicitly depend on ipaddress module on python 2.7 .
* Be less sensitive to small client/server time disagreements.
0.9.13 (2021-12-22)
===================
......
......@@ -62,6 +62,11 @@ _CONFIG_NAME_AUTO_SIGN_CSR_AMOUNT = 'auto_sign_csr_amount'
DEFAULT_BACKUP_SYMETRIC_CIPHER = 'aes256_cbc_pkcs7_hmac_10M_sha256'
# Back-date all timestamped values by this much, to accomodate slight
# desynchronisations between the local machine and the client's.
# This must be kept as small as possible, but cannot realistically be zero.
DESYNCHORNISATION_TOLERANCE = datetime.timedelta(seconds=10)
def Extension(value, critical):
"""
Avoid oid redundant parameter when creating an extension.
......@@ -324,7 +329,7 @@ class CertificateAuthority(object):
ca_crt = ca_key_pair['crt']
public_key = csr.public_key()
now = datetime.datetime.utcnow()
now = datetime.datetime.utcnow() - DESYNCHORNISATION_TOLERANCE
builder = x509.CertificateBuilder(
subject_name=template_csr.subject,
issuer_name=ca_crt.subject,
......@@ -551,7 +556,7 @@ class CertificateAuthority(object):
),
] + self._ca_extension_list
public_key = private_key.public_key()
now = datetime.datetime.utcnow()
now = datetime.datetime.utcnow() - DESYNCHORNISATION_TOLERANCE
crt_builder = x509.CertificateBuilder(
subject_name=subject,
issuer_name=subject,
......@@ -790,7 +795,7 @@ class CertificateAuthority(object):
):
# We cannot use the existing CRL (or maybe none exist), generate a
# new one.
last_update = now
last_update = now - DESYNCHORNISATION_TOLERANCE
crl_number = storage.getNextCertificateRevocationListNumber()
storage.storeCRLLastUpdate(
last_update=utils.datetime2timestamp(last_update),
......@@ -799,6 +804,7 @@ class CertificateAuthority(object):
revoked_certificate_list = [
x509.RevokedCertificateBuilder(
serial_number=x['serial'],
# XXX: cap this value to last_update ?
revocation_date=utils.timestamp2datetime(x['revocation_date']),
).build(_cryptography_backend)
for x in storage.getRevocationList()
......
......@@ -1283,7 +1283,10 @@ class CaucaseTest(TestCase):
self._runClient()
new_crl, = self._getClientCRLList()
# May be equal due to lack of timestamp accuracy.
self.assertLessEqual(now, new_crl.last_update)
self.assertLessEqual(
now - caucase.ca.DESYNCHORNISATION_TOLERANCE,
new_crl.last_update,
)
def testBadCSR(self):
"""
......
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