Subject: Re: [Acme] Just the technical comments (was: ACME draft is now in WGLC.)

From: Richard Barnes <[email-masked]>
Date: Mon, 6 Mar 2017 13:32:05 -0500

On Mon, Feb 13, 2017 at 5:02 PM, Martin Thomson <[email-masked]>
wrote:

> At Rich's request, here are the technical parts.  I assume that the
> editors will be trawling through the entirety of the original mail
> (for which I apologize).
>
> These are just the headline items, I pulled two forward because I
> think they are more important.  The others are small beans.  Of course
> I'm happy to be wrong about any of these.
>
> S6.3.2
>
>    [...] and MUST reflect [the?] value of the
>    "external-account-binding" field in the resulting account object
>
> Is this a direct copy of the MAC that was provided?  Do you realize
> that this enables a user with access to any account that was created
> with a binding to replay the binding in new accounts without actually
> having the MAC key?

How would that work?  ISTM that since the MAC is calculated over the JWK
representation of the account public key, you couldn't re-use the MAC to
convey this authorization to another key.

If there is an issue here, we do need to fix it, since the major purpose of
external account binding is to convey authorization, e.g., for EV.

It is probably overkill to reflect the whole object.  I think my preferred
solution would be to just reflect the "kid" value as you suggest.

  Would it be acceptable to just reflect that the
> binding exists?  (Potentially bad idea: just include the key id; if
> the CA wants, that key identifier could be a URL to the external
> account details page and do double-duty.)
>
> Note that this would be a violation of the stated security goal of not
> having integrity compromised by a TLS MitM or CDN.  It doesn't
> necessarily permit misissuance unless the binding to the account
> carries authorizations across, or things like that.
>
> S6.3.4
>
>    It is up to server policy
>    how long to retain data related to that account, whether to revoke
>    certificates issued by that account, and whether to send email to
>    that account's contacts.
>
> This is terrible.  If I wish to decommission an account key, then I
> can't because I might find that my certificates are all suddenly
> revoked.  Think about a large organization that has a pool of
> authorized accounts used for managing certificates.  If one of those
> needs to fall out of the pool (the machine hosting the key is being
> scrapped or rebuilt, for instance), then you don't want to have all
> the certificates that it issued disappearing suddenly.
>
> If there are good reasons to revoke certificates, then be definite
> about it and say that they go away, at least then people can plan
> around the problem.
>

As with all server behaviors here, we can't really be too prescriptive; CAs
will have compliance needs dictated by things like customers or root
programs that will be will override voluntary protocol specifications.
Some cautionary text might be warranted.

> S5.2
>
>    Servers MUST NOT respond to GET
>    requests for resources that might be considered sensitive.
>
> Since this is a requirement, it might pay to do a little due diligence
> on what might be sensitive.  I'm not sure that all implementers will
> have the same view (or same motivations) when it comes to this.
>

The only thing that comes to mind is accounts, though some CAs might also
consider authorizations sensitive.  We note that.

