From f9b22283dd2160ec073e93df9b52ef6b47d6c335 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Mon, 27 May 2019 12:12:43 +1000 Subject: [PATCH] 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 --- ipatests/create_external_ca.py | 7 ++++--- ipatests/pytest_ipa/integration/tasks.py | 5 +++-- ipatests/test_integration/test_external_ca.py | 13 +++++++++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ipatests/create_external_ca.py b/ipatests/create_external_ca.py index 706782adc..a318b8090 100644 --- a/ipatests/create_external_ca.py +++ b/ipatests/create_external_ca.py @@ -34,14 +34,15 @@ class ExternalCA: """Provide external CA for testing """ - def __init__(self, days=365): + def __init__(self, days=365, key_size=None): self.now = datetime.datetime.utcnow() self.delta = datetime.timedelta(days=days) self.ca_key = None self.ca_public_key = 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 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( public_exponent=65537, - key_size=key_size, + key_size=self.key_size, backend=default_backend(), ) self.ca_public_key = self.ca_key.public_key() diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py index ec9c68958..f07347619 100644 --- a/ipatests/pytest_ipa/integration/tasks.py +++ b/ipatests/pytest_ipa/integration/tasks.py @@ -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, - 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. 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 ipa_csr = host.get_file_contents(csr_name) - external_ca = ExternalCA() + external_ca = ExternalCA(key_size=key_size) # Create root CA root_ca = external_ca.create_ca(path_length=root_ca_path_length) # Sign CSR diff --git a/ipatests/test_integration/test_external_ca.py b/ipatests/test_integration/test_external_ca.py index 7ad0146c8..a42355217 100644 --- a/ipatests/test_integration/test_external_ca.py +++ b/ipatests/test_integration/test_external_ca.py @@ -373,6 +373,19 @@ class TestExternalCAInvalidCert(IntegrationTest): result = self.master.run_command(cmd, raiseonerr=False) 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): """Test case for https://pagure.io/freeipa/issue/7877"""