add test for external CA key size sanity check

We recently added validation of externally-signed CA certificate to
ensure certificates signed by external CAs with too-small keys
(according to system crypto policy) are rejected.

Add an integration test that attempts to renew with a 1024-bit
external CA, and asserts failure.

Part of: https://pagure.io/freeipa/issue/7761

Reviewed-By: Christian Heimes <cheimes@redhat.com>
This commit is contained in:
Fraser Tweedale 2019-05-27 12:12:43 +10:00 committed by Alexander Bokovoy
parent 891d54e46f
commit f9b22283dd
3 changed files with 20 additions and 5 deletions

View File

@ -34,14 +34,15 @@ class ExternalCA:
"""Provide external CA for testing """Provide external CA for testing
""" """
def __init__(self, days=365): def __init__(self, days=365, key_size=None):
self.now = datetime.datetime.utcnow() self.now = datetime.datetime.utcnow()
self.delta = datetime.timedelta(days=days) self.delta = datetime.timedelta(days=days)
self.ca_key = None self.ca_key = None
self.ca_public_key = None self.ca_public_key = None
self.issuer = None self.issuer = None
self.key_size = key_size or 2048
def create_ca_key(self, key_size=2048): def create_ca_key(self):
"""Create private and public key for CA """Create private and public key for CA
Note: The test still creates 2048 although IPA CA uses 3072 bit RSA Note: The test still creates 2048 although IPA CA uses 3072 bit RSA
@ -50,7 +51,7 @@ class ExternalCA:
""" """
self.ca_key = rsa.generate_private_key( self.ca_key = rsa.generate_private_key(
public_exponent=65537, public_exponent=65537,
key_size=key_size, key_size=self.key_size,
backend=default_backend(), backend=default_backend(),
) )
self.ca_public_key = self.ca_key.public_key() self.ca_public_key = self.ca_key.public_key()

View File

@ -1678,7 +1678,8 @@ def add_dns_zone(master, zone, skip_overlap_check=False,
def sign_ca_and_transport(host, csr_name, root_ca_name, ipa_ca_name, def sign_ca_and_transport(host, csr_name, root_ca_name, ipa_ca_name,
root_ca_path_length=None, ipa_ca_path_length=1): root_ca_path_length=None, ipa_ca_path_length=1,
key_size=None,):
""" """
Sign ipa csr and save signed CA together with root CA back to the host. Sign ipa csr and save signed CA together with root CA back to the host.
Returns root CA and IPA CA paths on the host. Returns root CA and IPA CA paths on the host.
@ -1689,7 +1690,7 @@ def sign_ca_and_transport(host, csr_name, root_ca_name, ipa_ca_name,
# Get IPA CSR as bytes # Get IPA CSR as bytes
ipa_csr = host.get_file_contents(csr_name) ipa_csr = host.get_file_contents(csr_name)
external_ca = ExternalCA() external_ca = ExternalCA(key_size=key_size)
# Create root CA # Create root CA
root_ca = external_ca.create_ca(path_length=root_ca_path_length) root_ca = external_ca.create_ca(path_length=root_ca_path_length)
# Sign CSR # Sign CSR

View File

@ -373,6 +373,19 @@ class TestExternalCAInvalidCert(IntegrationTest):
result = self.master.run_command(cmd, raiseonerr=False) result = self.master.run_command(cmd, raiseonerr=False)
assert result.returncode == 1 assert result.returncode == 1
def test_external_ca_with_too_small_key(self):
# reuse the existing deployment and renewal CSR
root_ca_fname, ipa_ca_fname = tasks.sign_ca_and_transport(
self.master, paths.IPA_CA_CSR, ROOT_CA, IPA_CA, key_size=1024)
cmd = [
paths.IPA_CACERT_MANAGE, 'renew',
'--external-cert-file', ipa_ca_fname,
'--external-cert-file', root_ca_fname,
]
result = self.master.run_command(cmd, raiseonerr=False)
assert result.returncode == 1
class TestExternalCAInvalidIntermediate(IntegrationTest): class TestExternalCAInvalidIntermediate(IntegrationTest):
"""Test case for https://pagure.io/freeipa/issue/7877""" """Test case for https://pagure.io/freeipa/issue/7877"""