> S5.7
>
> In a couple of places, a specific error URN is mandated (with MUST),
> but this section only uses SHOULD for the error description.
>
>    Authorization and challenge objects can also contain error
>    information to indicate why the server was unable to validate
>    authorization.
>
> Where and how would this appear?  This needs more definition (I
> looked, but I didn't find anything further down).
>

Challenge objects have an "error" field, defined in S7.  I think the
authorization one is a stale reference.

But it looks like this para has been deleted in the latest master anyway

https://github.com/ietf-wg-acme/acme/commit/9414fafdee308bdd2faa34abd93ebb78fa8a5d24

S6.1.4
>
>    [[ Open issue: More flexible scoping? ]]
>
> Red flag.  In my view, the simple approach is fine.  New authorization
> resources are cheap.  They can even be cloned easily, even allowing
> one challenge to fulfill multiple.
>

This was already removed.

https://github.com/ietf-wg-acme/acme/pull/246/files

> S6.4.1
>
>    The server can also provide the client with direct access to an SCT
>    for a certificate using a Link relation header field with relation
>    "ct-sct".
>
> Where is this link relation type registered?  It isn't in either the
> IANA considerations section or in the registry:
> http://www.iana.org/assignments/link-relations/link-relations.xhtml
>
> The same goes for the other link relation types that are used in the
> example.  I see neither "revoke" nor "directory" being registered.
> BTW, "index" would probably do well instead of "directory", "revoke"
> seems specific enough to this usage - like "ct-sct" that using a URI
> for the relation type would probably be better than registering a link
> relation.
>

Already addressed:

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

> S6.5.1
>
>    In responding to poll requests while
>    the validation is still in progress, the server MUST return a 202
>    (Accepted) response
>
> The 202 is an odd choice here.  The resource exists and has content,
> so 200 works perfectly well for this purpose.
>

WFM.  200 + Retry-After is OK?

> S6.6
>
>    The server MAY disallow a subset of reasonCodes from
>       being used by the user.
>
> Does a server ignore the reasonCode, or does it reject the request
> when an impermissible code is chosen by the client?
>

Already addressed (in the "fail" direction):

https://github.com/ietf-wg-acme/acme/pull/251/files

> S9.2
>
>    For identifiers
>    where the server already has some public key associated with the
>    domain this attack can be prevented by requiring the client to prove
>    control of the corresponding private key.
>
> This doesn't seem right.  I believe that the model permits multiple
> accounts to act for a single domain.  Not doing so would represent a
> pretty big operational burden.  What public key does this then refer
> to?  Or is this promise not valid?
>

Agreed.  We should just delete this suggestion.

>
> S9.3
>
> You should also recommend rate limits on account creation, or your
> other mitigations might be weakened.
>

Yep.

> S9.4
>
> Does an ACME server send Referer[sic]?  What should it set it to?
>

You mean as an SSRF mitigation?  In that case, the real question is what
headers the ACME server should send in order to minimize the probability
that an attacked resource would respond to the request.  I'm not sure
Referer is great for that; wouldn't Origin be better?  And in the Origin
case, I would think the right thing to set it to would be the origin for
the server.

> S10.2
>
>    A CA that accepts TLS-based proof of domain control should attempt to
>    check whether a domain is hosted on a domain with a default virtual
>    host before allowing an authorization request for this host to use a
>    TLS-based challenge.  A default virtual host can be detected by
>    initiating TLS connections to the host with random SNI values within
>    the namespace used for the TLS-based challenge (the "acme.invalid"
>    namespace for "tls-sni-02").
>
> This doesn't seem right.  If the default vhost is an attacker, then
> they can generate the answers the server expects.  Based on this text,
> I don't actually know what the right answer might be, is it a TLS
> unrecognized_name alert?
>

While in principle, you're correct that the attacker can provide whatever
he wants, in practice, I don't think these systems are quite that agile.
Instead, I think they just let you configure fairly static parameters, so
e.g., the certificate would be constant over short time-scales.  I don't
think you can defend against the fully general case, but we can be more
precise here.

Proposed edits for this and others above in this PR:

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

Thanks,
--Richard

---

From: Martin Thomson <[email-masked]>
Date: Tue, 7 Mar 2017 11:21:26 +1100

Yes, many of these things were already addressed by Jacob and others.

> convey this authorization to another key.

Yeah, that is a detail I missed (that the MAC has a very specific form
isn't established by this point in the doc).

> solution would be to just reflect the "kid" value as you suggest.

That would be fine.

>> [re: Revocation on account deletion]
>
>
> programs that will be will override voluntary protocol specifications.  Some
> cautionary text might be warranted.

I realize that there might be cases where termination of an account
might result in revocation, but the protocol doesn't need to require
it.  (I think that this was discussed and resolved by saying that the
certificates will not be directly affected by this action.)

> WFM.  200 + Retry-After is OK?

Probably.  It's a little odd to include Retry-After on a successful
response, (503 being more common), but I can't think of anything
better.

> case, I would think the right thing to set it to would be the origin for the
> server.

I don't mean as anything.  The question is simply whether it does or
not.  It might make it easier to construct a valid response, though
I'm not sure that has reads on the ability of an attacker to generate
a valid response given the challenge structure.

It would set the value to some part of the URL that referred it.

Origin is very specific to the web security model.  It refers to the
origin that is making a request.  I wouldn't use it here.

> Proposed edits [...]

I'll review that, thanks.

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Mon, 6 Mar 2017 17:10:29 -0800

> a valid response given the challenge structure.
No, the server is not defined to send a Referer header. I think it's not
needed.