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:: ...@@ -142,6 +142,8 @@ Here is an illustration of the certificate and CA certificate renewal process::
|none |passive |active |passive |active |passive |... |none |passive |active |passive |active |passive |...
Active CA: | | | Active CA: | | |
[ca v1 ][ca v2 ][ca v3 |... [ca v1 ][ca v2 ][ca v3 |...
Trust anchor: | | |
[ca v1 | ][ca v2 | ][ca v3 |...
Legend:: Legend::
......
...@@ -620,9 +620,15 @@ class CertificateAuthority(object): ...@@ -620,9 +620,15 @@ class CertificateAuthority(object):
def getCACertificate(self): 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): def getCACertificateList(self):
""" """
......
...@@ -1724,6 +1724,15 @@ class CaucaseTest(unittest.TestCase): ...@@ -1724,6 +1724,15 @@ class CaucaseTest(unittest.TestCase):
[x.serial_number for x in utils.load_crl(crl_pem_b, cau_ca_list)], [x.serial_number for x in utils.load_crl(crl_pem_b, cau_ca_list)],
) )
self.assertRaises(CaucaseError, _checkUserAccess, user2_key) 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 # The old CA is now fully expired
self._stopServer() self._stopServer()
old_cau_pem = self._setCACertificateRemainingLifeTime( old_cau_pem = self._setCACertificateRemainingLifeTime(
...@@ -1744,6 +1753,13 @@ class CaucaseTest(unittest.TestCase): ...@@ -1744,6 +1753,13 @@ class CaucaseTest(unittest.TestCase):
self.assertRaises(CaucaseError, _checkUserAccess, user2_key) self.assertRaises(CaucaseError, _checkUserAccess, user2_key)
# Renewed and non-revoked user certificate is accepted # Renewed and non-revoked user certificate is accepted
_checkUserAccess(user3_key) _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): 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