diff --git a/backend/bdd/features/pki/acme/new-order.feature b/backend/bdd/features/pki/acme/new-order.feature new file mode 100644 index 000000000..5ec9620e4 --- /dev/null +++ b/backend/bdd/features/pki/acme/new-order.feature @@ -0,0 +1,17 @@ +Feature: New Order + + Scenario: Create a new order +# 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 +# # TODO: make it I have an account already instead? +# 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 + """ + { + "ORGANIZATION_NAME": "Infisical Inc", + "COMMON_NAME": "localhost" + } + """ + Then I create a RSA private key pair as cert_key + Then I sign the certificate signing request csr with private key cert_key and output it as csr_pem in PEM format diff --git a/backend/bdd/features/steps/pki_acme.py b/backend/bdd/features/steps/pki_acme.py index 7e1cad457..d3f0c109e 100644 --- a/backend/bdd/features/steps/pki_acme.py +++ b/backend/bdd/features/steps/pki_acme.py @@ -9,6 +9,9 @@ from behave import then from josepy.jwk import JWKRSA from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography import x509 +from cryptography.x509.oid import NameOID +from cryptography.hazmat.primitives import hashes ACC_KEY_BITS = 2048 ACC_KEY_PUBLIC_EXPONENT = 65537 @@ -93,3 +96,53 @@ def step_impl(context: Context, email: str, kid: str, secret: str, account_var: # TODO: add EAB info here registration = messages.NewRegistration.from_data(email=email) context.vars[account_var] = context.acme_client.new_account(registration) + + +@when("I create certificate signing request as {csr_var}") +def step_impl(context: Context, csr_var: str): + context.vars[csr_var] = x509.CertificateSigningRequestBuilder() + + +@then("I add names to certificate signing request {csr_var}") +def step_impl(context: Context, csr_var: str): + names = json.loads(context.text) + builder: x509.CertificateSigningRequestBuilder = context.vars[csr_var] + builder.subject_name( + x509.Name( + [ + x509.NameAttribute(getattr(NameOID, name), value) + for name, value in names.items() + ] + ) + ) + + +@then("I add subject alternative name to certificate signing request {csr_var}") +def step_impl(context: Context, csr_var: str): + names = json.loads(context.text) + builder: x509.CertificateSigningRequestBuilder = context.vars[csr_var] + builder.add_extension( + x509.SubjectAlternativeName([x509.DNSName(name) for name in names]), + critical=False, + ) + + +@then("I create a RSA private key pair as {rsa_key_var}") +def step_impl(context: Context, rsa_key_var: str): + context.vars[rsa_key_var] = rsa.generate_private_key( + # TODO: make them configurable if we need to + public_exponent=65537, + key_size=2048, + ) + + +@then( + "I sign the certificate signing request {csr_var} with private key {pk_var} and output it as {pem_var} in PEM format" +) +def step_impl(context: Context, csr_var: str, pk_var: str, pem_var: str): + context.vars[pem_var] = ( + context.vars[csr_var] + .sign(context.vars[pk_var], hashes.SHA256()) + .public_bytes(serialization.Encoding.PEM) + .decode("utf-8") + )