From b2bfff341f78971f61cb2fb0e48561e492c8de4b Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Tue, 9 Mar 2021 19:50:52 -0800 Subject: [PATCH 1/8] adding cert bot --- requirements-tests.in | 1 + requirements-tests.txt | 1 + requirements.in | 1 + requirements.txt | 1 + 4 files changed, 4 insertions(+) diff --git a/requirements-tests.in b/requirements-tests.in index 9f4ce427..9b2b6988 100644 --- a/requirements-tests.in +++ b/requirements-tests.in @@ -3,6 +3,7 @@ bandit black coverage +certbot factory-boy Faker fakeredis diff --git a/requirements-tests.txt b/requirements-tests.txt index 0047c5d2..79f36f73 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -30,6 +30,7 @@ botocore==1.20.17 # boto3 # moto # s3transfer +certbot==1.13.0 certifi==2020.12.5 # via requests cffi==1.14.0 diff --git a/requirements.in b/requirements.in index 1eb96f97..91e6309d 100644 --- a/requirements.in +++ b/requirements.in @@ -7,6 +7,7 @@ asyncpool boto3 botocore celery[redis]==4.4.2 # need to first resolve the module not found error https://github.com/celery/celery/issues/6406 +certbot certifi certsrv CloudFlare diff --git a/requirements.txt b/requirements.txt index ebb48e91..5537a81c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,6 +40,7 @@ botocore==1.20.17 # s3transfer celery[redis]==4.4.2 # via -r requirements.in +certbot==1.13.0 certifi==2020.12.5 # via # -r requirements.in From f2205b6025c734ebf9cc06954e25f9aa9af72c57 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Tue, 9 Mar 2021 19:51:55 -0800 Subject: [PATCH 2/8] new test vectors --- lemur/tests/vectors.py | 99 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/lemur/tests/vectors.py b/lemur/tests/vectors.py index 7a78818c..c47017ae 100644 --- a/lemur/tests/vectors.py +++ b/lemur/tests/vectors.py @@ -587,3 +587,102 @@ zwKDoqAD+L4wEg8d890Zy2mbzJnDu2HQiMIROaBldKEAMQA= """ CERT_CHAIN_PKCS7_PEM = CERT_CHAIN_PKCS7_STR.encode('utf-8') + +ACME_CHAIN_LONG_STR = SAN_CERT_STR + """ +-----BEGIN CERTIFICATE----- +MIIFWzCCA0OgAwIBAgIQTfQrldHumzpMLrM7jRBd1jANBgkqhkiG9w0BAQsFADBm +MQswCQYDVQQGEwJVUzEzMDEGA1UEChMqKFNUQUdJTkcpIEludGVybmV0IFNlY3Vy +aXR5IFJlc2VhcmNoIEdyb3VwMSIwIAYDVQQDExkoU1RBR0lORykgUHJldGVuZCBQ +ZWFyIFgxMB4XDTIwMDkwNDAwMDAwMFoXDTI1MDkxNTE2MDAwMFowWTELMAkGA1UE +BhMCVVMxIDAeBgNVBAoTFyhTVEFHSU5HKSBMZXQncyBFbmNyeXB0MSgwJgYDVQQD +Ex8oU1RBR0lORykgQXJ0aWZpY2lhbCBBcHJpY290IFIzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAu6TR8+74b46mOE1FUwBrvxzEYLck3iasmKrcQkb+ +gy/z9Jy7QNIAl0B9pVKp4YU76JwxF5DOZZhi7vK7SbCkK6FbHlyU5BiDYIxbbfvO +L/jVGqdsSjNaJQTg3C3XrJja/HA4WCFEMVoT2wDZm8ABC1N+IQe7Q6FEqc8NwmTS +nmmRQm4TQvr06DP+zgFK/MNubxWWDSbSKKTH5im5j2fZfg+j/tM1bGaczFWw8/lS +nukyn5J2L+NJYnclzkXoh9nMFnyPmVbfyDPOc4Y25aTzVoeBKXa/cZ5MM+WddjdL +biWvm19f1sYn1aRaAIrkppv7kkn83vcth8XCG39qC2ZvaQIDAQABo4IBEDCCAQww +DgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAS +BgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTecnpI3zHDplDfn4Uj31c3S10u +ZTAfBgNVHSMEGDAWgBS182Xy/rAKkh/7PH3zRKCsYyXDFDA2BggrBgEFBQcBAQQq +MCgwJgYIKwYBBQUHMAKGGmh0dHA6Ly9zdGcteDEuaS5sZW5jci5vcmcvMCsGA1Ud +HwQkMCIwIKAeoByGGmh0dHA6Ly9zdGcteDEuYy5sZW5jci5vcmcvMCIGA1UdIAQb +MBkwCAYGZ4EMAQIBMA0GCysGAQQBgt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCN +DLam9yN0EFxxn/3p+ruWO6n/9goCAM5PT6cC6fkjMs4uas6UGXJjr5j7PoTQf3C1 +vuxiIGRJC6qxV7yc6U0X+w0Mj85sHI5DnQVWN5+D1er7mp13JJA0xbAbHa3Rlczn +y2Q82XKui8WHuWra0gb2KLpfboYj1Ghgkhr3gau83pC/WQ8HfkwcvSwhIYqTqxoZ +Uq8HIf3M82qS9aKOZE0CEmSyR1zZqQxJUT7emOUapkUN9poJ9zGc+FgRZvdro0XB +yphWXDaqMYph0DxW/10ig5j4xmmNDjCRmqIKsKoWA52wBTKKXK1na2ty/lW5dhtA +xkz5rVZFd4sgS4J0O+zm6d5GRkWsNJ4knotGXl8vtS3X40KXeb3A5+/3p0qaD215 +Xq8oSNORfB2oI1kQuyEAJ5xvPTdfwRlyRG3lFYodrRg6poUBD/8fNTXMtzydpRgy +zUQZh/18F6B/iW6cbiRN9r2Hkh05Om+q0/6w0DdZe+8YrNpfhSObr/1eVZbKGMIY +qKmyZbBNu5ysENIK5MPc14mUeKmFjpN840VR5zunoU52lqpLDua/qIM8idk86xGW +xx2ml43DO/Ya/tVZVok0mO0TUjzJIfPqyvr455IsIut4RlCR9Iq0EDTve2/ZwCuG +hSjpTUFGSiQrR2JK2Evp+o6AETUkBCO1aw0PpQBPDQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFVDCCBDygAwIBAgIRAO1dW8lt+99NPs1qSY3Rs8cwDQYJKoZIhvcNAQELBQAw +cTELMAkGA1UEBhMCVVMxMzAxBgNVBAoTKihTVEFHSU5HKSBJbnRlcm5ldCBTZWN1 +cml0eSBSZXNlYXJjaCBHcm91cDEtMCsGA1UEAxMkKFNUQUdJTkcpIERvY3RvcmVk +IER1cmlhbiBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQw +M1owZjELMAkGA1UEBhMCVVMxMzAxBgNVBAoTKihTVEFHSU5HKSBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEiMCAGA1UEAxMZKFNUQUdJTkcpIFByZXRl +bmQgUGVhciBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALbagEdD +Ta1QgGBWSYkyMhscZXENOBaVRTMX1hceJENgsL0Ma49D3MilI4KS38mtkmdF6cPW +nL++fgehT0FbRHZgjOEr8UAN4jH6omjrbTD++VZneTsMVaGamQmDdFl5g1gYaigk +kmx8OiCO68a4QXg4wSyn6iDipKP8utsE+x1E28SA75HOYqpdrk4HGxuULvlr03wZ +GTIf/oRt2/c+dYmDoaJhge+GOrLAEQByO7+8+vzOwpNAPEx6LW+crEEZ7eBXih6V +P19sTGy3yfqK5tPtTdXXCOQMKAp+gCj/VByhmIr+0iNDC540gtvV303WpcbwnkkL +YC0Ft2cYUyHtkstOfRcRO+K2cZozoSwVPyB8/J9RpcRK3jgnX9lujfwA/pAbP0J2 +UPQFxmWFRQnFjaq6rkqbNEBgLy+kFL1NEsRbvFbKrRi5bYy2lNms2NJPZvdNQbT/ +2dBZKmJqxHkxCuOQFjhJQNeO+Njm1Z1iATS/3rts2yZlqXKsxQUzN6vNbD8KnXRM +EeOXUYvbV4lqfCf8mS14WEbSiMy87GB5S9ucSV1XUrlTG5UGcMSZOBcEUpisRPEm +QWUOTWIoDQ5FOia/GI+Ki523r2ruEmbmG37EBSBXdxIdndqrjy+QVAmCebyDx9eV +EGOIpn26bW5LKerumJxa/CFBaKi4bRvmdJRLAgMBAAGjgfEwge4wDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLXzZfL+sAqSH/s8ffNE +oKxjJcMUMB8GA1UdIwQYMBaAFAhX2onHolN5DE/d4JCPdLriJ3NEMDgGCCsGAQUF +BwEBBCwwKjAoBggrBgEFBQcwAoYcaHR0cDovL3N0Zy1kc3QzLmkubGVuY3Iub3Jn +LzAtBgNVHR8EJjAkMCKgIKAehhxodHRwOi8vc3RnLWRzdDMuYy5sZW5jci5vcmcv +MCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQBgt8TAQEBMA0GCSqGSIb3DQEB +CwUAA4IBAQB7tR8B0eIQSS6MhP5kuvGth+dN02DsIhr0yJtk2ehIcPIqSxRRmHGl +4u2c3QlvEpeRDp2w7eQdRTlI/WnNhY4JOofpMf2zwABgBWtAu0VooQcZZTpQruig +F/z6xYkBk3UHkjeqxzMN3d1EqGusxJoqgdTouZ5X5QTTIee9nQ3LEhWnRSXDx7Y0 +ttR1BGfcdqHopO4IBqAhbkKRjF5zj7OD8cG35omywUbZtOJnftiI0nFcRaxbXo0v +oDfLD0S6+AC2R3tKpqjkNX6/91hrRFglUakyMcZU/xleqbv6+Lr3YD8PsBTub6lI +oZ2lS38fL18Aon458fbc0BPHtenfhKj5 +-----END CERTIFICATE----- +""" + +ACME_CHAIN_SHORT_STR = SAN_CERT_STR + """ +-----BEGIN CERTIFICATE----- +MIIFWzCCA0OgAwIBAgIQTfQrldHumzpMLrM7jRBd1jANBgkqhkiG9w0BAQsFADBm +MQswCQYDVQQGEwJVUzEzMDEGA1UEChMqKFNUQUdJTkcpIEludGVybmV0IFNlY3Vy +aXR5IFJlc2VhcmNoIEdyb3VwMSIwIAYDVQQDExkoU1RBR0lORykgUHJldGVuZCBQ +ZWFyIFgxMB4XDTIwMDkwNDAwMDAwMFoXDTI1MDkxNTE2MDAwMFowWTELMAkGA1UE +BhMCVVMxIDAeBgNVBAoTFyhTVEFHSU5HKSBMZXQncyBFbmNyeXB0MSgwJgYDVQQD +Ex8oU1RBR0lORykgQXJ0aWZpY2lhbCBBcHJpY290IFIzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAu6TR8+74b46mOE1FUwBrvxzEYLck3iasmKrcQkb+ +gy/z9Jy7QNIAl0B9pVKp4YU76JwxF5DOZZhi7vK7SbCkK6FbHlyU5BiDYIxbbfvO +L/jVGqdsSjNaJQTg3C3XrJja/HA4WCFEMVoT2wDZm8ABC1N+IQe7Q6FEqc8NwmTS +nmmRQm4TQvr06DP+zgFK/MNubxWWDSbSKKTH5im5j2fZfg+j/tM1bGaczFWw8/lS +nukyn5J2L+NJYnclzkXoh9nMFnyPmVbfyDPOc4Y25aTzVoeBKXa/cZ5MM+WddjdL +biWvm19f1sYn1aRaAIrkppv7kkn83vcth8XCG39qC2ZvaQIDAQABo4IBEDCCAQww +DgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAS +BgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTecnpI3zHDplDfn4Uj31c3S10u +ZTAfBgNVHSMEGDAWgBS182Xy/rAKkh/7PH3zRKCsYyXDFDA2BggrBgEFBQcBAQQq +MCgwJgYIKwYBBQUHMAKGGmh0dHA6Ly9zdGcteDEuaS5sZW5jci5vcmcvMCsGA1Ud +HwQkMCIwIKAeoByGGmh0dHA6Ly9zdGcteDEuYy5sZW5jci5vcmcvMCIGA1UdIAQb +MBkwCAYGZ4EMAQIBMA0GCysGAQQBgt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCN +DLam9yN0EFxxn/3p+ruWO6n/9goCAM5PT6cC6fkjMs4uas6UGXJjr5j7PoTQf3C1 +vuxiIGRJC6qxV7yc6U0X+w0Mj85sHI5DnQVWN5+D1er7mp13JJA0xbAbHa3Rlczn +y2Q82XKui8WHuWra0gb2KLpfboYj1Ghgkhr3gau83pC/WQ8HfkwcvSwhIYqTqxoZ +Uq8HIf3M82qS9aKOZE0CEmSyR1zZqQxJUT7emOUapkUN9poJ9zGc+FgRZvdro0XB +yphWXDaqMYph0DxW/10ig5j4xmmNDjCRmqIKsKoWA52wBTKKXK1na2ty/lW5dhtA +xkz5rVZFd4sgS4J0O+zm6d5GRkWsNJ4knotGXl8vtS3X40KXeb3A5+/3p0qaD215 +Xq8oSNORfB2oI1kQuyEAJ5xvPTdfwRlyRG3lFYodrRg6poUBD/8fNTXMtzydpRgy +zUQZh/18F6B/iW6cbiRN9r2Hkh05Om+q0/6w0DdZe+8YrNpfhSObr/1eVZbKGMIY +qKmyZbBNu5ysENIK5MPc14mUeKmFjpN840VR5zunoU52lqpLDua/qIM8idk86xGW +xx2ml43DO/Ya/tVZVok0mO0TUjzJIfPqyvr455IsIut4RlCR9Iq0EDTve2/ZwCuG +hSjpTUFGSiQrR2JK2Evp+o6AETUkBCO1aw0PpQBPDQ== +-----END CERTIFICATE----- +""" From caa44c1531bf41a841392d6a6631071d4e7b0faa Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Wed, 10 Mar 2021 12:39:50 -0800 Subject: [PATCH 3/8] adding functionality to fetch the desired chain --- lemur/plugins/lemur_acme/acme_handlers.py | 24 +++++++++++++-------- lemur/plugins/lemur_acme/challenge_types.py | 9 +++++--- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lemur/plugins/lemur_acme/acme_handlers.py b/lemur/plugins/lemur_acme/acme_handlers.py index 4de6c3f0..8636d882 100644 --- a/lemur/plugins/lemur_acme/acme_handlers.py +++ b/lemur/plugins/lemur_acme/acme_handlers.py @@ -23,6 +23,7 @@ from acme import challenges, errors, messages from acme.client import BackwardsCompatibleClientV2, ClientNetwork from acme.errors import TimeoutError from acme.messages import Error as AcmeError +from certbot import crypto_util as acme_crypto_util from flask import current_app from lemur.common.utils import generate_private_key @@ -92,7 +93,8 @@ class AcmeHandler(object): deadline = datetime.datetime.now() + datetime.timedelta(seconds=360) try: - orderr = acme_client.poll_and_finalize(order, deadline) + orderr = acme_client.poll_authorizations(order, deadline) + orderr = acme_client.finalize_order(orderr, deadline, fetch_alternative_chains=True) except (AcmeError, TimeoutError): sentry.captureException(extra={"order_url": str(order.uri)}) @@ -112,14 +114,23 @@ class AcmeHandler(object): f"Successfully resolved Acme order: {order.uri}", exc_info=True ) - pem_certificate, pem_certificate_chain = self.extract_cert_and_chain(orderr.fullchain_pem) + pem_certificate, pem_certificate_chain = self.extract_cert_and_chain(orderr.fullchain_pem, + orderr.alternative_fullchains_pem) current_app.logger.debug( "{0} {1}".format(type(pem_certificate), type(pem_certificate_chain)) ) return pem_certificate, pem_certificate_chain - def extract_cert_and_chain(self, fullchain_pem): + def extract_cert_and_chain(self, fullchain_pem, alternative_fullchains_pem, preferred_issuer=None): + + if not preferred_issuer: + preferred_issuer = current_app.config.get("ACME_PREFERRED_ISSUER", None) + if preferred_issuer: + # returns first chain if not match + fullchain_pem = acme_crypto_util.find_chain_with_issuer([fullchain_pem] + alternative_fullchains_pem, + preferred_issuer) + pem_certificate = OpenSSL.crypto.dump_certificate( OpenSSL.crypto.FILETYPE_PEM, OpenSSL.crypto.load_certificate( @@ -127,12 +138,7 @@ class AcmeHandler(object): ), ).decode() - if current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA", False) \ - and datetime.datetime.now() < datetime.datetime.strptime( - current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA_EXPIRATION_DATE", "17/03/21"), '%d/%m/%y'): - pem_certificate_chain = current_app.config.get("IDENTRUST_CROSS_SIGNED_LE_ICA") - else: - pem_certificate_chain = fullchain_pem[len(pem_certificate):].lstrip() + pem_certificate_chain = fullchain_pem[len(pem_certificate):].lstrip() return pem_certificate, pem_certificate_chain diff --git a/lemur/plugins/lemur_acme/challenge_types.py b/lemur/plugins/lemur_acme/challenge_types.py index 538ec236..49ae47a0 100644 --- a/lemur/plugins/lemur_acme/challenge_types.py +++ b/lemur/plugins/lemur_acme/challenge_types.py @@ -119,8 +119,10 @@ class AcmeHttpChallenge(AcmeChallenge): current_app.logger.info("Uploaded HTTP-01 challenge tokens, trying to poll and finalize the order") try: - finalized_orderr = acme_client.poll_and_finalize(orderr, - datetime.datetime.now() + datetime.timedelta(seconds=90)) + deadline = datetime.datetime.now() + datetime.timedelta(seconds=90) + orderr = acme_client.poll_authorizations(orderr, deadline) + finalized_orderr = acme_client.finalize_order(orderr, deadline, fetch_alternative_chains=True) + except errors.ValidationError as validationError: for authz in validationError.failed_authzrs: for chall in authz.body.challenges: @@ -130,7 +132,8 @@ class AcmeHttpChallenge(AcmeChallenge): ERROR_CODES[chall.error.code])) raise Exception('Validation error occured, can\'t complete challenges. See logs for more information.') - pem_certificate, pem_certificate_chain = self.acme.extract_cert_and_chain(finalized_orderr.fullchain_pem) + pem_certificate, pem_certificate_chain = self.acme.extract_cert_and_chain(finalized_orderr.fullchain_pem, + finalized_orderr.alternative_fullchains_pem) if len(deployed_challenges) != 0: for token_path in deployed_challenges: From 4937c5dc2c7ebccf8e489c78df4fd90fec954885 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Wed, 10 Mar 2021 12:42:42 -0800 Subject: [PATCH 4/8] testing test_extract_cert_and_chain --- .../lemur_acme/tests/test_acme_handler.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lemur/plugins/lemur_acme/tests/test_acme_handler.py b/lemur/plugins/lemur_acme/tests/test_acme_handler.py index 324af5ac..74211b1b 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_handler.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_handler.py @@ -5,6 +5,12 @@ from flask import Flask from cryptography.x509 import DNSName from lemur.plugins.lemur_acme import acme_handlers +from lemur.tests.vectors import ( + ACME_CHAIN_SHORT_STR, + ACME_CHAIN_LONG_STR, + SAN_CERT_STR, +) + class TestAcmeHandler(unittest.TestCase): def setUp(self): @@ -110,3 +116,18 @@ class TestAcmeHandler(unittest.TestCase): self.assertEqual( result, [options["common_name"], "test2.netflix.net"] ) + + def test_extract_cert_and_chain(self): + # expecting the short chain + leaf_pem, chain_pem = self.acme.extract_cert_and_chain(ACME_CHAIN_SHORT_STR, + [ACME_CHAIN_LONG_STR], + "(STAGING) Artificial Apricot R3") + self.assertEqual(leaf_pem, SAN_CERT_STR) + self.assertEqual(chain_pem, ACME_CHAIN_SHORT_STR[len(leaf_pem):].lstrip()) + + # expecting the long chain + leaf_pem, chain_pem = self.acme.extract_cert_and_chain(ACME_CHAIN_SHORT_STR, + [ACME_CHAIN_LONG_STR], + "(STAGING) Doctored Durian Root CA X3") + self.assertEqual(leaf_pem, SAN_CERT_STR) + self.assertEqual(chain_pem, ACME_CHAIN_LONG_STR[len(leaf_pem):].lstrip()) From 45712c582bbca3552db907db37c26994dd46c12d Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Wed, 10 Mar 2021 12:43:36 -0800 Subject: [PATCH 5/8] fixing the mock to include the alternative chain --- lemur/plugins/lemur_acme/tests/test_acme_http.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lemur/plugins/lemur_acme/tests/test_acme_http.py b/lemur/plugins/lemur_acme/tests/test_acme_http.py index 0df9e6b2..d81e165d 100644 --- a/lemur/plugins/lemur_acme/tests/test_acme_http.py +++ b/lemur/plugins/lemur_acme/tests/test_acme_http.py @@ -146,7 +146,8 @@ Q9ePRFBCiXOQ6wPLoUhrrbZ8LpFUFYDXHMtYM7P9sc9IAWoONXREJaO08zgFtMp4 idWw1VrejtwclobqNMVtG3EiPUIpJGpbMcJgbiLSmKkrvQtGng== -----END CERTIFICATE----- """ - mock_client.poll_and_finalize.return_value = mock_finalized_order + mock_finalized_order.alternative_fullchains_pem = [mock_finalized_order.fullchain_pem] + mock_client.finalize_order.return_value = mock_finalized_order mock_acme.return_value = (mock_client, "") From addaa3ab1301580a2ca75fddc6d984ffbe0448aa Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Wed, 10 Mar 2021 12:43:58 -0800 Subject: [PATCH 6/8] adding the config as an example --- lemur/tests/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lemur/tests/conf.py b/lemur/tests/conf.py index 3dfb5621..51b61a3d 100644 --- a/lemur/tests/conf.py +++ b/lemur/tests/conf.py @@ -201,6 +201,7 @@ ACME_EMAIL = "jim@example.com" ACME_TEL = "4088675309" ACME_DIRECTORY_URL = "https://acme-v01.api.letsencrypt.org" ACME_DISABLE_AUTORESOLVE = True +ACME_PREFERRED_ISSUER = "R3" LDAP_AUTH = True LDAP_BIND_URI = "ldap://localhost" From 13539814db5aed2dcb21be6f0c2456dfcd4d34d2 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Wed, 10 Mar 2021 13:23:21 -0800 Subject: [PATCH 7/8] adding documentation --- docs/administration.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/administration.rst b/docs/administration.rst index c2ca7b04..9f4d47d5 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -871,6 +871,15 @@ account. See :ref:`Using a pre-existing ACME account ` for mor This is the registration for the ACME account, the most important part is the uri attribute (in JSON) +.. data:: ACME_PREFERRED_ISSUER + :noindex: + + This is an optional parameter to indicate the preferred chain to retrieve from ACME. + This is applicable to Let's Encrypts recent `migration https://letsencrypt.org/certificates/`_ to their own root where they provide two distinct certificate chains; + the main chain will be the long chain that is rooted in the expiring DTS root, whereas the alternative chain is rooted in X1 root CA. + Select "X1" to get the shorter chain (currently alternative), leave blank or "DST Root CA X3" for the longer chain. + + Active Directory Certificate Services Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From e48f4ffe7748bc838e9e0ceb654dec61fdbf49d1 Mon Sep 17 00:00:00 2001 From: Hossein Shafagh Date: Wed, 10 Mar 2021 13:29:53 -0800 Subject: [PATCH 8/8] improved documentation --- docs/administration.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/administration.rst b/docs/administration.rst index 9f4d47d5..af18167e 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -874,9 +874,11 @@ account. See :ref:`Using a pre-existing ACME account ` for mor .. data:: ACME_PREFERRED_ISSUER :noindex: - This is an optional parameter to indicate the preferred chain to retrieve from ACME. - This is applicable to Let's Encrypts recent `migration https://letsencrypt.org/certificates/`_ to their own root where they provide two distinct certificate chains; - the main chain will be the long chain that is rooted in the expiring DTS root, whereas the alternative chain is rooted in X1 root CA. + This is an optional parameter to indicate the preferred chain to retrieve from ACME when finalizing the order. + This is applicable to Let's Encrypts recent `migration https://letsencrypt.org/certificates/`_ to their + own root, where they provide two distinct certificate chains (fullchain_pem vs. alternative_fullchains_pem); + the main chain will be the long chain that is rooted in the expiring DTS root, whereas the alternative chain + is rooted in X1 root CA. Select "X1" to get the shorter chain (currently alternative), leave blank or "DST Root CA X3" for the longer chain.