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 @@ ...@@ -2,6 +2,7 @@
================== ==================
* Janitorial: make updated code checkers happier. * Janitorial: make updated code checkers happier.
* Explicitly depend on ipaddress module on python 2.7 . * Explicitly depend on ipaddress module on python 2.7 .
* Be less sensitive to small client/server time disagreements.
0.9.13 (2021-12-22) 0.9.13 (2021-12-22)
=================== ===================
......
...@@ -62,6 +62,11 @@ _CONFIG_NAME_AUTO_SIGN_CSR_AMOUNT = 'auto_sign_csr_amount' ...@@ -62,6 +62,11 @@ _CONFIG_NAME_AUTO_SIGN_CSR_AMOUNT = 'auto_sign_csr_amount'
DEFAULT_BACKUP_SYMETRIC_CIPHER = 'aes256_cbc_pkcs7_hmac_10M_sha256' 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): def Extension(value, critical):
""" """
Avoid oid redundant parameter when creating an extension. Avoid oid redundant parameter when creating an extension.
...@@ -324,7 +329,7 @@ class CertificateAuthority(object): ...@@ -324,7 +329,7 @@ class CertificateAuthority(object):
ca_crt = ca_key_pair['crt'] ca_crt = ca_key_pair['crt']
public_key = csr.public_key() public_key = csr.public_key()
now = datetime.datetime.utcnow() now = datetime.datetime.utcnow() - DESYNCHORNISATION_TOLERANCE
builder = x509.CertificateBuilder( builder = x509.CertificateBuilder(
subject_name=template_csr.subject, subject_name=template_csr.subject,
issuer_name=ca_crt.subject, issuer_name=ca_crt.subject,
...@@ -551,7 +556,7 @@ class CertificateAuthority(object): ...@@ -551,7 +556,7 @@ class CertificateAuthority(object):
), ),
] + self._ca_extension_list ] + self._ca_extension_list
public_key = private_key.public_key() public_key = private_key.public_key()
now = datetime.datetime.utcnow() now = datetime.datetime.utcnow() - DESYNCHORNISATION_TOLERANCE
crt_builder = x509.CertificateBuilder( crt_builder = x509.CertificateBuilder(
subject_name=subject, subject_name=subject,
issuer_name=subject, issuer_name=subject,
...@@ -790,7 +795,7 @@ class CertificateAuthority(object): ...@@ -790,7 +795,7 @@ class CertificateAuthority(object):
): ):
# We cannot use the existing CRL (or maybe none exist), generate a # We cannot use the existing CRL (or maybe none exist), generate a
# new one. # new one.
last_update = now last_update = now - DESYNCHORNISATION_TOLERANCE
crl_number = storage.getNextCertificateRevocationListNumber() crl_number = storage.getNextCertificateRevocationListNumber()
storage.storeCRLLastUpdate( storage.storeCRLLastUpdate(
last_update=utils.datetime2timestamp(last_update), last_update=utils.datetime2timestamp(last_update),
...@@ -799,6 +804,7 @@ class CertificateAuthority(object): ...@@ -799,6 +804,7 @@ class CertificateAuthority(object):
revoked_certificate_list = [ revoked_certificate_list = [
x509.RevokedCertificateBuilder( x509.RevokedCertificateBuilder(
serial_number=x['serial'], serial_number=x['serial'],
# XXX: cap this value to last_update ?
revocation_date=utils.timestamp2datetime(x['revocation_date']), revocation_date=utils.timestamp2datetime(x['revocation_date']),
).build(_cryptography_backend) ).build(_cryptography_backend)
for x in storage.getRevocationList() for x in storage.getRevocationList()
......
...@@ -1283,7 +1283,10 @@ class CaucaseTest(TestCase): ...@@ -1283,7 +1283,10 @@ class CaucaseTest(TestCase):
self._runClient() self._runClient()
new_crl, = self._getClientCRLList() new_crl, = self._getClientCRLList()
# May be equal due to lack of timestamp accuracy. # 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): 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