Commit Graph

7079 Commits

Author SHA1 Message Date
Shiloh Heurich 473b4059c4
feat: Add core definitions for dns-account-01 (#8140)
## Summary

This PR introduces the foundational components required to support
the `dns-account-01` challenge type, as specified in draft-ietf-acme-dns-account-label-00:
https://datatracker.ietf.org/doc/draft-ietf-acme-dns-account-label/.

It focuses only on core definitions and SA support. PA/VA/RA logic will be in
a follow-up change.

Core Definitions & Logic:
- //core/objects.go: Added `ChallengeTypeDNSAccount01` constant and
  updated validation methods
- //core/challenges.go: Added `DNSAccountChallenge01` constructor
  and factory support

Storage Authority (SA) Support:
- //sa/model.go: Added `dns-account-01` to challenge type mappings

Testing:
- //core/*_test.go: Basic definition and validation tests
- //sa/sa_test.go: Database round-trip tests for `dns-account-01`
  challenges

Dependencies:
- Updated github.com/eggsampler/acme/v3 to release version v3.6.2
2025-07-29 09:27:04 -07:00
Aaron Gable 440c6957f9
CA: Truncate notBefore and notAfter to second-level precision (#8319)
When generating the validity period of a to-be-issued certificate,
truncate the notBefore timestamp to second-level precision, trimming off
any nanoseconds which won't be represented in the final certificate. Do
the same for the notAfter, although this should be a no-op since only
whole numbers of seconds are used to compute it from the notBefore.

It's possible that this could cause some of the maxBackdate calculations
to fail, because truncation can cause the notBefore timestamp to move up
to (nearly) 1 second earlier. However, this only becomes a concern in
practice if maxBackdate is set to 10 seconds or less.

This results in cleaner logs, since Go only prints the fractional
seconds portion of a timestamp if it is non-zero:
https://go.dev/play/p/iAeSX3VMrJD

Fixes https://github.com/letsencrypt/boulder/issues/8318
2025-07-28 15:09:55 -07:00
Samantha Frank 80c75ab435
docker: Update CI mariadb from 10.6.22 to 10.11.13 (#8321)
Closes #8307
2025-07-28 17:48:23 -04:00
Jacob Hoffman-Andrews 85d1e3cf5e
sa: use internal fqdnSet model instead of core.FQDNSet (#8314)
Fixes https://github.com/letsencrypt/boulder/issues/8112
2025-07-23 16:49:04 -07:00
James Renken 04ae9ebcda
bad-key-revoker: Add delay to mitigate race condition (#8301)
Add a `MaxExpectedReplicationLag` parameter to `bad-key-revoker`. Wait
that interval before searching for certificates to revoke.

The interval is set to only 100ms in both `test/config` and
`test/config-next` so that integration tests don't require long sleeps.
The default value within BKR is, and the production value should be,
higher.

Part of #5686
2025-07-21 14:18:19 -07:00
dependabot[bot] a3c1e62049
build(deps): bump github.com/redis/go-redis/v9 from 9.7.3 to 9.10.0 (#8313)
Bumps github.com/redis/go-redis/v9 from 9.7.3 to 9.10.0

Commits: https://github.com/redis/go-redis/compare/v9.7.3...v9.10.0
Latest changelog: https://github.com/redis/go-redis/releases/tag/v9.10.0
2025-07-18 15:17:22 -07:00
Aaron Gable cd59eed63d
Ceremony: use pre-existing SKID during cross-signing (#8311)
When cross-signing a pre-existing root, the cross-sign's Subject Key
Identifier field needs to exactly match the existing cert's Subject Key
Identifier. Rather than recompute it, copy it directly from the
"to-be-cross-signed" cert.
2025-07-18 13:08:32 -07:00
Aaron Gable 5a5ae229a0
Ceremony: allow shortening of Subject Organization Name (#8310)
In general, the ceremony tool requires that any Unrestricted Cross Sign
(see Baseline Requirements, Section 7.1.2.2.3) must have a Subject
Organization Name which is identical to the issuer's Organization Name.
Allow a special case whereby a cert (such as ISRG Root X1) which has
Subject Organization Name "Internet Security Research Group" can
cross-certify a cert (such as the upcoming Root YR) which has the
shorter string "ISRG" for that same field.

---

> [!WARNING]
> ~~Do not merge before
https://github.com/letsencrypt/boulder/pull/8309~~
2025-07-17 17:36:05 -07:00
Aaron Gable d5bb88b975
Ceremony: remove support for delegated CRL and OCSP signers (#8309)
Delegated CRL Signers are forbidden by the Baseline Requirements, and we
haven't used Delegated OCSP Responders since 2020. This code is dead,
and creates unnecessary complexity, so remove it.

At the same time, improve our README to reflect these changes and
resolve several formatting lint warnings.
2025-07-17 16:28:26 -07:00
Aaron Gable b9dbcdbba2
Dependabot: add a 30-day cooldown between go dependency updates (#8312)
Documentation for the "cooldown" config parameter is here:
https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#cooldown-
2025-07-17 14:57:58 -07:00
dependabot[bot] 15824538c1
build(deps): bump github.com/aws/aws-sdk-go-v2/service/s3 from 1.82.0 to 1.83.0 in the aws group (#8300)
Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.82.0 to 1.83.0

Changelog: https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.82.0...service/s3/v1.83.0
2025-07-14 16:45:56 -07:00
Aaron Gable cfd5c12f6f
Add hotfix tag functionality to release tool (#8290)
If given the name of a pre-existing release branch (created with
//tools/release/branch), it will:
- fetch all commits on that branch;
- compute the next release tag by incrementing the highest extant patch
version; and
- create (and optionally push) the new tag.

Most of the logic is contained in the new `nextTagOnBranch` function.
The rest of the diff is slight rearrangement to accommodate that new
function elegantly, and minor cleanups of the branch tool that I found
in the process of writing this change.
2025-07-14 10:10:28 -07:00
James Renken 7e04a7176f
test: Update cert-checker & ca configs to match prod (#8303) 2025-07-10 12:50:30 -07:00
Jacob Hoffman-Andrews 9b3fc4016b
integration: test that IPs in CN are rejected (#8299)
Followup to #8276 and #8282
2025-07-10 11:00:34 -07:00
James Renken 6ba4207153
Add IP prefix blocklist (#8278)
Fixes #8237
2025-07-09 11:28:17 -07:00
Samantha Frank 99be9909a6
test: Remove mail test srv (#8304)
Part of #8199
2025-07-09 11:03:41 -07:00
James Renken 79a7cb3c1b
bad-key-revoker, cmd: Remove unused mailer & SMTPConfig stanzas (#8302)
Part of #8199
2025-07-09 10:33:46 -07:00
James Renken 102997da4a
sa: Drop LockCol from registrations table in db-next (#8298)
`LockCol` in the `registrations` table is no longer used or needed, as
of #8296.

Part of #7934
2025-07-09 09:38:13 -07:00
James Renken 21d304812e
test: Allow IP address issuance in config (#8295)
Issuance for IP address identifiers is now enabled in production.

Fixes #8235
2025-07-08 14:25:34 -07:00
Samantha Frank caa980f9ee
sa: Change a return type for GetEnabledRateLimitOverrides (#8280)
These methods have no callers.

Part of https://github.com/letsencrypt/boulder/issues/8165
2025-07-08 13:59:54 -04:00
James Renken e15368c205
Ignore LockCol in registrations table (#8296)
We stopped actively using `LockCol` in the `registrations` table in
#7911, and `DEFAULT`ed inserts to 0 in #7935.

Part of #7934
2025-07-07 22:07:57 -07:00
Samantha Frank a3eb6aa043
email-exporter: Use the upsert-by-email endpoint (#8297)
Prevent duplicate contacts in Pardot by using the upsert-by-email
endpoint.

Some background: In
https://github.com/letsencrypt/boulder/pull/7998#discussion_r1949702280
(later superseded by https://github.com/letsencrypt/boulder/pull/8016),
we discussed using this endpoint. It turns out I was wrong about Pardot
storing Prospects by email address; you can have multiple Prospects with
the same email. While subscribed newsletters won’t be sent to both
contacts, the onboarding process doesn’t deduplicate in this way and
will send to an email address each time it’s added, resulting in
duplicate onboarding messages.
2025-07-07 16:55:30 -07:00
Samantha Frank 05e631593e
ratelimits: Supporting additions for admin tooling (#8279)
- Export `ValidateLimit()` for use in the admin tool.
- Add utility functions `DumpOverrides()` and
`LoadOverridesByBucketKey()` to dump/load overrides to/from a YAML file.
- Export `Limit` and several of its fields to support calls to
`LoadOverridesByBucketKey()` and `ValidateLimit()`, and to return
results from `DumpOverrides()`.
- Add `BuildBucketKey()`, which builds and validates bucket keys based
on the limit name and provided components.
- Also add a `MarshalYAML()` method to `config.Duration`.

Part of https://github.com/letsencrypt/boulder/issues/8165
2025-07-07 17:01:05 -04:00
James Renken c1ce0c83d0
identifier, policy, va: Remove/reject scope zone from IPv6 addresses (#8294)
Followup to #8293
Fixes #8292
2025-07-07 13:57:21 -07:00
dependabot[bot] 5b380adb53
build(deps): bump github.com/aws/aws-sdk-go-v2/service/s3 from 1.81.0 to 1.82.0 in the aws group (#8285)
Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.81.0 to 1.82.0

Changelog: https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.81.0...service/s3/v1.82.0
2025-07-07 12:06:03 -07:00
Youfu Zhang bf0439bc12
Fix IsReservedAddr to handle IPv6 zone, add/verify tests (#8293)
- Fixes a bug where IsReservedAddr did not properly handle IPv6
addresses with a zone (scope), due to `netip.Prefix.Contains` returning
false for zoned addresses.
- Now strips the zone before checking.
- Added tests covering IPv6 addresses with zones.

Part of https://github.com/letsencrypt/boulder/pull/8292
2025-07-07 10:46:48 -07:00
Aaron Gable 9d5512abb8
Add AddressesResolved to tls-alpn-01 IP validation records (#8288)
Set the ValidationRecord.AddressesResolved field when performing
tls-alpn-01 validation on an IP address. This field is redundant with
ValidationRecord.Hostname, because we don't perform any resolution of
DNS names to IP addresses when conducting validation of an IP address.
But populating it anyway appeases the safety checks within the
Challenge.RecordsSane() method, and matches the fact that we populate it
for http-01 validation of IP addresses.

Add a check to several unit tests which fails on main but passes with
this change applied.

Fixes https://github.com/letsencrypt/boulder/issues/8286
2025-07-04 22:18:48 -07:00
Aaron Gable d7e4ed18ad
Remove the last vestiges of account contacts (#8247)
Remove the concept of an account contact from all of boulder except the
WFE. Specifically:
- Delete the UpdateRegistrationContact methods from the RA and SA
- Remove all understanding of the Contact field from the RA and SA's
NewRegistration methods
- Remove the Contact field from corepb.Registration to ensure it can
never be communicated anywhere

Note that this does not remove the Contact field from core.Registration,
as that represents an ACME API type, and we're still willing to parse
the Contact field from incoming new-account requests.

Fixes https://github.com/letsencrypt/boulder/issues/8199
2025-07-03 12:55:16 -07:00
James Renken 4d0ae36512
errors: Fix anchor link to rate limits page (#8291) 2025-07-03 11:02:44 -07:00
Aaron Gable b4675dbae6
Properly quote workflow tag push filter in yaml (#8284)
For some reason it's necessary to quote `*`, but not necessary to quote
`release-*`.

Also, switch from a single `*` to a double `**` to catch tag names that
contain `/`.
2025-07-01 09:48:35 -07:00
Aaron Gable 7d5adcdf31
CI: run release job on all tag pushes (#8283)
We don't use tags for anything other than tagging releases, so this
should run for all tags.
2025-06-30 16:24:59 -07:00
Aaron Gable a1a7a7f7e6
Reject all CSRs with an IP in the CN (#8282)
Although https://github.com/letsencrypt/boulder/pull/8231 fixed
csr.CNFromCSR to ignore Common Names that are valid IPs, that didn't
fully solve our issue: identifier.FromCSR still extracts the CN and
assumes that it is a dnsName, leading to a mismatch between the CSR's
identifiers and the Order's identifiers.

Instead, let's outright reject all CSRs which carry an IP in their
Subject Common Name. Although this doesn't have the elegance of
rejecting such CNs on a profile-by-profile basis, it matches our ongoing
effort to do away with CNs entirely.
2025-06-30 16:07:11 -07:00
github-actions[bot] 5493682a19
Update IANA special-purpose address registries (#8277) 2025-06-30 12:05:25 -07:00
Aaron Gable 8accf18e60
Create tools/release.go to automate release tagging (#6731)
Create tools/release/tag and tools/release/branch, a pair of small Go
scripts which automates the creation of release tags and hotfix
branches. It also updates our release documentation to provide
instructions on how to use these new tools.

### //tools/release/tag/main.go:

In its primary mode, this script creates a new release tag pointing at
the current tip of `main`. It assumes that you have
"github.com/letsencrypt/boulder" (i.e. this repo) set as your "origin"
remote. The new tag is always of the format "v0.YYYYMMDD.0", so that the
major version does not make any backwards-compatibility guarantees, the
minor version continues our tradition of date-stamping our version
numbers, and the patch version can be incremented by hotfix releases. It
only pushes the newly-created tag if passed the "-push" flag; otherwise
it just creates the new tag locally and exits, allowing the user to
inspect it and push it themselves.

This tag naming system is superior to our current
"release-YYYY-MM-DD[a]" system for a few reasons. First, by virtue of
being a Semver, we get access to tools (like pkg.go.dev) which
understand semver. It shortens our tags, making them easier to read in
horizontally-constrained environments like github's tag dropdowns and
releases sidebar. And it provides a dedicated place (the patch version)
for us to indicate hotfix tags, rather than our ad-hoc letter-based
suffix system.

Eventually, it will also support a mode where you supply a hotfix
release branch name, and it tags the tip of that branch instead of the
tip of main. This mode does not yet exist, to ensure that we can land
the this MVP.

### //tools/release/branch/main.go:

This script tags an existing tag name as input, and produces a new
release branch starting at that tag. The new branch has the name
"release-branch-foo", where "foo" is the major and minor of the base
tag's semantic version number. The intention is that commits will then
be merged to that release branch using the standard pull-request
workflow, and then the as-yet-unimplemented code path of the
tagging tool (see above) will be used to tag the hotfix release itself.

Fixes #5726
2025-06-30 11:32:14 -07:00
Samantha Frank 8aafb31347
ratelimits: Small cleanup in transaction.go (#8275) 2025-06-26 17:43:02 -04:00
Aaron Gable 30eac83730
RFC 9773: Update ARI URL (#8274)
https://www.rfc-editor.org/rfc/rfc9773.html is no longer a draft; it
deserves a better-looking path!
2025-06-26 08:50:44 -07:00
Aaron Gable 4e74a25582
Restore TestAccountEmailError (#8273)
This integration test was removed in the early versions of
https://github.com/letsencrypt/boulder/pull/8245, because that PR had
removed all validation of contact addresses. However, later iterations
of that PR restored (most) contact validation, so this PR restores (most
of) the TestAccountEmailError integration test.
2025-06-25 16:35:52 -07:00
James Renken 21d022840b
Really fix GHA for IANA registries (#8271) 2025-06-25 15:58:44 -07:00
Aaron Gable e110ec9a03
Confine contact addresses to the WFE (#8245)
Change the WFE to stop populating the Contact field of the
NewRegistration requests it sends to the RA. Similarly change the WFE to
ignore the Contact field of any update-account requests it receives,
thereby removing all calls to the RA's UpdateRegistrationContact method.

Hoist the RA's contact validation logic into the WFE, so that we can
still return errors to clients which are presenting grossly malformed
contact fields, and have a first layer of protection against trying to
send malformed addresses to email-exporter.

A follow-up change (after a deploy cycle) will remove the deprecated RA
and SA methods.

Part of https://github.com/letsencrypt/boulder/issues/8199
2025-06-25 15:51:44 -07:00
James Renken ea23894910
Fix GHA for IANA registries (#8270)
Add `org: read` to the IANA GHA token's scope, so it can ask
boulder-developers for review.

Add a line break formatting change from IANA.
2025-06-25 13:30:47 -07:00
James Renken 9308392adf
iana: Embed & parse reserved IP registries from primary source (#8249)
Move `policy.IsReservedIP` to `iana.IsReservedAddr`.

Move `policy.IsReservedPrefix` to `iana.IsReservedPrefix`.

Embed & parse IANA's special-purpose address registries for IPv4 and
IPv6 in their original CSV format.

Fixes #8080
2025-06-25 12:05:25 -07:00
dependabot[bot] 901f2dba7c
build(deps): bump the aws group with 4 updates (#8263)
Bumps the aws group with 4 updates:
[github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2),
[github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2),
[github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2)
and [github.com/aws/smithy-go](https://github.com/aws/smithy-go).

Updates `github.com/aws/aws-sdk-go-v2` from 1.36.4 to 1.36.5
Updates `github.com/aws/aws-sdk-go-v2/config` from 1.29.16 to 1.29.17
Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.80.2 to 1.80.3
Updates `github.com/aws/smithy-go` from 1.22.2 to 1.22.4

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-25 14:08:41 -04:00
James Renken a29f2f37d6
va: Check for reserved IP addresses at dialer creation (#8257)
Fixes #8041
2025-06-25 10:09:47 -07:00
Aaron Gable c576a200d0
Remove id-kp-clientAuth from intermediate ceremony (#8265)
Fixes https://github.com/letsencrypt/boulder/issues/8264
2025-06-24 16:19:31 -07:00
Matthew McPherrin 5ddd5acf99
Print key hash as hex in admin tool. (#8266)
The ProtoText printing of this structure prints the binary string as
escaped
utf8 text, which is essentially gibberish for my processes.

---------

Co-authored-by: Aaron Gable <aaron@letsencrypt.org>
2025-06-23 17:36:06 -07:00
Jacob Hoffman-Andrews cd02caea99
Add verify-release-ancestry.sh (#8268)
And run it from the release workflow.
2025-06-23 17:22:47 -07:00
Samantha Frank ddc4c8683b
email-exporter: Don't waste limited attempts on cached entries (#8262)
Currently, we check the cache only immediately before attempting to send
an email address. However, we only reach that point if the rate limiter
(used to respect the daily API quota) permits it. As a result, around
40% of sends are wasted on email addresses that are ultimately skipped
due to cache hits.

Replace the pre-send cache `Seen` check with an atomic `StoreIfAbsent`
executed before the `limiter.Wait()` so that limiter tokens are consumed
only for email addresses that actually need sending. Skip the
`limiter.Wait()` on cache hits, remove cache entries only when a send
fails, and increment metrics only on successful sends.
2025-06-23 14:55:53 -07:00
Jacob Hoffman-Andrews f087d280be
Add a GitHub Action that only runs on main or hotfix (#8267)
It can be used by tag protection rules to ensure that tags may only be
pushed if their corresponding commit was first pushed to main or a
hotfix branch.
2025-06-23 12:16:01 -07:00
Samantha Frank 1bfc3186c8
grpc: Enable client-side health_v1 health checking (#8254)
- Configure all gRPC clients to check the overall serving status of each
endpoint via the `grpc_health_v1` service.
- Configure all gRPC servers to expose the `grpc_health_v1` service to
any client permitted to access one of the server’s services.
- Modify long-running, deep health checks to set and transition the
overall (empty string) health status of the gRPC server in addition to
the specific service they were configured for.

Fixes #8227
2025-06-18 10:37:20 -04:00
Aaron Gable b6c5ee69ed
Make ARI error messages clearer (#8260)
Fixes https://github.com/letsencrypt/boulder/issues/8259
2025-06-17 16:55:36 -07:00