Subject: [Acme] tls-sni-01 - is Z(0) allowed?

From: Hugo Landau <[email-masked]>
Date: Fri, 30 Oct 2015 15:04:03 +0000

After having read the specification in its current draft form, I have the
following comments and questions:

- The expiry date on authorization objects is a date and not a timestamp. This
  seems undesirable; in some cases it may be desired to issue an authorization
  for a very short period of time, such as 30 minutes. Shouldn't this field be
  a timestamp and not a date?

- The tls-sni-01 specification seems to allow SANs not of the form
  *.acme.invalid to appear. Is there any use case which requires this leeway?
  If there's no reason to allow it, it seems like something which should be
  prohibited.

- One ambiguity in the tls-sni-01 specification seems to be whether validation
  servers are allowed to query for the Z(0) value or not, or only Z(i) for i >
  0. This should probably be clarified.

- The proof of possession challenge specifies acceptable certificates, rather
  than acceptable keys. Is there some reason for this?

  Moreover, how is the ACME server supposed to state a certificate for a key
  which has never issued a certificate, such as an account key? It cannot
  create the necessary signature if it is to create a self-signed certificate.

  SubjectPublicKeyInfo (or JWK) seems more appropriate here.

- The proof of possession challenge specifies multiple certificates.  It could
  be changed to support only a single certificate, instead allowing multiple
  proof of possession challenges to be used in combinations. This would allow
  multiple prior keys to be required. On the other hand, I can't immediately
  think of a use case, so that might be overkill.

- Some examples in the spec POSTing to challenges specify the "type" field,
  while others don't. The field seems redundant, although being explicit
  here might be desirable in much the same spirit as the "resource" field.
  Which way is this supposed to go?

- The use of Location and Content-Location headers seems a bit quirky.
  Location, as far as I can tell, has no defined semantics for status code 200.
  In the GET <issued certificate URI> case, it seems redundant, but the example
  seems to suggest it should be present.

- New certificate requests can be responded to either with a certificate or
  deferral to another URI from which a certificate can (eventually) be
  obtained. This seems like an overcomplication; the deferral case can support
  the immediate case just as well.

- Automatic renewal seems dubious, especially in an era of certificate
  transparency. Eventually all certificates issued will probably be logged, and
  it would be troublesome to have certificates issued and logged which have
  been issued on purely speculative grounds. If I issue a certificate via an
  ACME CA, and then I switch to another CA, I don't want the old CA continuing
  to issuing certificates, even if nobody can use them. In the future CAs might
  use the prior issuance of other certificates for the same domain by other
  CAs, as detected via CT, as a risk indicator. I think this is alluded to in
  the specification: "domain for which known certs exist from other CAs".

  As it is, expiration provides a last resort measure taking a certificate out
  of play if e.g. the private key is lost, and the certificate cannot be
  revoked. With implicit renewal you have to wait until the applicable
  authorizations expire, presumably. It seems like a somewhat fundamental
  principle that a CA's issuance of a certificate must be connected with an
  explicit request by a domain to do so.

  Since ACME is all about automation clients can explicitly request a new
  certificate trivially if they so choose, so the value of this mechanism
  seems dubious.

- GET-triggered renewal is better, but it also seems like a needless weakness.
  The specification itself mentions that this makes certificate URLs so called
  "capability URLs", but the W3C article on capability URLs makes clear they
  aren't exactly preferred. Not to mention that GET requests aren't supposed to
  change state; and I'd argue that submission to a CT log is at least in spirit
  such a change. If there is some reason why some ACME clients might have
  difficulty generating a new CSR (either from a previous CSR or from the
  previous certificate), one option might be to allow a certificate URL to be
  passed in new certificate requests instead of a CSR. Taking this route would
  make certificate URLs immutable, removing the Content-Location complication,
  which seems like a win.

Hugo Landau

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Sat, 31 Oct 2015 12:36:21 -0700

>   a timestamp and not a date?
Agreed.
>   If there's no reason to allow it, it seems like something which should be
Agreed.
>   0. This should probably be clarified.
I have a pull request that simplifies the TLS SNI challenge by removing
the multiple zName provision: https://github.com/ietf-wg-acme/acme/pull/22.

>   than acceptable keys. Is there some reason for this?
I think the notion is that most people don't have an easy way to find a
private key associated with a particular public key, but if we give them
a whole certificate, it's easier to figure out which machine uses that
certificate, and from there where the private key might be.
>   create the necessary signature if it is to create a self-signed certificate.
I think the current notion of Proof of Possession is that it would be
used in cases where the CA knows about an overlapping certificate. I
can't think of a particular policy need to require proof of possession
across account keys, but I can see that there might be one.
>   think of a use case, so that might be overkill.
Unfortunately this would expand the size of the challenges array
dramatically. If there were some future challenge that wanted to do a
similar thing, the result would be combinatorial blowup.

>   seems to suggest it should be present.
Agreed.
>   the specification: "domain for which known certs exist from other CAs".
I agree. I think the best approach is to require an explicit POST
/acme/new-cert for each issuance. Eric Rescorla has pointed out that
this requires keeping ACME account keys on the server that handles
issuance, or putting them on there every N months, where N is the
certificate renewal period.

The goal of including GET-based renewal with no authentication was to
make it possible to keep account keys mostly offline, and bring them
online manually every M months, where M is the expiry period for
relevant authorization objects. The assumption, of course, is that M >>
N. This wind up dependent on CA policy, but as a first approximation, M
might be 12 months.

So under GET-based renewal, the sever operator still needs to do some
manual steps once a year to ensure their certificates stay up to date. I
think that violates on of ACME's main goals: to reduce accidental
certificate expiration through automation.

Additionally, GET-based renewal assumes that server operators don't want
to rotate their keys with each new issuance.