Skip to content

Commit

Permalink
Add documentation for RFC-conformant design implementation decisions. (
Browse files Browse the repository at this point in the history
…#5105)

@jsha suggested I re-implement a PR against Pebble regarding Authorization
reuse into Boulder (see letsencrypt/pebble#325).

This is an initial attempt. I opted to handle this by creating a new file for
"Implementation Details" that are RFC conformant and are known to have
confused client developers.
  • Loading branch information
jvanasco committed Oct 6, 2020
1 parent c1c307a commit 8e8f8bd
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -377,6 +377,13 @@ specification for various reasons. We detail these divergences (for both the
V1 and V2 API) in the [ACME divergences
doc](https://github.com/letsencrypt/boulder/blob/main/docs/acme-divergences.md).

# ACME Protocol Implementation Details

The ACME specification allows developers to make certain decisions as to how
various elements in the RFC are implemented. Some of these fully conformant
decisions are listed in [ACME implementation details
doc](https://github.com/letsencrypt/boulder/blob/main/docs/acme-implementation_details.md).

## Problems or questions?

The best place to ask dev related questions is on the [Community
Expand Down
5 changes: 5 additions & 0 deletions docs/DESIGN.md
Expand Up @@ -25,6 +25,11 @@ A couple of notes:
* In various places the Boulder implementation of ACME diverges from the current
RFC draft. These divergences are documented in [docs/acme-divergences.md](https://github.com/letsencrypt/boulder/blob/main/docs/acme-divergences.md).

* The RFC draft leaves many decisions on it's implementation to the discretion
of server and client developers. The ACME RFC is also silent on some matters,
as the relevant implementation details would be influenced by other RFCs.
Several of these details and decisions particular to Boulder are documented in [docs/acme-implementation_details.md](https://github.com/letsencrypt/boulder/blob/main/docs/acme-implementation_details.md).

* We focus on the primary ACME operations and do not include all possible
interactions (e.g. account key change, authorization deactivation)

Expand Down
3 changes: 2 additions & 1 deletion docs/acme-divergences.md
@@ -1,6 +1,7 @@
# Boulder divergences from ACME

While Boulder attempts to implement the ACME specification ([RFC 8555]) as strictly as possible there are places at which we will diverge from the letter of the specification for various reasons. This document describes the difference between RFC 8555 and Boulder's implementation of ACME, informally called ACMEv2 and available at https://acme-v02.api.letsencrypt.org/directory. Boulder's implementation of ACMEv1 differs substantially from the final RFC. Documentation for Boulder's ACMEv1 support is available in [acme-divergences-v1.md](acme-divergences-v1.md).
While Boulder attempts to implement the ACME specification ([RFC 8555]) as strictly as possible there are places at which we will diverge from the letter of the specification for various reasons. This document describes the difference between RFC 8555 and Boulder's implementation of ACME, informally called ACMEv2 and available at https://acme-v02.api.letsencrypt.org/directory. Boulder's implementation of ACMEv1 differs substantially from the final RFC. Documentation for Boulder's ACMEv1 support is available in [acme-divergences-v1.md](acme-divergences-v1.md). A listing of RFC conformant design decisions that may differ from other ACME servers is listed in [implementation_details](https://github.com/letsencrypt/boulder/blob/main/docs/acme-implementation_details.md).


Presently, Boulder diverges from the RFC 8555 ACME spec in the following ways:

Expand Down
69 changes: 69 additions & 0 deletions docs/acme-implementation_details.md
@@ -0,0 +1,69 @@
# Boulder implementation details

The ACME specification ([RFC 8555]) clearly dictates what Clients and Servers
must do to properly implement the protocol.

The specification is intentionally silent, or vague, on certain points to give
developers freedom in making certain decisions or to follow guidance from other
RFCs. Due to this, two ACME Servers might fully conform to the RFC but behave
slightly differently. ACME Clients should not "over-fit" on Boulder or the
Let's Encrypt production service, and aim to be compatible with a wide range of
ACME Servers, including the [Pebble](https://github.com/letsencrypt/pebble)
test server.

The following items are a partial listing of RFC-conformant design decisions
Boulder has made. This listing is not complete, and is based on known details
which have caused issues for developers in the past. This listing may not
reflect the current status of Boulder or the configuration of LetsEncrypt's
production instance and is provided only as a reference for client developers.

Please note: these design implementation decisions are fully conformant with the
RFC specification and are not
[divergences](https://github.com/letsencrypt/boulder/blob/main/docs/acme-divergences.md).


## Object Reuse

The ACME specification does not prohibit certain objects to be re-used.

### Authorization

Boulder may recycle previously "valid" or "pending" `Authorizations` for a given
`Account` when creating a new `Order`.

### Order

Boulder may return a previously created `Order` when a given `Account` submits
a new `Order` that is identical to a previously submitted `Order` that is in
the "pending" or "ready" state.

## Alternate Chains

The production Boulder instance for LetsEncrypt in enabled with support for
Alternate chains.


## Certificate Request Domains

The RFC states the following:

The CSR MUST indicate the exact same
set of requested identifiers as the initial newOrder request.
Identifiers of type "dns" MUST appear either in the commonName
portion of the requested subject name or in an extensionRequest
attribute [RFC2985] requesting a subjectAltName extension, or both.

Boulder requires all domains to be specified in the `subjectAltName`
extension, and will reject a CSR if a domain specified in the `commonName` is
not present in the `subjectAltName`. Additionally, usage of the `commonName`
was previously deprecated by the CA/B Forum and in earlier RFCs.

For more information on this see [Pebble Issue #304](https://github.com/letsencrypt/pebble/issues/304) and
[Pebble Issue #233] https://github.com/letsencrypt/pebble/issues/233







0 comments on commit 8e8f8bd

Please sign in to comment.