Subject: [Acme] New draft and DANGER

From: Ted Hardie <[email-masked]>
Date: Mon, 28 Sep 2015 10:57:53 -0700

Howdy working group,

As you can see, the draft-ietf version of this spec is now out, with a
significant caveat in its abstract (DANGER: Do not implement).  Obviously,
one of our first jobs as a working group it make it something that we don't
believe poses that danger.  The PR discussing the fix is here:

https://github.com/ietf-wg-acme/acme/pull/6

Please review the PR as soon as possible and provide comments to the list.

Other issues or text suggestions for the draft are, of course, also
welcome.  Please send those to the list as well.  It is handy if you can
send individual issues on separate threads, so we can track them.

Thanks,

Ted

---

From: "Salz, Rich" <[email-masked]>
Date: Mon, 28 Sep 2015 18:16:47 +0000

> Please review the PR as soon as possible and provide comments to the
> list. Other issues or text suggestions for the draft are, of course, also
> welcome.

It can be useful to open an issue on the GH repo, so that things don't get lost.

But please everyone, avoid the temptation to have all the discussion there, as opposed to this list.

Thanks.

---

From: Richard Barnes <[email-masked]>
Date: Mon, 28 Sep 2015 15:01:57 -0400

Dear WG,

I opened a few PRs over the weekend that address recently-raised issues:

* "Address signature reuse vulnerability" -
https://github.com/ietf-wg-acme/acme/pull/6
* "Address default virtual host risks" -
https://github.com/ietf-wg-acme/acme/pull/7
* "Add explicit versioning to challenges" -
https://github.com/ietf-wg-acme/acme/pull/8

I would really like to merge these and push -01 in the next few days.
It would be really helpful if a few folks could review these changes
and comment to the list (even if it's just "LGTM").

Thanks,
--Richard

On Mon, Sep 28, 2015 at 2:16 PM, Salz, Rich <[email-masked]> wrote:
> _______________________________________________
> Acme mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/acme

---

From: Ted Hardie <[email-masked]>
Date: Mon, 28 Sep 2015 13:43:36 -0700

On Mon, Sep 28, 2015 at 12:01 PM, Richard Barnes <[email-masked]> wrote:

> Dear WG,
> <https://github.com/ietf-wg-acme/acme/pull/7>
​I'm not sure this quite right.  If I understand the proposal correctly,
when a client sees http-01 but understands only http-00, the idea that one
is related to the other has no meaning, as the client can only respond to
challenges when type and version match what it has code for,​ right?

I think if we want that behavior, we'll need to specify whether a single
array can have array entries with different versions of the same challenge
type and we'll need to ensure that the same challenge type with different
versions isn't used to create full coverage.

That is, if it's okay for a challenge to be something like "Fulfil HTTP
challenge version 0 and DNS challenge version 1 OR HTTP challenge version 1
and DNS challenge version 0"",  then we should say so.  I also think we
need to explicitly rule out things like "Fulfil HTTP challenge version 0
and HTTP challenge version 1". (If the latter is okay, we shouldn't call
them versions, but treat each iteration as fully semantically distinct).

regards,

Ted
Wearing no hats

---

From: Richard Barnes <[email-masked]>
Date: Mon, 28 Sep 2015 16:50:12 -0400

On Mon, Sep 28, 2015 at 4:43 PM, Ted Hardie <[email-masked]> wrote:
> I'm not sure this quite right.  If I understand the proposal correctly, when
> a client sees http-01 but understands only http-00, the idea that one is
> related to the other has no meaning, as the client can only respond to
> challenges when type and version match what it has code for, right?
>

I was actually envisioning that the version numbers on the challenges
would only change when the challenge changed.  (I was also thinking
they would use the I-D version number, but I could go either way on
that.)  That way, two challenges have different tokens iff they entail
different behavior.  So as of version -07, you might have "http-01",
"tls-sni-03", and "dns-07".  Then when we head to RFC, we can drop the
version numbers.

However...

> and DNS challenge version 0"",  then we should say so.  I also think we need
> to explicitly rule out things like "Fulfil HTTP challenge version 0 and HTTP
> challenge version 1". (If the latter is okay, we shouldn't call them
> versions, but treat each iteration as fully semantically distinct).

... we do have that capability right now, with the "combinations"
element of the authorization object.  For example, you would represent
the above with:

{
  ...
  "challenges": [
    { "type": "http-00", ... },
    { "type": "dns-00", ... },
    { "type": "http-01", ... },
    { "type": "dns-01", ... },
  ],
 "combinations": [ [0, 2], [1, 3] ]
}

Hope that helps,
--Richard

P.S. Obviously, now that -00 is out, the PR will need to be updated to
use "-01".

---

From: Martin Thomson <[email-masked]>
Date: Mon, 28 Sep 2015 13:50:21 -0700

