From 4150035fcdd9a45ac64f61362bef9de8d544ff1b Mon Sep 17 00:00:00 2001 From: Fang-Pen Lin Date: Thu, 6 Nov 2025 22:33:21 -0800 Subject: [PATCH] More test cases --- .../features/pki/acme/access-control.feature | 40 +++++++++++++------ backend/bdd/features/steps/pki_acme.py | 25 ++++++++++-- .../ee/services/pki-acme/pki-acme-errors.ts | 2 +- .../ee/services/pki-acme/pki-acme-service.ts | 4 +- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/backend/bdd/features/pki/acme/access-control.feature b/backend/bdd/features/pki/acme/access-control.feature index ed3f85ccf..81b48b025 100644 --- a/backend/bdd/features/pki/acme/access-control.feature +++ b/backend/bdd/features/pki/acme/access-control.feature @@ -15,12 +15,28 @@ Feature: Access Control 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 Then I submit the certificate signing request PEM csr_pem certificate order to the ACME server as order - And I put away current ACME client as client0 - - 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 maidu@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account1 Then I peak and memorize the next nonce as nonce Then I memorize with jq "" as + When I send a raw ACME request to "" + """ + { + "protected": { + "alg": "RS256", + "nonce": "{nonce}", + "url": "", + "kid": "{acme_account0.uri}" + }, + "payload": {"invalid": "payload"} + } + """ + # With original owner account, the invalid payload is going to trigger other errors instead of 404, this is to make sure + # that our URLs are actually correct + Then the value response.status_code should not be equal to 404 + And I put away current ACME client as client0 + + 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 maidu@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account1 + Then I peak and memorize the next nonce as nonce When I send a raw ACME request to "" """ { @@ -30,19 +46,19 @@ Feature: Access Control "url": "", "kid": "{acme_account1.uri}" }, - "payload": {} + "raw_payload": "" } """ Then the value response.status_code should be equal to 404 Examples: Endpoints - | src_var | jq | dest_var | url - | order | . | not_used | {BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/accounts/{account0_id}/orders | - | order | . | not_used | {order.uri} | - | order | . | not_used | {order.uri}/finalize | - | order | . | not_used | {order.uri}/certificate | - | order | .authorizations[0].uri | auth_uri | {auth_uri} | - | order | .authorizations[0].body.challenges[0].url | challenge_uri | {challenge_uri} | + | src_var | jq | dest_var | url | payload | + | order | . | not_used | {BASE_URL}/api/v1/pki/acme/profiles/{acme_profile.id}/accounts/{account0_id}/orders | | + | order | . | not_used | {order.uri} | | + | order | . | not_used | {order.uri}/finalize | {\"csr\": \"\"} | + | order | . | not_used | {order.uri}/certificate | | + | order | .authorizations[0].uri | auth_uri | {auth_uri} | | + | order | .authorizations[0].body.challenges[0].url | challenge_uri | {challenge_uri} | {} | Scenario Outline: URL mismatch Given I have an ACME cert profile as "acme_profile" diff --git a/backend/bdd/features/steps/pki_acme.py b/backend/bdd/features/steps/pki_acme.py index 52a234644..88c31c4a0 100644 --- a/backend/bdd/features/steps/pki_acme.py +++ b/backend/bdd/features/steps/pki_acme.py @@ -310,11 +310,21 @@ def send_raw_acme_req(context: Context, url: str): acme_client = context.acme_client content = json.loads(context.text) protected = replace_vars(content["protected"], context.vars) - payload = ( - replace_vars(content["payload"], context.vars) if "payload" in content else None - ) alg = acme_client.net.alg - encoded_payload = json.dumps(payload).encode() if payload is not None else b"" + if "raw_payload" in content: + encoded_payload = content["raw_payload"].encode("utf-8") + else: + if "payload" not in content: + payload = ( + replace_vars(content["payload"], context.vars) + if "payload" in content + else None + ) + encoded_payload = ( + json.dumps(payload).encode() if payload is not None else b"" + ) + else: + encoded_payload = b"" protected_headers = json.dumps(protected) signature = alg.sign( key=acme_client.net.key.key, @@ -483,6 +493,13 @@ def step_impl(context: Context, var_path: str, expected: str): assert value == expected_value, f"{value!r} does not match {expected_value!r}" +@then("the value {var_path} should not be equal to {expected}") +def step_impl(context: Context, var_path: str, expected: str): + value = eval_var(context, var_path) + expected_value = replace_vars(json.loads(expected), context.vars) + assert value != expected_value, f"{value!r} does match {expected_value!r}" + + @then('I memorize {var_path} with jq "{jq_query}" as {var_name}') def step_impl(context: Context, var_path: str, jq_query, var_name: str): _, value = apply_value_with_jq( diff --git a/backend/src/ee/services/pki-acme/pki-acme-errors.ts b/backend/src/ee/services/pki-acme/pki-acme-errors.ts index 98a89a731..ba3c9fbc0 100644 --- a/backend/src/ee/services/pki-acme/pki-acme-errors.ts +++ b/backend/src/ee/services/pki-acme/pki-acme-errors.ts @@ -139,7 +139,7 @@ export class AcmeAccountDoesNotExistError extends AcmeError { super({ type: AcmeErrorType.AccountDoesNotExist, message, - status: 400, + status: 404, error }); this.name = "AcmeAccountDoesNotExistError"; diff --git a/backend/src/ee/services/pki-acme/pki-acme-service.ts b/backend/src/ee/services/pki-acme/pki-acme-service.ts index 6e45f2a92..3190f98ef 100644 --- a/backend/src/ee/services/pki-acme/pki-acme-service.ts +++ b/backend/src/ee/services/pki-acme/pki-acme-service.ts @@ -165,7 +165,7 @@ export const pkiAcmeServiceFactory = ({ throw new AcmeBadPublicKeyError({ message: "Invalid JWS payload" }); } logger.error(error, "Unexpected error while verifying JWS payload"); - throw new AcmeServerInternalError({ message: "Failed to verify JWS payload" }); + throw new AcmeMalformedError({ message: "Failed to verify JWS payload" }); } const { protectedHeader: rawProtectedHeader, payload: rawPayload } = result; try { @@ -257,7 +257,7 @@ export const pkiAcmeServiceFactory = ({ } const accountId = extractAccountIdFromKid(protectedHeader.kid, profileId); if (expectedAccountId && accountId !== expectedAccountId) { - throw new NotFoundError({ message: "ACME resource not found" }); + throw new AcmeAccountDoesNotExistError({ message: "ACME resource not found" }); } const account = await acmeAccountDAL.findByProjectIdAndAccountId(profile.id, accountId); if (!account) {