## 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
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
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
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.
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~~
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.
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.
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.
- 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
- 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
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
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
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 `/`.
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.
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
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.
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
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
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>
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>
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.
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.
- 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