From adf0cccd5a6a24198c368e859e8edec989fac190 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Tue, 8 Jun 2021 14:16:32 +0200 Subject: [PATCH 1/3] Set correct KU and EKU extensions A CA certificate must not have an EKU extension. KU key_cert_signing is required. crl_sign is recommended for CRLs and digital_signature is recommended for OCSP. An end-entity cert must have an EKU. TLS server and TLS client are recommended. KU digital_signature is required for modern perfect forward secrecy handshake. key_encipherment is optional for old non-PFS handshake. Signed-off-by: Christian Heimes --- trustme/__init__.py | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/trustme/__init__.py b/trustme/__init__.py index 017a98e..bf6ef82 100644 --- a/trustme/__init__.py +++ b/trustme/__init__.py @@ -240,25 +240,17 @@ def __init__( ) .add_extension( x509.KeyUsage( - digital_signature=False, + digital_signature=True, # OCSP content_commitment=False, key_encipherment=False, data_encipherment=False, key_agreement=False, - key_cert_sign=True, - crl_sign=True, + key_cert_sign=True, # sign certs + crl_sign=True, # sign revocation lists encipher_only=False, decipher_only=False), critical=True ) - .add_extension( - x509.ExtendedKeyUsage([ - ExtendedKeyUsageOID.CLIENT_AUTH, - ExtendedKeyUsageOID.SERVER_AUTH, - ExtendedKeyUsageOID.CODE_SIGNING, - ]), - critical=True - ) .sign( private_key=sign_key, algorithm=hashes.SHA256(), @@ -402,6 +394,27 @@ def issue_cert(self, *identities, **kwargs): ), critical=True, ) + .add_extension( + x509.KeyUsage( + digital_signature=True, + content_commitment=False, + key_encipherment=True, + data_encipherment=False, + key_agreement=False, + key_cert_sign=False, + crl_sign=False, + encipher_only=False, + decipher_only=False), + critical=True + ) + .add_extension( + x509.ExtendedKeyUsage([ + ExtendedKeyUsageOID.CLIENT_AUTH, + ExtendedKeyUsageOID.SERVER_AUTH, + ExtendedKeyUsageOID.CODE_SIGNING, + ]), + critical=True + ) .sign( private_key=self._private_key, algorithm=hashes.SHA256(), From f768f96e4119b9fb5bf0e0f4c5b970ebb09a6a44 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Tue, 8 Jun 2021 14:36:53 +0200 Subject: [PATCH 2/3] Adjust tests Signed-off-by: Christian Heimes --- tests/test_trustme.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/test_trustme.py b/tests/test_trustme.py index 68d61e6..015a155 100644 --- a/tests/test_trustme.py +++ b/tests/test_trustme.py @@ -38,7 +38,27 @@ def assert_is_ca(ca_cert): assert ku.value.crl_sign is True assert ku.critical is True - eku = ca_cert.extensions.get_extension_for_class(x509.ExtendedKeyUsage) + try: + ca_cert.extensions.get_extension_for_class(x509.ExtendedKeyUsage) + except x509.ExtensionNotFound: + pass + else: + pytest.fail("ca cert has an EKU") + + +def assert_is_leaf(leaf_cert): + bc = leaf_cert.extensions.get_extension_for_class(x509.BasicConstraints) + assert bc.value.ca is False + assert bc.critical is True + + ku = leaf_cert.extensions.get_extension_for_class(x509.KeyUsage) + assert ku.value.digital_signature is True + assert ku.value.key_encipherment is True + assert ku.value.key_cert_sign is False + assert ku.value.crl_sign is False + assert ku.critical is True + + eku = leaf_cert.extensions.get_extension_for_class(x509.ExtendedKeyUsage) assert eku.value == x509.ExtendedKeyUsage([ x509.oid.ExtendedKeyUsageOID.CLIENT_AUTH, x509.oid.ExtendedKeyUsageOID.SERVER_AUTH, @@ -88,6 +108,7 @@ def test_basics(): assert server_cert.not_valid_before <= today <= server_cert.not_valid_after assert server_cert.issuer == ca_cert.subject + assert_is_leaf(server_cert) san = server_cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) hostnames = san.value.get_values_for_type(x509.DNSName) @@ -177,6 +198,7 @@ def test_intermediate(): child_server_cert = x509.load_pem_x509_certificate( child_server.cert_chain_pems[0].bytes(), default_backend()) assert child_server_cert.issuer == child_ca_cert.subject + assert_is_leaf(child_server_cert) def test_path_length(): @@ -422,6 +444,7 @@ def test_identity_variants(): san = cert.extensions.get_extension_for_class( x509.SubjectAlternativeName ) + assert_is_leaf(cert) got = san.value[0] assert got == expected From e3ac2d61a5ab902cdeac1c95dfc0a49c81c5d290 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Tue, 8 Jun 2021 14:39:03 +0100 Subject: [PATCH 3/3] Update tests/test_trustme.py --- tests/test_trustme.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/test_trustme.py b/tests/test_trustme.py index 015a155..fb5137f 100644 --- a/tests/test_trustme.py +++ b/tests/test_trustme.py @@ -38,12 +38,8 @@ def assert_is_ca(ca_cert): assert ku.value.crl_sign is True assert ku.critical is True - try: + with pytest.raises(x509.ExtensionNotFound): ca_cert.extensions.get_extension_for_class(x509.ExtendedKeyUsage) - except x509.ExtensionNotFound: - pass - else: - pytest.fail("ca cert has an EKU") def assert_is_leaf(leaf_cert):