Fixes#486
This moves the GetCertificateBySerial call earlier, which means that
call needs to succeed even for revoked certificates. So this also
follows up on #252 by keeping revoked certs in the primary
certificatesByID map (while still adding them to the
revokedCertificatesByID map).
The draft spec version at the time of this PR was
draft-ietf-acme-ari-03, but failed replacement order handling is from
the [yet-to-be-released
draft-ietf-acme-ari-04](1813de294a/draft-ietf-acme-ari.md (L177)).
* Add a `renewalInfo` entry to the directory object which provides the
base URL for ARI requests.
* Add a new WFE handlefunc which parses incoming requests and returns
reasonable `renewalInfo` for determining when the client should attempt
renewal of a certificate.
* Add support for marking orders as `replaced`. Replacement orders can
be chained, but there can be no duplicate replacement of orders, just
like boulder.
* Restructured the asynchronous finalization anonymous go func to handle
storing replaced orders. To be replaced, an order must previously have
been finalized and have an issued certificate.
Switch to go-jose v4
This required a change to specify the supported signing algorithms, as
part of go-jose/v4's breaking changes to defend against some attacks on
JWS.
Because Pebble already limited the supported algorithms, it was easy to
see what the supported algorithms are.
Add lint, build (multi-platform), and test (linux-only) GitHub Actions. Fix
a variety of golangci-lint findings.
For now, does not modify the windows Appveyor setup, and does not
run the loadtester.
Fixes#356
- Use Go 1.18.x in Travis, and set go.mod version to 1.17.
- Update golangci-lint to 1.45.2 and ignore new lints.
- Update import paths to include /v2/. This fixes a problem
introduced by fixing the go.mod module path to use /v2/.
- Remove golangci-lint from appveyor.
Adds a new config value, `BlockedDomains`, which is a list of strings
representing domains for which Pebble should not issue certificates.
Adding a blocked domain such as "example.com" prevents issuance
for all subdomains of that name (e.g. "foo.example.com") as well.
If an order is rejected due to one of its names matching this blocklist,
the request will return a `rejectedIdentifier` error. This mirrors the
functionality of Boulder's Policy Authority.
Also slightly refactors the frontend's order verification code to split
domain-specific (as opposed to generic or ip-specific) checks into
their own helper function.
Signed-off-by: JoshVanL <vleeuwenjoshua@gmail.com>
This PR adds basic support for External Account Binding (EAB) as defined in the
[ACME protocol](https://tools.ietf.org/html/rfc8555#section-7.3.4).
The pebble config takes an extra argument `requireExternalBinding` which will
require new account ACME request to contain the `externalAccountBinding` object
to be present. Pebble will then verify the contents of the object as per the
spec.
The Pebble config takes an optional object of `externalAccountBindings`
containing a string map to
KIDs to MAC symmetric keys. These are stored statically in memory.
An extra config example has been made to show both options available
(test/config/pebble-config-external-account-bindings.json).
This has been tested using https://github.com/go-acme/lego. The following
command will successfully create a new account with Pebble using one of the keys
defined in the example config.
```
lego --server https://localhost:14000/dir --domains foo.com --email \
joshua.vanleeuwen@jetstack.io --http --kid kid-1 --hmac \
zWNDZM6eQGHWpSRTPal5eIUYFTu7EajVIoguysqZ9wG44nMEtx3MUAsUDkMTQ12W --eab run
```
**The keys in the example config are public and should never be used in
production**
Adds support for enumerating all orders for an ACME account object according to
RFC 8555, Section 7.1.2. By default, three orders are returned per page, to make
it easy to test pagination. This number can be modified by setting the `PEBBLE_WFE_ORDERS_PER_PAGE` environment variable to a positive integer.
For example, to have 15 orders per page, run
```
PEBBLE_WFE_ORDERS_PER_PAGE=15 pebble
```
Fixes#84.
RFC8555 mentions (https://tools.ietf.org/html/rfc8555#section-7.1.3)
that clients should check the "status" field of an order to determine
whether they need to take any action.
This commit implements authorization reuse, such that any valid and
unexpired authz completed by the ACME account for that identifier has a
chance to be reused in new orders. The chance is controlled by the env
variable PEBBLE_AUTHZREUSE and it defaults to 50 (percent). The
chance is evaluated regardless of whether there is an eligible authz to
reuse or not.
This PR changes the way account IDs are created. They used to be the SHA256 of the account's public key before. Now, they are numeric IDs (incremented by one for every new account).
This is a prerequisite for correctly implementing account key roll-over, for which the account's ID must no longer depend on the account's public key (see #151).
Adds an endpoint to the API to revoke certificates.
There are some caveats to consider:
1. It doesn't verify account ownership.
2. It doesn't verify the certificate issuer.
3. It validates the reason, but it doesn't do anything with it after.
Signed-off-by: David Calavera <david.calavera@gmail.com>
This PR updates the way Pebble handles an Order's status field to closer match the way we handle it in Boulder. This means the order's status is considered to be a calculated field derived based on the order's error/beganProcessing/certificate fields and the status/expires/error of the order's associated authorizations. Along the way the new "Ready" status was implemented. This PR also addresses the problem of the order status not being updated when an authorization is failed. Now, an order has a problem details field that is set when an authorization associated with the order has a failed challenge validation.
Resolves#110 and #98
This PR adds support for a user posting an account update to the account's URL.
Currently, this just reads a new Account object from the request body, copying across the specified Contact field as required.
The ACME spec no longer talks about "registrations" and Pebble shouldn't either. This PR updates all registration occurrences to use the term "account" instead.
**Updates the README**
5491a24 updates the README to include Chisel usage instructions
& reference the current-most draft.
**Adds multi-validation and true async issuance.**
7d615b5 splits the operation of the CA and VA across multiple
go-routines instead of doing all work on the WFE's handler routine.
The VA now performs multiple validations, sleeping a random amount of
time between each. This forces the ACME client to poll the
authorizations to learn when they have switched from pending to invalid
or valid. All validation attempts must succeed for the authorization to
be valid.
The WFE no longer communicates directly with the CA, instead when the VA
updates the last authorization on an order to valid status it invokes
the CA's CompleteOrder function in a separate goroutine. This will
complete the order & update it with a certificate pointer. The WFE uses
this pointer to construct the certificate URL as required.
This PR adds the initial CA skeleton for doing order issuance.
Pebble generates a root & intermediate keypair/certificate at startup. The intermediate is used for certificate signing purposes and the root issues the intermediate and is otherwise just there to mimick production. In the future we should introduce additional intermediates & chain options to use the full specification.
Couple other changes:
* Fixed the embedded challenges in authorizations to use a pointer so that the embedded contents are updated when the challenge is completed.
* Replaced a few WFE `Printf`'s with log statements.
* Updated the VA to log whether an HTTP validation was a success or a failure.
* Added a pointer from Authorizations to the Order they belong to
* Added enforcement of Order expiry for authz updates.
* Moved the MemoryStore out of the `wfe` package. This was primarily to let the CA store the root & intermediate certificates in the DB. This allows using the `/certZ/` endpoint to retrieve the root & intermediate.