Skip to content

Instantly share code, notes, and snippets.

@bifurcation
Last active December 29, 2015 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bifurcation/8c955b99bd0daec8673d to your computer and use it in GitHub Desktop.
Save bifurcation/8c955b99bd0daec8673d to your computer and use it in GitHub Desktop.
ACME Support for Pre-ACME CAs

ACME Support for Pre-ACME CAs

In order for current CAs to be able to migrate to ACME, it's important that ACME have a conceptual model that aligns with those CAs current issuance practices.

Background

Recall that the ACME proceeds roughly as follows:

  1. Applicant registers an account with the CA
  2. Applicant proves possession of one or more domains
  3. Applicant requests issuance of certificates with those domains

That gives us an object ownership model of roughly the following form:

Registration
 |
 +--* Authorization
 |
 +--* Certificate

That is, a registration representing a user's account can have multiple authorizations, which can in turn be used to issue multiple certificates belonging to the account.

Requirements

After talking with current CAs, it appears that there a few gaps between this process and the processes that current CAs follow:

  1. CAs don't issue instructions for validating names until they get a CSR
  2. CAs consider authorizations to be scoped to a particular issuance
  3. CAs bundle multiple CSRs into an "order" (e.g., for RSA and ECDSA certs with the same contents)
  4. CAs have a "buy" step that is separate from requesting issuance
  5. CAs consider renewal different from creation of a new certificate

CAs will also probably need a way to bridge between their existing account systems and ACME registrations. However, since this concern is fairly specific to the registration management process, we will save it for another time.

There will also be a need to define some new challenge types to accommodate legacy validation practices, but this should be trivial given the extensibility of the challenge space.

Our goal here is to address these needs while minimizing the additional complexity that is added to the protocol.

Revised object model and issuance process

Given these requirements, we need more nuance in our object model. For (2), we will need to give authorizations a notion of scope. To address (3), we will need an "order" abstraction, and to address (5), we will need to more clearly separate "certificate requests" from "certificate instances".

This leads us to an object model something like the following:

Registration
 |
 +--* Authorization
 |
 +--* Order
       |
       +--* Authorization
       |
       +--* CertificateRequest
             |
             +--* CertificateInstance

Note that "Authorzation" appears twice, since we're accommodating both "global" authorizations and "order" authorizations. The CA can advertise its willingness to create global authorizations by putting a "new-authz" endpoint in its directory. If that appears, the client can use that, but it must also fulfil any new authorizations/challenges that the CA requires of it in a new order.

The separate "buy" step would be represented using an update to an order object, providing any required information. Abstracting over the commercial connotations, I prefer to think of this as "activation" of the order -- converting an existing order into one that is ready to be used for issuance.

As in current ACME, the process would flow down the tree (now with a few more branches):

  1. Applicant registers an account with the CA
  2. If the CA offers global authorizations, then the applicant may make some
  3. Applicant requests issuance by sending in some CSRs to create a new order
  4. If the order returned by the CA requires more authorizations, the applicant fulfils the required challenges
  5. Once all required authorizations have been fulfilled, the applicant activates the order (if it is not already active) to issue certificates

In other words:

OLD: Register -> Authorize -> Send CSR -> [CA Issues]
NEW: Register -> Authorize* -> Send CSR -> Authorize* -> Activate? -> [CA Issues]

For CAs that allow global authorizations, this flow reduces to the former flow, assuming that applicants take advantage of global authorizations when they can. The registration and authorization step are the same. The new-certificate step is replaced by a new-order step. If the applicant has done all the necessary authorizations, then the CA can create an order object that is already ready and activated, and has all of the relevant certificates populated.

Payment challenge?

Another way to handle the "buy" operation (besides having an "activate" step) would be to have any required payment actions be handled via a new challenge. Rather than considering this a "payment" challenge, I would suggest that it be something like an "out-of-band" challenge -- the ACME client needs to have a human visit a web page and get further instructions.

{
  "type": "out-of-band",
  "href": "https://ca.com/completion/token-for-this-transaction"
}

This model would result in a simpler conceptual model, since everything blocking on the issuance would be a challenge, whether payment or domain validation. However, it could result in some additional complexity in client logic if CAs wanted to be able to only issue challenges after purchase. In that case, you would need to have the set of challenges change over time (with validation challenges added after the payment challenge was fulfilled), and have the client accommodate this possibility.


The major question at this point is whether the expanded new flow is sufficient to meet the needs of a critical mass of existing CAs. For example, is it OK to have the activation/purchase always after the authorization? Or does there need to be an option for it to come sooner?

@rmhrisk
Copy link

rmhrisk commented Dec 29, 2015

I have previously given this some thought, I think the above are required but additioanlly CAs will need support for:

  • Definition of additional identifier types (email, legalPerson, etc)
  • Ability to vailidate multiple identifiers in a single order
  • Additional chalenge types (OAUTH, emailPing, documentVerification)
  • Challenging for additional evidence (for the other certificate validation types)

For payment challenge, my thinking was I would use 402 (Payment Required) with a JSON message describing accepted payment methods, and an invoice like structure. My thinking was a JWT signed payment message from some "trusted payment" entity could be passed in on resubmission. This message would say what was paid for.

For additional evidence, my thinking was I would use 403 (Authorization Required) with a JSON message describing what additional evidence was needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment