Would it be possible to extract the key and identifiers from the CSR, add
the key  to the database if it doesn't already exist, find or create the
authorizations for the identifiers, not store the CSR, and then assemble
the certificate from the (valid) authorizations and key later?

Alternatively, could one get rid of the CSRs altogether, and have the
new-order be a nested JWS? The inner JWS would be signed by the key that
goes on the certificate and would contain everything required to generate
the certificate (identifiers, requested dates if applicable, etc.). The
outer JWS would be signed by the ACME account key and link the inner JWS to
the ACME account.

What goes in a CSR or certificate that can't be reconstructed later?

Logan

On Sep 19, 2017 2:26 PM, "Daniel McCarney" <c...@letsencrypt.org> wrote:

Hi folks,

Just over a year ago in a thread titled "Proactive vs On-Finalization
Certificate Issuance"[0] we reached the consensus on the question of
whether to
issue a certificate "on-finalization" or "proactively" with the conclusion
to
standardize on proactive issuance.

Implementation experience shows that proactive issuance is slow in
practice. An
order can be associated with many authorizations and an authorization can be
associated with many orders. This interacts poorly with optimizations Let's
Encrypt has developed from in-the-field experience with ACME and it is
difficult
to rate-limit effectively. I propose that we return to the on-finalization
style
approach and that we provide the CSR during finalization..

## Issues with proactive issuance

### Authorization Reuse

Proactive issuance requires that when an authorization is switched to a
valid
state by the result of a challenge update that we find the associated
orders and
iterate each order's authorizations to see if all of the authorizations are
valid and issuance can occur.

Let's Encrypt reuses existing authorizations[1][2] whenever possible, as
encouraged by ACME. This has been of huge value in reducing resource
consumption
(both in terms of database storage and challenge/API requests). Many clients
create pending authorizations they do not finalize and similarly re-create
pending authorizations for identifiers that the account already has valid
authorizations for. Unchecked this leads to significant database growth and
resource consumption, even with aggressive rate-limits[3].

The combination of authorization reuse and proactive issuance means a given
authorization can be associated with many orders. This necessitates an
expensive
many-to-many query at each authorization update to see if any associated
orders are now complete.

One possible workaround is a rate-limit that would constrain the number of
orders an authorization can be associated with. However establishing the
value
of the limit to both reduce server-side load & also effectively support
Let's
Encrypt's large-volume integrators and their issuance patterns is
challenging.

### CSR-first new-order flow

To support proactive issuance the CA also needs to have the CSR for the
order
at-hand when checking each authorization in case issuance can proceed. The
`new-order` request that creates the order therefore carries the full CSR
that
was previously delivered by the "certificate finalize" message.

We see users create many more authorizations than they are able to finalize
successfully. With the legacy "new-cert" flow our authorization reuse
dramatically helped reduce the DB space used up by authorizations that will
never lead to issuance because no CSR is stored until all identifiers are
validated.

With the new-order flow we have to accept and store a full CSR before
handing
back authorizations to the client. Reuse of authorizations does not prevent
the
DB bloat that will occur from users submitting new order requests and not
fulfilling them. The CSR contains a full public key and is one of the single
largest contributors to DB disk space usage. Addressing this will require
another strict rate limit on outstanding new-orders and is again difficult
to
“dial-in” in to both prevent excessive resource consumption and also
maintain
the ability for big integrators to process large-scale issuance using our
API.

# Proposed Change

I believe we should change the `new-order` endpoint to not accept a full
CSR but
to instead accept a list of identifiers that the ACME client wishes to
authenticate & issue for. Authorizations can be created and returned for
those
domains as happens today.

The order resource should be changed to have a “finalizeURL” field which
provides the client a URL to POST a CSR to indicate that the CA should
issue the
certificate. Proactive issuance should be removed outright.

This will address both the problem of scanning existing many-to-many orders
& their authorizations as well as the db bloat that will occur from
front-loading the delivery of the CSR.

It may be tempting to leave proactive issuance as an optional feature but
this
will require maintaining the CSR in the new-order and I also believe that
having
two very distinct methods of issuance will complicate the client ecosystem
and
returns us to the question of how to determine which will occur that
spawned the
original "Proactive vs On-finalization Certificate Issuance"
thread[0].

[0] https://mailarchive.ietf.org/arch/msg/acme/0lVmGl8e-rmSH0x7ycDW5dj6GAY
[1] https://community.letsencrypt.org/t/upcoming-api-changes/17947
[2] https://community.letsencrypt.org/t/automatic-recycling-of-p
ending-authorizations/41321
[3] https://letsencrypt.org/docs/rate-limits/


_______________________________________________
Acme mailing list
Acme@ietf.org
https://www.ietf.org/mailman/listinfo/acme
_______________________________________________
Acme mailing list
Acme@ietf.org
https://www.ietf.org/mailman/listinfo/acme

Reply via email to