> challenges when type and version match what it has code for, right?

A-00 + B-01 is a bit odd, but if the server wants to support multiple
versions, then it can enumerate all the combinations.  Otherwise, A-00
and A-01 are treated as completely different challenges in every
regard.

I think that keeps it simple.  An implementation that does only one
version (the sensible thing at this point) doesn't have any complexity
to swallow.  An implementation that supports multiple versions should
probably just do the simple thing.

---

From: Ted Hardie <[email-masked]>
Date: Mon, 28 Sep 2015 14:15:10 -0700

Comments in-line, but basically I think we agree.

> "tls-sni-03", and "dns-07".  Then when we head to RFC, we can drop the
​So, I was assuming that the challenges have different tokens only if the
behavior changed and the new behavior wasn't interoperable.  I'm not sure I
would drop the version numbers when we head to RFC, but that's a discussion
for another day.​

> need
​Yes, it was the combinations facility I was referencing; sorry for not
being more clear.​

>  "combinations": [ [0, 2], [1, 3] ]
I think the spec may need to say something like:

When setting permitted combinations, administrators  should note that the
version associated with a challenge type does not need to be consistent
across combinations.  Similarly, administrators should generally avoid
creating combinations entirely out of different version of the same basic
type.  An example of the first would be:

{
  ...
  "challenges": [
 "combinations": [ [0, 3], [1, 2] ]
}

​and an example of the latter would be:

{
  ...
  "challenges": [
}​

(This is predicated on an assumption that combinations are designed to test
two or more independent things, rather than go deeper in a single type. If
that is a bad assumption, I'd like to understand why).

regards,

Ted​

---

From: Andrew Ayer <[email-masked]>
Date: Wed, 30 Sep 2015 19:32:36 -0700

On Mon, 28 Sep 2015 15:01:57 -0400

> https://github.com/ietf-wg-acme/acme/pull/6

I see that in all three challenges, the server now constructs the
authorized key object (previously, this detail was inconsistent among
the challenges).  I think this is a bad idea, and that the client
should be exclusively responsible for constructing this object.

The problem is that to be secure, the client has to check that the
server-provided object references the client's public key and not the
public key of an application-layer MitM.  The spec says to do this, but
the protocol still works if the client omits the check, which some
lazy/careless implementers might do as a shortcut. This can be avoided
by having the client construct the object instead.

The flow would be:

1. Server sends the client a challenge object containing the token.

2. Client constructs authorized key object containing its public key
and the token, and serializes it to a string.

3. Client writes serialized object to file (Simple HTTP) or computes its
hash and provisions the TLS cert (DVSNI) or TXT record (DNS) containing
the hash.  (For uniformity, perhaps Simple HTTP should use a hash also.)

4. Client base64 encodes the serialized object and sends it to the
server in the challenge response.

I think this is both simpler for the client and more robust.  It moves
complexity and security-sensitive checks from the client to the server,
which is how it should be.  There will be few server implementations
and they will be written by security-conscious developers.  In
contrast, there will be relatively more client implementations and who
knows what kinds of developers will be writing them.

-- Andrew

---

From: Richard Barnes <[email-masked]>
Date: Wed, 30 Sep 2015 21:48:32 -0700

> knows what kinds of developers will be writing them.

Sorry, I probably should have explained this better.  The thinking
here is actually to increase robustness by denying the client the
opportunity to create hash collisions.

The authorized key object is JSON, which means that the number of
serializations for it is bounded only be the size of the object the
server will accept.  If a malicious client can generate an authorized
key object that collides with a legitimate one (a second preimage),
then he can authorize his own key.  Having the server generate the
object puts all of the entropy that goes into the digest under the
control of the server.

Let's also consider what the risk is if the client screws up, i.e., if
he provisions a bad key authorization or digest.  First, since ACME
runs over HTTPS, the only entities that can attack are (1) the CA, who
is completely trusted in any case, and (2) an entity such as a CDN
that one end lets into the the HTTPS connection.  So the only real
risk is from the intermediary, who could possibly substitute in an
authorized key object with a token and key of its choosing, and
convince the client to provision it to the validation server.

However, the client is required to parse the object and echo back the
token under its signature.  If the client holds off until the server
accepts the response (i.e., returns a 2XX response) before
provisioning the validation server, then the server can verify that
the token is OK and if not, fail the validation.  Then the attack
would only work if the CA assigns the same token to the attacker's and
victim's challenges, and we already require that the token uniquely
identify the challenge.

In other words, there's a trade-off here between a little more surety
in the crypto and a little more protection against the CDN.  Given
that ambiguity about crypto bit us last time, I opted for the former.

Would it help to clarify that the CA MUST verify the token before
accepting the response, and the client MUST NOT provision the
validation until after the response is accepted?

--Richard