More test cases

This commit is contained in:
Fang-Pen Lin
2025-11-06 22:33:21 -08:00
parent d7cf4388fe
commit 4150035fcd
4 changed files with 52 additions and 19 deletions

View File

@@ -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 <src_var> with jq "<jq>" as <dest_var>
When I send a raw ACME request to "<url>"
"""
{
"protected": {
"alg": "RS256",
"nonce": "{nonce}",
"url": "<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 "<url>"
"""
{
@@ -30,19 +46,19 @@ Feature: Access Control
"url": "<url>",
"kid": "{acme_account1.uri}"
},
"payload": {}
"raw_payload": "<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"

View File

@@ -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(

View File

@@ -139,7 +139,7 @@ export class AcmeAccountDoesNotExistError extends AcmeError {
super({
type: AcmeErrorType.AccountDoesNotExist,
message,
status: 400,
status: 404,
error
});
this.name = "AcmeAccountDoesNotExistError";

View File

@@ -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) {