Commit 0b871b56 authored by Vincent Pelletier's avatar Vincent Pelletier

ca: Make getCACertificate return the *oldest* still-valid CA cert.

This fixes late-trust-bootstrap clients' ability to trust certificates
issued by an older CA.
parent 3aefb18a
......@@ -142,6 +142,8 @@ Here is an illustration of the certificate and CA certificate renewal process::
|none |passive |active |passive |active |passive |...
Active CA: | | |
[ca v1 ][ca v2 ][ca v3 |...
Trust anchor: | | |
[ca v1 | ][ca v2 | ][ca v3 |...
Legend::
......
......@@ -620,9 +620,15 @@ class CertificateAuthority(object):
def getCACertificate(self):
"""
Return current CA certificate, PEM-encoded.
Return oldest still-valid CA certificate, PEM-encoded.
"""
return utils.dump_certificate(self._getCurrentCAKeypair()['crt'])
self._renewCAIfNeeded()
# XXX: _loadCAKeyPairList seems a bit too expensive for such simple operation.
# So do out-of-storage self._ca_key_pairs_list pruning only.
now = datetime.datetime.utcnow()
while self._ca_key_pairs_list[0]['crt'].not_valid_after <= now:
self._ca_key_pairs_list.pop(0)
return utils.dump_certificate(self._ca_key_pairs_list[0]['crt'])
def getCACertificateList(self):
"""
......
......@@ -1724,6 +1724,15 @@ class CaucaseTest(unittest.TestCase):
[x.serial_number for x in utils.load_crl(crl_pem_b, cau_ca_list)],
)
self.assertRaises(CaucaseError, _checkUserAccess, user2_key)
# A client without established trust anchor gets all still-valid CA
# certificates, not just the active one, so they can check still-valid
# certificates issued on the CA being retired.
os.unlink(self._client_user_ca_crt)
self._runClient('--mode', 'user')
self.assertItemsEqual(
[old_cau_pem, new_cau_pem],
utils.getCertList(self._client_user_ca_crt),
)
# The old CA is now fully expired
self._stopServer()
old_cau_pem = self._setCACertificateRemainingLifeTime(
......@@ -1744,6 +1753,13 @@ class CaucaseTest(unittest.TestCase):
self.assertRaises(CaucaseError, _checkUserAccess, user2_key)
# Renewed and non-revoked user certificate is accepted
_checkUserAccess(user3_key)
# A client without established trust anchor only gets valid CA certs.
os.unlink(self._client_user_ca_crt)
self._runClient('--mode', 'user')
self.assertItemsEqual(
[new_cau_pem],
utils.getCertList(self._client_user_ca_crt),
)
def testCaucasedCRLRenewal(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