open-mpic / aws-lambda-python

An implementation of the Open MPIC API using AWS-Lambda serverless fucntions written in Python as well as AWS API Gateway.
MIT License
7 stars 4 forks source link

Logic for DCV challenge checks #11

Open birgelee opened 1 month ago

birgelee commented 1 month ago

So right now our code for both DNS and HTTP DCV checks expect the challenge presented to exactly match the page or DNS record fetched from the target domain. Some feedback has been that this is potentially too restrictive as some CAs permit some amount of entropy in the response as long as the requested challenge is present.

Upon reading the BRs, it seems the CA/B Forum's stance on this is actually pretty lax. To quote TLS-BR-2.0.7:

3.2.2.4.18 Agreed‑Upon Change to Website v2 Confirming the Applicant’s control over the FQDN by verifying that the Request Token or Random Value is contained in the contents of a file.

Similar language appears to be present in the instructions of DNS validation:

3.2.2.4.7 DNS Change Confirming the Applicant’s control over the FQDN by confirming the presence of a Random Value or Request Token for either in a DNS CNAME, TXT or CAA record for either ...

Maybe I am misinterpreting this, but my understanding of this language (particularly the HTTP language) is that, if I put had a challenge string 123456 which was sent to me by a CA and I put up a document at /.well-known/pki-validaiton/don-t-issue-my-cert.html which read:

<body>
<p>123456 is not the challenge you are looking for.
Please do not issue my cert</p>
</body>

The CA would theoretically be allowed to count this as successful completion of the challenge per BR standards (obviously barring any additional restrictions in their CPS) even though significant other content was present in addition to the challenge string. The provided page does "contain" the required challenge string.

I am a bit less confident on the language regarding DNS validation but I would personally interpret this to say that a TXT record of "v=spf1 ip4:192.0.2.0 ip4:192.0.2.1 include:examplesender.email -all my_challenge_value_123456" at the target domain would be grounds to permit issuance.

However, ACME RFC8555 seems to be a bit stricter. It clearly specifies for DNS: "Verify that the contents of one of the TXT records match the digest value"

and for HTTP it seems to only support the stripping of white space at the end of the body:

  1. Verify that the body of the response is a well-formed key authorization. The server SHOULD ignore whitespace characters at the end of the body.

With all this in mind, I think we need a fairly flexible approach to DCV checking logic. To best account for all requirements, I guess one approach could be:

Personally I think this will generally achieve compliance. The only way it could potentially lead to a non-compliant check is if an ACME challenge is checked using contains mode (as the BRs reference RFC8555 for the ACME check and RFC8555 only permits tailing white space).

Maybe this is an argument for an explicit ACME method. The permitted HTTP paths also very from ACME to non-ACME with 3.2.2.4.18 "Agreed‑Upon Change to Website v2" expecting the path "/.well‐known/pki‐validation" and 3.2.2.4.19 "Agreed‑Upon Change to Website ‑ ACME" expecting the path "/.well-known/acme-challenge/" These paths could be enforced by the API if ACME and non-ACME validation were explicitly separated.

@sciros would be interested to know your thoughts on this as I know this was something you discussed previously.

sciros commented 1 month ago

@birgelee thanks for looking into this. I think your idea is workable and should accommodate the slightly more "involved" multiline HTTP validation checks, while letting the more straightforward checks stay basic and avoid regex.