diff --git a/backend/bdd/features/pki/acme/external-ca.feature b/backend/bdd/features/pki/acme/external-ca.feature index 6d9ae02db..2ddf8f539 100644 --- a/backend/bdd/features/pki/acme/external-ca.feature +++ b/backend/bdd/features/pki/acme/external-ca.feature @@ -1,23 +1,110 @@ Feature: External CA Scenario: Issue a certificate from an external CA - Given I have an ACME cert profile as "acme_profile" - When I have an ACME client connecting to "{BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/directory" - Then I register a new ACME account with email fangpen@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account - When I create certificate signing request as csr - Then I add names to certificate signing request csr + Given I create a Cloudflare connection as cloudflare + Then I memorize cloudflare with jq ".appConnection.id" as app_conn_id + Given I create a external ACME CA with the following config as ext_ca """ { - "COMMON_NAME": "localhost" + "dnsProviderConfig": { + "provider": "cloudflare", + "hostedZoneId": "MOCK_ZONE_ID" + }, + "directoryUrl": "https://acme-v02.api.letsencrypt.org/directory", + "accountEmail": "fangpen@infisical.com", + "dnsAppConnectionId": "{app_conn_id}", + "eabKid": "", + "eabHmacKey": "" } """ - And I create a RSA private key pair as cert_key - And I sign the certificate signing request csr with private key cert_key and output it as csr_pem in PEM format - And I submit the certificate signing request PEM csr_pem certificate order to the ACME server as order - And I select challenge with type http-01 for domain localhost from order in order as challenge - And I serve challenge response for challenge at localhost - And I tell ACME server that challenge is ready to be verified - And I poll and finalize the ACME order order as finalized_order - And the value finalized_order.body with jq ".status" should be equal to "valid" - And I parse the full-chain certificate from order finalized_order as cert - And the value cert with jq ".subject.common_name" should be equal to "localhost" + Then I memorize ext_ca with jq ".id" as ext_ca_id + Given I create a certificate template with the following config as cert_template + """ + { + "subject": [ + { + "type": "common_name", + "allowed": [ + "*" + ] + } + ], + "sans": [ + { + "type": "dns_name", + "allowed": [ + "*" + ] + } + ], + "keyUsages": { + "required": [], + "allowed": [ + "digital_signature", + "key_encipherment", + "non_repudiation", + "data_encipherment", + "key_agreement", + "key_cert_sign", + "crl_sign", + "encipher_only", + "decipher_only" + ] + }, + "extendedKeyUsages": { + "required": [], + "allowed": [ + "client_auth", + "server_auth", + "code_signing", + "email_protection", + "ocsp_signing", + "time_stamping" + ] + }, + "algorithms": { + "signature": [ + "SHA256-RSA", + "SHA512-RSA", + "SHA384-ECDSA", + "SHA384-RSA", + "SHA256-ECDSA", + "SHA512-ECDSA" + ], + "keyAlgorithm": [ + "RSA-2048", + "RSA-4096", + "ECDSA-P384", + "RSA-3072", + "ECDSA-P256", + "ECDSA-P521" + ] + }, + "validity": { + "max": "365d" + } + } + """ + Then I memorize cert_template with jq ".certificateTemplate.id" as cert_template_id + Given I create an ACME profile with ca ext_ca_id and template cert_template_id as "acme_profile" + +# Given I have an ACME cert profile as "acme_profile" +# When I have an ACME client connecting to "{BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/directory" +# Then I register a new ACME account with email fangpen@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account +# When I create certificate signing request as csr +# Then I add names to certificate signing request csr +# """ +# { +# "COMMON_NAME": "localhost" +# } +# """ +# And I create a RSA private key pair as cert_key +# And I sign the certificate signing request csr with private key cert_key and output it as csr_pem in PEM format +# And I submit the certificate signing request PEM csr_pem certificate order to the ACME server as order +# And I select challenge with type http-01 for domain localhost from order in order as challenge +# And I serve challenge response for challenge at localhost +# And I tell ACME server that challenge is ready to be verified +# And I poll and finalize the ACME order order as finalized_order +# And the value finalized_order.body with jq ".status" should be equal to "valid" +# And I parse the full-chain certificate from order finalized_order as cert +# And the value cert with jq ".subject.common_name" should be equal to "localhost" diff --git a/backend/bdd/features/steps/pki_acme.py b/backend/bdd/features/steps/pki_acme.py index 5aab5531e..6c6e55852 100644 --- a/backend/bdd/features/steps/pki_acme.py +++ b/backend/bdd/features/steps/pki_acme.py @@ -186,6 +186,45 @@ def step_impl(context: Context, var_name: str): context.vars[var_name] = response +@given( + 'I create an ACME profile with ca {ca_id} and template {template_id} as "{profile_var}"' +) +def step_impl(context: Context, ca_id: str, template_id: str, profile_var: str): + profile_slug = faker.slug() + jwt_token = context.vars["AUTH_TOKEN"] + response = context.http_client.post( + "/api/v1/pki/certificate-profiles", + headers=dict(authorization="Bearer {}".format(jwt_token)), + json={ + "projectId": context.vars["PROJECT_ID"], + "slug": profile_slug, + "description": "ACME Profile created by BDD test", + "enrollmentType": "acme", + "caId": replace_vars(ca_id, context.vars), + "certificateTemplateId": replace_vars(template_id, context.vars), + "acmeConfig": {}, + }, + ) + response.raise_for_status() + resp_json = response.json() + profile_id = resp_json["certificateProfile"]["id"] + kid = profile_id + + response = context.http_client.get( + f"/api/v1/pki/certificate-profiles/{profile_id}/acme/eab-secret/reveal", + headers=dict(authorization="Bearer {}".format(jwt_token)), + ) + response.raise_for_status() + resp_json = response.json() + secret = resp_json["eabSecret"] + + context.vars[profile_var] = AcmeProfile( + profile_id, + eab_kid=kid, + eab_secret=secret, + ) + + @given('I have an ACME cert profile with external ACME CA as "{profile_var}"') def step_impl(context: Context, profile_var: str): profile_id = context.vars.get("PROFILE_ID")