Commit Graph

896 Commits

Author SHA1 Message Date
Samantha Frank 428fcb30de
ARI: Store and reflect optional "replaces" value for Orders (#8056)
- Plumb the "replaces" value from the WFE through to the SA via the RA
- Store validated "replaces" value for new orders in the orders table
- Reflect the stored "replaces" value to subscribers in the order object
- Reorder CertificateProfileName before Replaces/ReplacesSerial in RA
and SA protos for consistency

Fixes #8034
2025-03-12 15:09:29 -04:00
Jacob Hoffman-Andrews 7aebcb1aeb
ra: deprecate UnsplitIssuance flag (#8043)
Remove some RA tests that were checking for errors specific to the split
issuance flow. Make one of the tests test GetSCTs directly, which makes
for a much nicer test!
2025-03-06 13:43:06 -08:00
Samantha Frank e6c812a3db
va/ra: Deprecate EnforceMultiCAA and EnforceMPIC (#8025)
Replace DCV and CAA checks (PerformValidation and IsCAAValid) in
va/va.go and va/caa.go with their MPIC compliant counterparts (DoDCV and
DoCAA) in va/vampic.go. Deprecate EnforceMultiCAA and EnforceMPIC and
default code paths as though they are both true. Require that RIR and
Perspective be set for primary and remote VAs.

Fixes #7965
Fixes #7819
2025-03-03 16:33:27 -05:00
Aaron Gable a2141cb695
RA: Control MaxNames via profile (#8019)
Add MaxNames to the set of things that can be configured on a
per-profile basis. Remove all references to the RA's global maxNames,
replacing them with reference's to the current profile's maxNames. Add
code to the RA's main() to copy a globally-configured MaxNames into each
profile, for deployability.

Also remove any understanding of MaxNames from the WFE, as it is
redundant with the RA and is not configured in staging or prod. Instead,
hardcode the upper limit of 100 into the ratelimit package itself.

Fixes https://github.com/letsencrypt/boulder/issues/7993
2025-02-27 15:51:00 -06:00
Jacob Hoffman-Andrews 692bd53ae5
ca: unsplit issuance flow (#8014)
Add a new RPC to the CA: `IssueCertificate` covers issuance of both the
precertificate and the final certificate. In between, it calls out to
the RA's new method `GetSCTs`.

The RA calls the new `CA.IssueCertificate` if the `UnsplitIssuance`
feature flag is true.

The RA had a metric that counted certificates by profile name and hash.
Since the RA doesn't receive a profile hash in the new flow, simply
record the total number of issuances.

Fixes https://github.com/letsencrypt/boulder/issues/7983
2025-02-24 11:37:17 -08:00
Aaron Gable 212a66ab49
Update go versions in CI and release (#7971)
Update from go1.23.1 to go1.23.6 for our primary CI and release builds.
This brings in a few security fixes that aren't directly relevant to us.

Add go1.24.0 to our matrix of CI and release versions, to prepare for
switching to this next major version in prod.
2025-02-19 14:37:01 -08:00
Aaron Gable 3e4bc168ae
RA: Clean up deprecated validation configuration (#7992)
Remove the RA's deprecated top-level config keys which used to control
order and authz lifetimes. Make the new profile-based config keys which
replaced them required.

Since configuring a profile and default profile name is now mandatory,
always supply a profile name to the CA when requesting issuance.

Fixes https://github.com/letsencrypt/boulder/issues/7986
2025-02-11 14:35:11 -08:00
Aaron Gable 0efb2a026d
Make authz reuse expiry cutoff proportional to authz lifetime (#8000)
Continue to use a 24-hour cutoff for authzs with "long" lifetimes, so
that our behavior is unchanged for authzs created with no profile
specified. Use a 1-hour cutoff for authzs with "short" (less than
24-hour) lifetimes, so that we can reuse authzs created with modern
profiles. Use linear interpolation between those values.

Fixes https://github.com/letsencrypt/boulder/issues/7994
2025-02-11 08:41:21 -08:00
Aaron Gable 27cbd1c94c
Fix RA profile deployability issue (#8002)
If validation profiles haven't been explicitly configured, use the
default profile for all incoming requests regardless of which profile
they specify.

Fixes https://github.com/letsencrypt/boulder/issues/7605
2025-02-10 09:33:58 -08:00
Aaron Gable 2f8c6bc522
RA: Use Validation Profiles to determine order/authz lifetimes (#7989)
Add three new fields to the ra.ValidationProfile structure, representing
the profile's pending authorization lifetime (used to assign an
expiration when a new authz is created), valid authorization lifetime
(used to assign an expiration when an authz is successfully validated),
and order lifetime (used to assign an expiration when a new order is
created). Remove the prior top-level fields which controlled these
values across all orders.

Add a "defaultProfileName" field to the RA as well, to facilitate
looking up a default set of lifetimes when the order doesn't specify a
profile. If this default name is explicitly configured, always provide
it to the CA when requesting issuance, so we don't have to duplicate the
default between the two services.

Modify the RA's config struct in a corresponding way: add three new
fields to the ValidationProfiles structure, and deprecate the three old
top-level fields. Also upgrade the ra.NewValidationProfile constructor
to handle these new fields, including doing validation on their values.

Fixes https://github.com/letsencrypt/boulder/issues/7605
2025-02-04 11:44:43 -05:00
Aaron Gable 6695895f8b
RA: Don't reuse authzs with mismatched profiles (#7967)
In the RA, inspect the profile of all authorizations returned when
looking for authz reuse, and refuse to reuse any whose profile doesn't
match the requested profile of the current NewOrder request.

Fixes https://github.com/letsencrypt/boulder/issues/7949
2025-02-03 16:47:35 -05:00
Samantha Frank 1d2601515b
RA: Count new registrations with contacts (#7984)
Adding a temporary metric to estimate the rate of new contacts for
accounts.

Part of #7966
2025-02-03 11:50:43 -05:00
Samantha Frank c7da1201db
RA: Make ProfileSelectionAllowList test clearer (#7981)
Improve the test of the `ra.validationProfiles` field by providing a
constructed `map[string]*ValidationProfile` instead of constructing one
inside the test. Much like how this data is provided, or `nil`, in calls
to `ra.NewRegistrationAuthorityImpl()`.
2025-01-28 15:54:31 -05:00
Samantha Frank 811e6073d1
ra: Gate OCSP Must-Staple issuance on account-based allow list (#7976)
Add support in the RA for an allow list of accounts permitted to request
certificates containing the OCSP Must-Staple extension. If no allow list
is configured, all accounts are permitted. When a list is provided,
Finalize requests with Must-Staple are rejected unless the account is on
the list, and metrics are updated to track allowed and denied requests.

Fixes #7914
2025-01-27 14:53:11 -08:00
James Renken 3fcaebe934
core: Remove contactsPresent from Registration (#7952)
Remove the `contactsPresent` field from `corepb.Registration`, and all
places where it is set. #7933 removed all places where it was used.

Fixes #7920
2025-01-25 17:46:52 -08:00
Samantha Frank a78efb82b5
RA: Allow profile selection to be gated on account-based allow lists (#7959)
Use the new allowlist package added in #7958 to implement an
account-based allow list for profile selection in the RA.

Part of #7604
2025-01-24 12:27:24 -05:00
Jacob Hoffman-Andrews a9080705b4
ra: revoke with explicit CRL shard (#7944)
In RA.RevokedCertificate, if the certificate being revoked has a
crlDistributionPoints extension, parse the URL and pass the appropriate
shard to the SA.

This required some changes to the `admin` tool. When a malformed
certificate is revoked, we don't have a parsed copy of the certificate
to extract a CRL URL from. So, specifically when a malformed certificate
is being revoked, allow specifying a CRL shard. Because different
certificates will have different shards, require one-at-a-time
revocation for malformed certificates.

To support that refactoring, move the serial-cleaning functionality
earlier in the `admin` tool's flow.

Also, split out one of the cases handled by the `revokeCertificate`
helper in the RA. For admin malformed revocations, we need to accept a
human-specified ShardIdx, so call the SA directly in that case (and skip
stat increment since admin revocations aren't useful for metrics). This
allows `revokeCertificate` to be a more helpful helper, by extracting
serial, issuer ID, and CRL shard automatically from an
`*x509.Certificate`.

Note: we don't yet issue certificates with the crlDistributionPoints
extension, so this code will not be active until we start doing so.

Part of #7094.
2025-01-21 21:31:40 -08:00
Samantha Frank c971a053a2
RA: Replace IsCAAValid call with DoCAA (#7962)
Replace the non-MPIC-compliant IsCAAValid VA method with the correct
MPIC-compliant DoCAA VA method when the EnforceMPIC feature is enabled.
This fixes the mistake introduced in #7870.
2025-01-21 11:31:48 -08:00
Samantha Frank 87a52d6fad
RA: Delete legacy rate limit metrics (#7960)
Remove two legacy rate limits metrics which are no longer in use.
2025-01-21 12:55:03 -05:00
Aaron Gable 6b1e7f04e8
SA: Clean up pre-profile order schema and feature flag (#7953)
Deprecate the MultipleCertificateProfiles feature flag, which has been
enabled in both Staging and Prod. Delete all code protected by that flag
being false, namely the orderModelv1 type and its support code. Update
the config schema to match the config-next schema.

Fixes https://github.com/letsencrypt/boulder/issues/7324
Fixes https://github.com/letsencrypt/boulder/issues/7408
2025-01-17 17:15:01 -08:00
James Renken 7da9a83deb
ra, pb: Don't expect or validate contactsPresent (#7933)
Part of #7920

There will be a followup removing the remaining places that set
`contactsPresent`.

---------

Co-authored-by: Jacob Hoffman-Andrews <jsha+github@letsencrypt.org>
2025-01-14 15:58:56 -08:00
James Renken 2e1f733c26
ra/sa: Remove deprecated UpdateRegistration methods (#7911)
This is the final stage of #5554: removing the old, combined
`UpdateRegistration` flow, which has been replaced by
`UpdateRegistrationContact` and `UpdateRegistrationKey`. Those new
functions have their own tests.

The RA's `UpdateRegistration` function no longer has any callers (as of
#7827's deployment), so it is safely deployable to remove it from the SA
too, and its request from gRPC.

Fixes #5554

---------

Co-authored-by: Jacob Hoffman-Andrews <jsha+github@letsencrypt.org>
Co-authored-by: Aaron Gable <aaron@letsencrypt.org>
2025-01-14 13:54:06 -08:00
Jacob Hoffman-Andrews 04dec59c67
ra: log User-Agent (#7908)
In the WFE, store the User-Agent in a `context.Context` object. In our
gRPC interceptors, pass that field in a Metadata header, and re-add it
to `Context` on the server side.

Add a test in the gRPC interceptors that User-Agent is properly
propagated.

Note: this adds a new `setup()` function for the gRPC tests that is
currently only used by the new test. I'll upload another PR shortly that
expands the use of that function to more tests.

Fixes https://github.com/letsencrypt/boulder/issues/7792
2025-01-14 13:39:41 -08:00
Matthew McPherrin bb9d82b85f
Remove the dead admin-revoker tool (#7941)
The admin-revoker tool is dead. Long live the admin tool.

There's a number places that still reference admin-revoker, including
Boulder's ipki and the revocation source in the database which are still
used, even if the tool is gone. But nothing actually using the tool.
2025-01-13 17:05:15 -08:00
James Renken 274d4463d1
ra: Remove isRenewal & isARIRenewal from NewOrderRequest proto (#7932)
Fixes #7671 
Fixes #5545
2025-01-13 16:14:17 -05:00
Aaron Gable 7209bc2632
RA: Fix special error case when finalizing authz (#7929)
Replace looking for AlreadyRevoked (which is never returned by the
underlying SA method) with the correct NotFound. Also add a comment
documenting why this behavior exists.

Fixes https://github.com/letsencrypt/boulder/issues/3995
2025-01-10 15:05:00 -08:00
James Renken e4668b4ca7
Deprecate DisableLegacyLimitWrites & UseKvLimitsForNewOrder flags; remove code using certificatesPerName & newOrdersRL tables (#7858)
Remove code using `certificatesPerName` & `newOrdersRL` tables.

Deprecate `DisableLegacyLimitWrites` & `UseKvLimitsForNewOrder` flags.

Remove legacy `ratelimit` package.

Delete these RA test cases:

- `TestAuthzFailedRateLimitingNewOrder` (rl:
`FailedAuthorizationsPerDomainPerAccount`)
- `TestCheckCertificatesPerNameLimit` (rl: `CertificatesPerDomain`)
- `TestCheckExactCertificateLimit` (rl: `CertificatesPerFQDNSet`)
- `TestExactPublicSuffixCertLimit` (rl: `CertificatesPerDomain`)

Rate limits in NewOrder are now enforced by the WFE, starting here:
5a9b4c4b18/wfe2/wfe.go (L781)

We collect a batch of transactions to check limits, check them all at
once, go through and find which one(s) failed, and serve the failure
with the Retry-After that's furthest in the future. All this code
doesn't really need to be tested again; what needs to be tested is that
we're returning the correct failure. That code is
`NewOrderLimitTransactions`, and the `ratelimits` package's tests cover
this.

The public suffix handling behavior is tested by
`TestFQDNsToETLDsPlusOne`:
5a9b4c4b18/ratelimits/utilities_test.go (L9)

Some other RA rate limit tests were deleted earlier, in #7869.

Part of #7671.
2025-01-10 12:50:57 -08:00
Jacob Hoffman-Andrews 635f43266a
use core.IsAnyNilOrZero more places (#7925)
There were a bunch of places that had `TODO(#7153)`; that issue is now
closed, so let's tidy up.
2025-01-07 15:48:47 -08:00
Jacob Hoffman-Andrews ef6593d06b
ra, wfe: use TimestampsForWindow to check renewal (#7888)
And in the RA, log the notBefore of the previous issuance.

To make this happen, I had to hoist the "check for previous certificate"
up a level into `issueCertificateOuter`. That meant I also had to hoist
the "split off a WithoutCancel context" logic all the way up to
`FinalizeOrder`.
2025-01-06 10:16:53 -08:00
James Renken 62299362bd
ra/ratelimits: Update tests, use new TransactionBuilder constructor, fix ARI rate limit exception (#7869)
Add a new `ratelimits.NewTransactionBuilderWithLimits` constructor which
takes pre-populated rate limit data, instead of filenames for reading it
off disk.

Use this new constructor to change rate limits during RA tests, instead
of using extra `testdata` files.

Fix ARI renewals' exception from rate limits: consider `isARIRenewal` as
part of the `isRenewal` arg to `checkNewOrderLimits`.

Remove obsolete RA tests for rate limits that are now only checked in
the WFE.

Update remaining new order rate limit tests from deprecated `ratelimit`s
to new Redis `ratelimits`.
2024-12-18 14:23:13 -08:00
Aaron Gable 0c658f202a
Fix error when deactivating an account (#7899)
The RA's DeactivateAccount method expects the account provided to it by
the WFE to still have status Valid. The new WFE deactivation code was
hardcoding the status to Deactivated. Fix the WFE to pass the account's
current status instead.

Add an integration test to confirm both the breakage and the fix. Also
leave behind some TODOs to simplify this codepath further, and not
require the status to be provided at all.

Part of #5554
2024-12-18 10:06:08 -08:00
Jacob Hoffman-Andrews 1f9f2bccf5
sa: remove CountFQDNSetTimestamps (#7883)
This was superseded in #6220 by FQDNTimestampsForWindow and is no longer
called.
2024-12-16 12:24:01 -08:00
Jacob Hoffman-Andrews 40e100c297
doc: replace "leaky" with "token" bucket (#7881)
Mostly we refer consistently to token bucket, but these two places (one
of which is soon to be removed) still had the "leaky" terminology, which
is potentially confusing.
2024-12-10 16:39:30 -08:00
Samantha Frank dda8acc34a
RA/VA: Add MPIC compliant DCV and CAA checks (#7870)
Today, we have VA.PerformValidation, a method called by the RA at
challenge time to perform DCV and check CAA. We also have VA.IsCAAValid,
a method invoked by the RA at finalize time when a CAA re-check is
necessary. Both of these methods can be executed on remote VA
perspectives by calling the generic VA.performRemoteValidation.

This change splits VA.PerformValidation into VA.DoDCV and VA.DoCAA,
which are both called on remote VA perspectives by calling the generic
VA.doRemoteOperation. VA.DoDCV, VA.DoCAA, and VA.doRemoteOperation
fulfill the requirements of SC-067 V3: Require Multi-Perspective
Issuance Corroboration by:

- Requiring at least three distinct perspectives, as outlined in the
"Phased Implementation Timeline" in BRs section 3.2.2.9 ("Effective
March 15, 2025").
- Ensuring that the number of non-corroborating (failing) perspectives
remains below the threshold defined by the "Table: Quorum Requirements"
in BRs section 3.2.2.9.
- Ensuring that corroborating (passing) perspectives reside in at least
2 distinct Regional Internet Registries (RIRs) per the "Phased
Implementation Timeline" in BRs section 3.2.2.9 ("Effective March 15,
2026").
- Including an MPIC summary consisting of: passing perspectives, failing
perspectives, passing RIRs, and a quorum met for issuance (e.g., 2/3 or
3/3) in each validation audit log event, per BRs Section 5.4.1,
Requirement 2.8.

When the new SeparateDCVAndCAAChecks feature flag is enabled on the RA,
calls to VA.IsCAAValid (during finalization) and VA.PerformValidation
(during challenge) are replaced with calls to VA.DoCAA and a sequence of
VA.DoDCV followed by VA.DoCAA, respectively.

Fixes #7612
Fixes #7614
Fixes #7615
Fixes #7616
2024-12-10 11:26:08 -05:00
Aaron Gable 749f9afa6b
Fix RA unit test merge conflict (#7874) 2024-12-06 08:59:01 -05:00
Aaron Gable 95e5f87f9e
Add feature flag to disable pending authz reuse (#7836)
Pending authz reuse is a nice-to-have feature because it allows us to
create fewer rows in the authz database table when creating new orders.
However, stats show that less than 2% of authorizations that we attach
to new orders are reused pending authzs. And as we move towards using a
more streamlined database schema to store our orders, authorizations,
and validation attempts, disabling pending authz reuse will greatly
simplify our database schema and code.

CPS Compliance Review: our CPS does not speak to whether or not we reuse
pending authorizations for new orders.
IN-10859 tracks enabling this flag in prod

Part of https://github.com/letsencrypt/boulder/issues/7715
2024-12-05 16:14:57 -08:00
Aaron Gable aac7c22946
Simplify RA pausing unit tests (#7868)
Greatly simplify the two RA unit tests covering failed validations and
account+identifier pausing. Most importantly, directly manipulate the
ratelimit backing store during test setup, to avoid having to "perform"
extra validations.

Fixes https://github.com/letsencrypt/boulder/issues/7812
2024-12-04 13:51:37 -08:00
Aaron Gable d962c61067
RA and WFE tests: use inmem rate limit source (#7859)
The purpose of these RA and WFE unit tests is to test how they deal with
certain rate limit conditions, not to test talking to an actual redis
instance. Streamline the tests by having them talk to an in-memory rate
limits store, rather than a redis-backed one.
2024-12-03 14:52:16 -08:00
Jacob Hoffman-Andrews 5cdfa3e26c
ra: wait for validations on clean shutdown (#7854)
This reduces the number of validations that get left indefinitely in
"pending" state.

Rename `DrainFinalize()` to `Drain()` to indicate that it now covers
more cases than just finalize.
2024-12-02 11:00:17 -08:00
Samantha Frank 27a77142ad
VA: Make performRemoteValidation more generic (#7847)
- Make performRemoteValidation a more generic function that returns a
new remoteResult interface
- Modify the return value of IsCAAValid and PerformValidation to satisfy
the remoteResult interface
- Include compile time checks and tests that pass an arbitrary operation
2024-11-27 15:29:33 -05:00
Aaron Gable ded2e5e610
Remove logging of contact email addresses (#7833)
Fixes https://github.com/letsencrypt/boulder/issues/7801
2024-11-25 13:33:56 -08:00
Aaron Gable 7791262815
Rate limit deactivating pending authzs (#7835)
When a client deactivates a pending authorization, count that towards
their FailedAuthorizationsPerDomainPerAccount and
FailedAuthorizationsForPausingPerDomainPerAccount rate limits. This
should help curb the few clients which constantly create new orders and
authzs, deactivate those pending authzs preventing reuse of them or
their orders, and then rinse and repeat.

Fixes https://github.com/letsencrypt/boulder/issues/7834
2024-11-21 17:17:16 -08:00
Samantha Frank 8bf13a90f4
VA: Make PerformValidation more like DoDCV (#7828)
- Remove Perspective and RIR from ValidationRecords
- Make ValidationResultToPB Perspective and RIR aware
- Update comment for VA.PerformValidation
- Make verificationRequestEvent more like doDCVAuditLog
- Update language used in problems created by performRemoteValidation to
be more like doRemoteDCV.
2024-11-20 14:13:55 -05:00
Samantha Frank a8cdaf8989
ratelimit: Remove legacy registrations per IP implementation (#7760)
Part of #7671
2024-11-19 18:39:21 -05:00
Samantha Frank 3506f09285
RA: Make calls to countCertificateIssued and countFailedValidations synchronous (#7824)
Solves CI flakes in TestCertificatesPerDomain and
TestIdentifiersPausedForAccount that are the result of a race on the
Redis database. This has the downside of making failed validations and
successful finalizations take slightly longer.
2024-11-15 16:33:51 -05:00
Jacob Hoffman-Andrews 0d70b12a75
ra: fix unittest for resetting pause limit (#7813)
TestPerformValidation_FailedThenSuccessfulValidationResetsPauseIdentifiersRatelimit
checks for a bucket being empty after a reset. However, that bucket is
based on an account ID that is shared across multiple test cases.
Instead, use a unique account and domain for this test.

Fixes #7812
2024-11-14 15:04:38 -08:00
Jacob Hoffman-Andrews 5e385e440a
ra: clean up countFailedValidations (#7797)
Return an error and do logging in the caller. This adds early returns on
a number of error conditions, which can prevent nil pointer dereference
in those cases.

Also update the description for AutomaticallyPauseZombieClients.

Follows up #7763.
2024-11-14 16:16:36 -05:00
Jacob Hoffman-Andrews 1d8cf3e212
ra: remove special case for empty DNSNames (#7795)
This case was added to work around a test case that didn't fill it out;
instead, fill DNSNames for that test case.
2024-11-11 11:07:20 -05:00
Kruti Sutaria a79a830f3b
ratelimits: Auto pause zombie clients (#7763)
- Added a new key-value ratelimit
`FailedAuthorizationsForPausingPerDomainPerAccount` which is incremented
each time a client fails a validation.
- As long as capacity exists in the bucket, a successful validation
attempt will reset the bucket back to full capacity.
- Upon exhausting bucket capacity, the RA will send a gRPC to the SA to
pause the `account:identifier`. Further validation attempts will be
rejected by the [WFE](https://github.com/letsencrypt/boulder/pull/7599).
- Added a new feature flag, `AutomaticallyPauseZombieClients`, which
enables automatic pausing of zombie clients in the RA.
- Added a new RA metric `paused_pairs{"paused":[bool],
"repaused":[bool], "grace":[bool]}` to monitor use of this new
functionality.
- Updated `ra_test.go` `initAuthorities` to allow accessing the
`*ratelimits.RedisSource` for checking that the new ratelimit functions
as intended.

Co-authored-by: @pgporada 

Fixes https://github.com/letsencrypt/boulder/issues/7738

---------

Co-authored-by: Phil Porada <pporada@letsencrypt.org>
Co-authored-by: Phil Porada <philporada@gmail.com>
2024-11-08 13:51:41 -08:00
James Renken 6a2819a95a
Introduce separate UpdateRegistrationContact & UpdateRegistrationKey methods in RA & SA (#7735)
Introduce separate UpdateRegistrationContact & UpdateRegistrationKey
methods in RA & SA

Clear contact field during DeactivateRegistration

Part of #7716
Part of #5554
2024-11-06 10:07:31 -08:00