Hey Ilari,
Thanks for this analysis. I agree that a tighter and clearer binding of
the challenge/response pair to the validation transaction would be
desireable, as would more uniformity across challenges. I would like to
propose a slightly different structure, though.
===
The essential elements of a challenge are (1) the content of the challenge,
(2) the content of the response, (3) the content of the validation query,
and (4) the content of the validation response (where in 3 and 4, we mean
the part that is specific to the validation, vs. .well-known or
_acme-challenge). Right now, (1) and (2) are the same for all challenges,
but (3) and (4) differ.
http: (1) token (2) keyAuthorization (3) token (4) keyAuthorization
tls: (1) token (2) keyAuthorization (3) H(token) (4) H(keyAuthorization)
dns: (1) token (2) keyAuthorization (3) (nil) (4) H(keyAuthorization)
I think we could meet the requirements above with the following steps:
1. Update the keyAuthorization structure to be a JSON object binding the
validation to a bunch of stuff, e.g.:
{
"identifier": {"type": "dns", "value": "example.com"},
"method": "dns-01",
"key": { ... },
"nonce: "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"
}
2. Have the client provide the serialized keyAuthorization in its response
to the challenge (in ACME) and have the server verify that it decodes
properly, has only the identified fields, and the fields have the proper
values.
3. Derive the validation query and response values from the serialized
keyAuthorization value provided in the response, using a "reveal the
preimage" pattern, either:
3.a. query = H(kA), response=kA, or
3.b. query = H(H(kA)), response=H(kA)
I kind of like the latter better, because it meets all the transport
requirements for DNS and TLS (since the hashes are small). It also enables
the server to verify that a challenge/response pair is valid without
necessarily revealing to the server the details of the validation; if the
server really wants to know, it can demand the raw key authorization.
That would give us a uniform structure across challenges:
all: (1) token (2) keyAuthorization (3) H(H(keyAuthorization)) (4)
H(keyAuthorization)
What would folks think of that? It's a large-ish change for this stage of
the process, but it seems like the regularity it provides will help
simplify analysis and make implementation easier, so I'm inclined to do it.
Thanks,
--Richard
On Tue, Jun 13, 2017 at 1:23 PM, Ilari Liusvaara <[email protected]>
wrote:
> On Tue, Jun 13, 2017 at 11:59:21AM -0400, Richard Barnes wrote:
> > Hey Zach,
> >
> > Thanks for submitting a PR on this. I just filed a review with some
> > specific comments:
> >
> > https://github.com/ietf-wg-acme/acme/pull/312#pullrequestreview-43769669
> >
> > This change seems fine to me, especially if we make the change I propose
> in
> > there to digest the whole key authorization instead of just the token. I
> > don't think there's a security problem here, but I also don't think
> > stateless clients are tremendously valuable to the ecosystem, and it
> seems
> > conservative to require more knowledge on the part of the verification
> host.
> >
> > Looking at the thread, I'm not seeing strong objections. Unless I hear
> > something here before Zach updates the PR, I'll go ahead and merge once
> > that's done.
>
> I think that if one wanted to be consistent among different validation
> methods, then challenges would be based on hash of one thing, and the
> responses would be (hash of) another.
>
> However, I do not think it is sufficient for security to take just the
> random token for request, and random token + accout JWT for response.
>
> The problems with do not manifest in HTTP nor DNS, since HTTP and DNS
> requests are also bound to the validatio name (via virtual host
> and QNAME respectively) as fundamential part of request process.
>
> However, TLS-SNI is another matter. There is nothing binding validation
> to domain name, not even if preimages are disclosed. And this in my view
> causes TLS-SNI to fail to validate the domain itself, instead validating
> the underlying IP address.
>
> Now, the lack of this binding does not manifest when the server is
> dedicated and the webmaster has full control of the entiere server,
> however it does manifest if the server is shared between multiple
> tenants. The server has no way of determining if the challenge-
> response pairs are legimate or not.
>
> To fix this, I think that the identifier being validated should be
> included in requests (and possibly responses).
>
>
> One scheme I considered earlier (but didn't actually send a mail about,
> due to writing the mail to a wrong place):
>
>
> Request form would be (before hashing):
>
> TR.<random>.<method>.<identifierbase64url>
>
>
> And response form would be (possibly before hashing):
>
> KA.<random>.<method>.<identifierbase64url>.<accountjwt>
>
>
> (I included message tags and methods to follow good practice of
> separating different messages, altough in this case, there is no
> way to confuse the two, since number of periods is different.)
>
>
> Now, disclosing the preimages allows verifying that the challenge-
> response pair is a validation of legimate domain.
>
>
>
>
> -Ilari
>
_______________________________________________
Acme mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/acme