Commit Graph

704 Commits

Author SHA1 Message Date
James Renken 7214b285e4
identifier: Remove helper funcs from PB identifiers migration (#8236)
Remove `ToDNSSlice`, `FromProtoWithDefault`, and
`FromProtoSliceWithDefault` now that all their callers are gone. All
protobufs but one have migrated from DnsNames to Identifiers.

Remove TODOs for the exception, `ValidationRecord`, where an identifier
type isn't appropriate and it really only needs a string.

Rename `corepb.ValidationRecord.DnsName` to `Hostname` for clarity, to
match the corresponding PB's field name.

Improve various comments and docs re: IP address identifiers.

Depends on #8221 (which removes the last callers)
Fixes #8023
2025-06-13 12:55:32 -07:00
James Renken ac68828f43
Replace most uses of net.IP with netip.Addr (#8205)
Retain `net.IP` only where we directly work with `x509.Certificate` and
friends.

Fixes #5925
Depends on #8196
2025-05-27 15:05:35 -07:00
James Renken aaaf623d49
va: Remove deprecated Domain from vapb.IsCAAValidRequest (#8193)
Part of #8023
2025-05-16 15:21:28 -07:00
Aaron Gable e01bc22984
Update protoc-gen-go to match updated grpc libraries (#8151)
https://github.com/letsencrypt/boulder/pull/8150 updated our runtime
protobuf dependency from v1.34.1 to v1.36.5. This change does the same
for our build-time dependency, to keep them in sync.
2025-05-01 17:14:57 -07:00
Jacob Hoffman-Andrews 203c836925
core: remove `db:` tags for Registration and Authorization (#8113)
These objects aren't used for database serialization anymore. Instead
the SA uses an internal model object.
2025-04-10 15:59:16 -07:00
James Renken ff9e59d70b
core: Remove DnsNames from Order (#8108)
Remove the deprecated `DnsNames` field from the `corepb.Order` proto
message. All users of this struct use `Identifiers` instead.

This unblocks future changes that will require `Order` users to handle
different identifier types.

Part of #7311
2025-04-08 15:17:18 -07:00
James Renken 767abc73a4
core: Remove DnsName from Authorization (#8097)
Remove the deprecated `DnsName` field from the core `Authorization`
struct. All users of this struct use `Identifier` instead.

This unblocks future changes that will require `Authorization` users to
handle different identifier types.

Part of #7311
2025-04-07 15:25:59 -07:00
James Renken 3f879ed0b4
Add Identifiers to Authorization & Order structs (#7961)
Add `identifier` fields, which will soon replace the `dnsName` fields,
to:
- `corepb.Authorization`
- `corepb.Order`
- `rapb.NewOrderRequest`
- `sapb.CountFQDNSetsRequest`
- `sapb.CountInvalidAuthorizationsRequest`
- `sapb.FQDNSetExistsRequest`
- `sapb.GetAuthorizationsRequest`
- `sapb.GetOrderForNamesRequest`
- `sapb.GetValidAuthorizationsRequest`
- `sapb.NewOrderRequest`

Populate these `identifier` fields in every function that creates
instances of these structs.

Use these `identifier` fields instead of `dnsName` fields (at least
preferentially) in every function that uses these structs. When crossing
component boundaries, don't assume they'll be present, for
deployability's sake.

Deployability note: Mismatched `cert-checker` and `sa` versions will be
incompatible because of a type change in the arguments to
`sa.SelectAuthzsMatchingIssuance`.

Part of #7311
2025-03-26 10:30:24 -07:00
James Renken b4308df0cc
identifier: Add FromCert & FromCSR; move Normalize from core (#8065)
Part of #7311
2025-03-19 17:03:59 -04:00
James Renken cb94164b54
policy: Add initial Identifier support (#8064)
Change WillingToIssue and WellFormedDomainNames to use Identifiers, and
(for now) reject non-DNS identifiers.

Part of #7311
2025-03-14 11:34:59 -07:00
James Renken edc3c7fa6d
Shorten "identifier(s)" in variable names & function arguments (#8066)
For consistency, and to prevent confusion with the `identifier` package,
use "ident(s)" instead.

Part of #7311
2025-03-14 10:59:38 -07:00
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
James Renken 3e6a8e2d25
va: Support IP address identifiers (#8020)
Add an `identifier` field to the `va.PerformValidationRequest` proto, which will soon replace its `dnsName` field.

Accept and prefer the `identifier` field in every VA function that uses this struct. Don't (yet) assume it will be present.

Throughout the VA, accept and handle the IP address identifier type. Handling is similar to DNS names, except that `getAddrs` is not called, and consider that:
- IPs are represented in a different field in the `x509.Certificate` struct.
- IPs must be presented as reverse DNS (`.arpa`) names in SNI for [TLS-ALPN-01 challenge requests](https://datatracker.ietf.org/doc/html/rfc8738#name-tls-with-application-layer-).
- IPv6 addresses are enclosed in square brackets when composing or parsing URLs.

For HTTP-01 challenges, accept redirects to bare IP addresses, which were previously rejected.

Fixes #2706
Part of #7311
2025-03-06 11:39:22 -08:00
Aaron Gable a00821ada6
Scale ARI suggested window to cert lifetime (#8024)
Compute the width of the ARI suggested renewal window as 2% of the
validity period. This means that 90-day certificates have their
suggested window shrink slightly from 48 hours to 43.2 hours, and gives
six-day (160h) certs a suggested window 3.2 hours wide.

Also move the center of that window to the midpoint of the certificate
validity period for certs which are valid for less than 10 days, so that
operators have (proportionally) a little more time to respond to renewal
issues.

Fixes https://github.com/letsencrypt/boulder/issues/7996
2025-03-05 15:32:25 -08:00
Aaron Gable 86ab2ed245
SA: Support profiles associated with authorizations (#7956)
Add "certificateProfileName" to the model used to insert new authz2 rows
and to the list of column names read when retrieving rows from the
authz2 table. Add support for this column to the functions which convert
to and from authz2 model types.

Add support for the profile field to core types so that it can be
returned by the SA.

Fixes https://github.com/letsencrypt/boulder/issues/7955
2025-01-27 14:53:30 -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 45a56ae9bd
database: No longer store or retrieve InitialIP (#7942)
The initialIP column has been defaulted to 0.0.0.0 since #7760. Remove
this field from the all structs while leaving the schema itself intact.

Part of #7917
2025-01-13 17:33:59 -05: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 c2632585f5
core: Move canceled.Is to core.IsCanceled (#7831)
Small refactor to use errors.Is() rather than the equality operator.
Also moves this utility function into core.
2024-11-20 13:10:02 -05:00
Samantha Frank a8cdaf8989
ratelimit: Remove legacy registrations per IP implementation (#7760)
Part of #7671
2024-11-19 18:39:21 -05:00
Aaron Gable 84b15eb911
Truncate ARI timestamps to 1-second resolution (#7784)
There's no reason for us to be providing nanosecond precision on ARI
timestamps, and apparently it messes up some JSON date-parsing
libraries.

Fixes https://github.com/letsencrypt/boulder/issues/7779
2024-11-05 10:04:27 -08:00
Samantha Frank b69c005d85
WFE: Use JSON tags to omit the Authorization ID and RegistrationID fields (#7769)
Use the `-` JSON tag to omit `ID` and `RegistrationID` fields instead of
mutating the core.Authorization object.
2024-10-28 14:52:18 -04:00
Samantha Frank 37b85fbd38
VA/RVA: Add metadata necessary for the MPIC ballot (#7732)
- Add `Perspective` and `RIR` fields to the remote-va configuration
- Configure RVA ValidationAuthorityImpl instances with the contents of
the JSON configuration
- Configure VA ValidationAuthorityImpl instances with the constant
`va.PrimaryPerspective`
- Log `Perspective` for non-Primary Perspectives, per the MPIC
requirements in section 5.4.1 (2) vii of the BRs. Also log the RIR for
posterity.
- Introduce `ValidationResult` RPC fields `Perspective` and `Rir`, which
are not currently used but will be required for corroboration in #7616

Fixes https://github.com/letsencrypt/boulder/issues/7613
Part of https://github.com/letsencrypt/boulder/issues/7615
Part of https://github.com/letsencrypt/boulder/issues/7616
2024-10-10 09:37:55 -04:00
Samantha Frank 61a9aa5353
WFE: Plumb ARI explanationURL through for incidents (#7730) 2024-09-30 15:25:22 -04:00
Aaron Gable dad9e08606
Lay the groundwork for supporting IP identifiers (#7692)
Clean up how we handle identifiers throughout the Boulder codebase by
- moving the Identifier protobuf message definition from sa.proto to
core.proto;
- adding support for IP identifier to the "identifier" package;
- renaming the "identifier" package's exported names to be clearer; and
- ensuring we use the identifier package's helper functions everywhere
we can.

This will make future work to actually respect identifier types (such as
in Authorization and Order protobuf messages) simpler and easier to
review.

Part of https://github.com/letsencrypt/boulder/issues/7311
2024-08-30 11:40:38 -07:00
Aaron Gable d58d09615a
Improve how we disable challenge types (#7677)
When creating an authorization, populate it with all challenges
appropriate for that identifier, regardless of whether those challenge
types are currently "enabled" in the config. This ensures that
authorizations created during a incident for which we can temporarily
disabled a single challenge type can still be validated via that
challenge type after the incident is over.

Also, when finalizing an order, check that the challenge type used to
validation each authorization is not currently disabled. This ensures
that, if we temporarily disable a single challenge due to an incident,
we don't issue any more certificates using authorizations which were
fulfilled using that disabled challenge.

Note that standard rolling deployment of this change is not safe if any
challenges are disabled at the same time, due to the possibility of an
updated RA not filtering a challenge when writing it to the database,
and then a non-updated RA not filtering it when reading from the
database. But if all challenges are enabled then this change is safe for
normal deploy.

Fixes https://github.com/letsencrypt/boulder/issues/5913
2024-08-29 15:38:50 -07:00
Aaron Gable da7865cb10
Add go1.23.0 to CI (#7665)
Begin testing on go1.23. To facilitate this, also update /x/net,
golangci-lint, staticcheck, and pebble-challtestsrv to versions which
support go1.23. As a result of these updates, also fix a handful of new
lint findings, mostly regarding passing non-static (i.e. potentially
user-controlled) format strings into Sprintf-style functions.

Additionally, delete one VA unittest that was duplicating the checks
performed by a different VA unittest, but with a context timeout bug
that caused it to break when go1.23 subtly changed DialContext behavior.
2024-08-23 14:56:53 -07:00
Aaron Gable e1790a5a02
Remove deprecated sapb.NewAuthzRequest fields (#7651)
Remove the id, identifierValue, status, and challenges fields from
sapb.NewAuthzRequest. These fields were left behind from the previous
corepb.Authorization request type, and are now being ignored by the SA.

Since the RA is no longer constructing full challenge objects to include
in the request, remove pa.ChallengesFor and replace it with the much
simpler pa.ChallengeTypesFor.

Part of https://github.com/letsencrypt/boulder/issues/5913
2024-08-15 15:35:10 -07:00
Aaron Gable 46859a22d9
Use consistent naming for dnsName gRPC fields (#7654)
Find all gRPC fields which represent DNS Names -- sometimes called
"identifier", "hostname", "domain", "identifierValue", or other things
-- and unify their naming. This naming makes it very clear that these
values are strings which may be included in the SAN extension of a
certificate with type dnsName.

As we move towards issuing IP Address certificates, all of these fields
will need to be replaced by fields which carry both an identifier type
and value, not just a single name. This unified naming makes it very
clear which messages and methods need to be updated to support
non-dnsName identifiers.

Part of https://github.com/letsencrypt/boulder/issues/7647
2024-08-12 14:32:55 -07:00
Aaron Gable fa732df492
Remove challenge.ProvidedKeyAuthorization (#7655)
This field was deprecated in
https://github.com/letsencrypt/boulder/pull/7515, and has been fully
replaced by vapb.PerformValidationRequest.ExpectedKeyAuthorization.

Fixes https://github.com/letsencrypt/boulder/issues/7514
2024-08-12 14:08:06 -07:00
Aaron Gable 61b484c13b
Update to math/rand/v2 (#7657)
Replace all of Boulder's usage of the Go stdlib "math/rand" package with
the newer "math/rand/v2" package which first became available in go1.22.
This package has an improved API and faster performance across the
board.

See https://go.dev/blog/randv2 and https://go.dev/blog/chacha8rand for
details.
2024-08-12 09:17:09 -07:00
Aaron Gable a21c417bc0
Remove RSA KEX tracking from validation (#7629)
We used this data to inform our decision making, and have now fully
turned off support for RSA KEX during validation. This log event field
will now never be set, so it can be removed.

Part of https://github.com/letsencrypt/boulder/issues/7321
Fixes https://github.com/letsencrypt/boulder/issues/7628
2024-07-26 12:36:29 -04:00
Samantha Frank 986c78a2b4
WFE: Reject new orders containing paused identifiers (#7599)
Part of #7406
Fixes #7475
2024-07-25 13:46:40 -04:00
Aaron Gable 09693f03dc
Deprecate Challenge.ProvidedKeyAuthorization (#7515)
The core.Challenge.ProvidedKeyAuthorization field is problematic, both
because it is poorly named (which is admittedly easily fixable) and
because it is a field which we never expose to the client yet it is held
on a core type. Deprecate this field, and replace it with a new
vapb.PerformValidationRequest.ExpectedKeyAuthorization field.

Within the VA, this also simplifies the primary logic methods to just
take the expected key authorization, rather than taking a whole (largely
unnecessary) challenge object. This has large but wholly mechanical
knock-on effects on the unit tests.

While we're here, improve the documentation on core.Challenge itself,
and remove Challenge.URI, which was deprecated long ago and is wholly
unused.

Part of https://github.com/letsencrypt/boulder/issues/7514
2024-06-04 14:48:36 -07:00
Aaron Gable 89213f9214
Use generic types for gRPC stream implementations (#7501)
Update the version of protoc-gen-go-grpc that we use to generate Go gRPC
code from our proto files, and update the versions of other gRPC tools
and libraries that we use to match. Turn on the new
`use_generic_streams` code generation flag to change how
protoc-gen-go-grpc generates implementations of our streaming methods,
from creating a wholly independent implementation for every stream to
using shared generic implementations.

Take advantage of this code-sharing to remove our SA "wrapper" methods,
now that they have truly the same signature as the SARO methods which
they wrap. Also remove all references to the old-style stream names
(e.g. foopb.FooService_BarMethodClient) and replace them with the new
underlying generic names, for the sake of consistency. Finally, also
remove a few custom stream test mocks, replacing them with the generic
mocks.ServerStreamClient.

Note that this PR does not change the names in //mocks/sa.go, to avoid
conflicts with work happening in the pursuit of
https://github.com/letsencrypt/boulder/issues/7476. Note also that this
PR updates the version of protoc-gen-go-grpc that we use to a specific
commit. This is because, although a new release of grpc-go itself has
been cut, the codegen binary is a separate Go module with its own
releases, and it hasn't had a new release cut yet. Tracking for that is
in https://github.com/grpc/grpc-go/issues/7030.
2024-05-24 13:54:25 -07:00
Aaron Gable eb607e5b10
Remove more test keys (#7488)
Part of https://github.com/letsencrypt/boulder/issues/7476
2024-05-16 11:20:07 -04:00
Aaron Gable e05d47a10a
Replace explicit int loops with range-over-int (#7434)
This adopts modern Go syntax to reduce the chance of off-by-one errors
and remove unnecessary loop variable declarations.

Fixes https://github.com/letsencrypt/boulder/issues/7227
2024-04-22 10:34:51 -07:00
Phil Porada 5f616ccdb9
Upgrade go-jose from v2.6.1 to v.4.0.1 (#7345)
Upgrade from the old go-jose v2.6.1 to the newly minted go-jose v4.0.1. 
Cleans up old code now that `jose.ParseSigned` can take a list of
supported signature algorithms.

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

---------

Co-authored-by: Aaron Gable <aaron@letsencrypt.org>
2024-04-02 17:49:51 -04:00
Aaron Gable 8d169a8dfb
Add certificateProfileName to RA, SA, and Core order protos (#7381)
This adds the profile name to the proto messages necessary to propagate
it from the WFE to the SA, and from the SA to the CA. This change is
safe to land prior to any logic being added, and unblocks
profile-handling logic changes to the WFE, RA, SA, and CA.

Part of https://github.com/letsencrypt/boulder/issues/7309
2024-03-14 13:46:58 -04:00
Samantha a97e074b5a
WFE/ARI: Add method for tracking certificate replacement (#7298)
Implement draft-ietf-acme-ari-02 changes in WFE newOrder:
- Add a `replaces` field to the newOrder request object
- Ensure that `replaces` values provided by subscribers are vetted
according to the requirements set out in the draft specification
- When a NewOrder request falls inside the suggested RenewalWindow,
exempt from rate limits in the WFE and indicate exemption in the RA
NewOrder request

Part of #7038
2024-02-26 16:47:08 -05:00
Aaron Gable b483ec2280
VA: Add metrics to measure key exchange cipher suites (#7322)
Add a new field to the structured JSON object logged by the VA
indicating whether the HTTP-01 or TLS-ALPN-01 requests ended up
negotiating a TLS cipher suite which uses RSA key exchange. This is
useful for measuring how many servers we reach out to are RSA-only, so
we can determine the deprecation timeline for RSA key exchange (which
has been removed from go1.22).

The go TLS library always prefers ECDHE key exchange over RSA, so we
should only be negotiating RSA key exchange if the server we're reaching
out to doesn't support ECDHE at all.

Part of https://github.com/letsencrypt/boulder/issues/7321
2024-02-13 17:44:23 -08:00
Phil Porada aece244f3b
test: Use more //test/hierarchy/ key material in tests (#7318)
The `//ca/ca_test.go` `setup` function will now create issuers that each
have a unique private key from `//test/hierarchy/`, rather than multiple
issuers sharing a private key. This was spotted while reviewing an [OCSP
test](10e894a172/ca/ocsp_test.go (L53-L87)).
Some now unnecessary key material has been deleted from `//test/`.

Fixes https://github.com/letsencrypt/boulder/issues/7304
2024-02-09 14:39:07 -05:00
Phil Porada 0e9f5d3545
va: Audit log which DNS resolver performs a lookup (#7271)
Adds the chosen DNS resolver to the VAs `ValidationRecord` object so
that for each challenge type during a validation, boulder can audit log
the resolver(s) chosen to fulfill the request..

Fixes https://github.com/letsencrypt/boulder/issues/7140
2024-02-05 14:26:39 -05:00
Matthew McPherrin 2f114f8a9b
Fix doc comment on core.KeyDigest (#7281)
This functionality was changed in
https://github.com/letsencrypt/boulder/pull/4745
but the doc wasn't updated.
2024-01-24 14:23:08 -08:00
Viktor Szépe 5c0ca04575
Fix typos (#7241)
Found new misspellings using the `typos` rust crate:
https://crates.io/crates/typos
2024-01-09 13:17:27 -08:00
Shiloh Heurich a55bf19ea0
Correct Comments on Challenge Construction in `core/challenges.go` (#7242)
This PR addresses a discrepancy between the code comments and the actual
behavior in the challenge construction functions within
`core/challenges.go`. The existing comments suggest that these functions
generate a random token if the supplied token is empty. However, upon
reviewing the relevant code, it's evident that these functions do not
generate a random token; they simply use the token that is passed to
them.

The [only calling
code](a3afce5f75/policy/pa.go (L561-L571))
in `policy/pa.go` demonstrates this behavior:

```go
token := core.NewToken()

for i, t := range challTypes {
	c, err := core.NewChallenge(t, token)
	// ... additional code ...
}
```

This change corrects the comments to reflect actual behavior.
2024-01-08 14:55:33 -08:00
Samantha d281702c17
PA: Improve wildcard exact blocklist implementation (#7218)
Revamp WillingToIssueWildcards to WillingToIssue. Remove the need for
identifier.ACMEIdentifiers in the WillingToIssue(Wildcards) method.
Previously, before invoking this method, a slice of identifiers was
created by looping over each dnsName. However, these identifiers were
solely used in error messages.

Segment the validation process into distinct parts for domain
validation, wildcard validation, and exact blocklist checks. This
approach eliminates the necessity of substituting *. with x. in wildcard
domains.

Introduce a new helper, ValidDomain. It checks that a domain is valid
and that it doesn't contain any invalid wildcard characters.
Functionality from the previous ValidDomain is preserved in
ValidNonWildcardDomain.

Fixes #3323
2023-12-19 14:22:18 -05:00
Phil Porada 6925fad324
Finish migration from int64 timestamps to timestamppb (#7142)
This is a cleanup PR finishing the migration from int64 timestamps to
protobuf `*timestamppb.Timestamps` by removing all usage of the old
int64 fields. In the previous PR
https://github.com/letsencrypt/boulder/pull/7121 all fields were
switched to read from the protobuf timestamppb fields.

Adds a new case to `core.IsAnyNilOrZero` to check various properties of
a `*timestamppb.Timestamp` reducing the visual complexity for receivers.

Fixes https://github.com/letsencrypt/boulder/issues/7060
2023-11-27 13:37:31 -08:00
Phil Porada caf73f2762
Explicitly check each interface type in core.IsAnyNilOrZero (#7168)
I introduced a bug in https://github.com/letsencrypt/boulder/pull/7162
which lead to incorrect type comparisons.

`IsAnyNilOrZero` takes a variadic amount of interfaces with each
interface containing a value with underlying type `string`, `int32`,
`float64`, etc and checks for that type's zero value in a switch
statement. When checking for multiple numeric types on the same case
statement line, the compiler will default to `int` rather than implying
the type of the untyped constant `0` leading to an incorrect result at
runtime. Contrast that to when each numeric type is on its own case
statement line where a correct comparison can be made.

Per [go.dev/blog/constants](https://go.dev/blog/constants):
> The default type of an untyped constant is determined by its syntax.
For string constants, the only possible implicit type is string. For
[numeric constants](https://go.dev/ref/spec#Numeric_types), the implicit
type has more variety. Integer constants default to int, floating-point
constants float64, rune constants to rune (an alias for int32), and
imaginary constants to complex128.

Per
[go.dev/doc/effective_go](https://go.dev/doc/effective_go#interfaces_and_types):
> Constants in Go are just that—constant. They are created at compile
time, even when defined as locals in functions, and can only be numbers,
characters (runes), strings or booleans. Because of the compile-time
restriction, the expressions that define them must be constant
expressions, evaluatable by the compiler.

See the following code for an explicit example.
```
package main
import "fmt"
func main() {
	for _, val := range []interface{}{1, int8(1), int16(1), int32(1), int64(1)} {
		switch v := val.(type) {
		case int, int8, int16, int32, int64:
			fmt.Printf("Type %T:\t%v\n", v, v == 1)
		}
	}
        fmt.Println("-----------------------------")
	for _, val := range []interface{}{1, int8(1), int16(1), int32(1), int64(1)} {
		switch v := val.(type) {
		case int:
			fmt.Printf("Type %T:\t%v\n", v, v == 1)
		case int8:
			fmt.Printf("Type %T:\t%v\n", v, v == 1)
		case int16:
			fmt.Printf("Type %T:\t%v\n", v, v == 1)
		case int32:
			fmt.Printf("Type %T:\t%v\n", v, v == 1)
		case int64:
			fmt.Printf("Type %T:\t%v\n", v, v == 1)
		}
	}
}

-------
Type int:	true
Type int8:	false
Type int16:	false
Type int32:	false
Type int64:	false
-----------------------------
Type int:	true
Type int8:	true
Type int16:	true
Type int32:	true
Type int64:	true
```
2023-11-20 10:31:40 -08:00
Phil Porada 01f2336317
Check more types in core.IsAnyNilOrZero (#7162)
The `core.IsAnyNilOrZero` function is used in the critical path for
issuance, ocsp generation, specific ratelimit lookups, and before
performing each domain validation. The original function heavily relies
upon the default switch case which uses the full reflect package, rather
than reflectlite which can't be used because it does not implement
`IsZero()`. We can reduce CPU utilization and increase the speed of each
call by performing some basic type checking.

Benchmarking the main branch in `before.txt` and this PR in `after.txt`
shows a noticeable reduction in CPU time between the two. I ran each
test with `go test -bench=. -count=10 | tee ${FILENAME}` and compared
them with
[benchstat](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat). The
only negatively affected case happens to be when a bool is `true` which
may just be due to a sample size of 10 test iterations.
```
$ benchstat before.txt after.txt 
goos: linux
goarch: amd64
pkg: github.com/letsencrypt/boulder/core
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
                                                     │  before.txt   │              after.txt               │
                                                     │    sec/op     │    sec/op     vs base                │
IsAnyNilOrZero/input_0-8                                6.349n ± 20%   4.660n ±  1%  -26.60% (p=0.000 n=10)
IsAnyNilOrZero/input_1-8                                7.385n ± 15%   6.316n ±  4%  -14.48% (p=0.000 n=10)
IsAnyNilOrZero/input_0#01-8                             6.803n ± 17%   4.284n ±  4%  -37.02% (p=0.000 n=10)
IsAnyNilOrZero/input_1#01-8                             6.806n ±  7%   4.430n ±  5%  -34.91% (p=0.000 n=10)
IsAnyNilOrZero/input_0#02-8                             6.321n ±  8%   4.232n ±  2%  -33.06% (p=0.000 n=10)
IsAnyNilOrZero/input_0.1-8                              7.074n ± 10%   4.176n ±  5%  -40.97% (p=0.000 n=10)
IsAnyNilOrZero/input_-8                                 7.494n ±  9%   3.242n ±  2%  -56.73% (p=0.000 n=10)
IsAnyNilOrZero/input_ahoyhoy-8                          9.839n ± 25%   3.990n ±  4%  -59.45% (p=0.000 n=10)
IsAnyNilOrZero/input_[]-8                               3.898n ± 13%   3.405n ±  2%  -12.63% (p=0.019 n=10)
IsAnyNilOrZero/input_[0]-8                              4.533n ±  6%   4.088n ±  2%   -9.82% (p=0.001 n=10)
IsAnyNilOrZero/input_[1]-8                              4.626n ±  6%   4.075n ±  5%  -11.92% (p=0.000 n=10)
IsAnyNilOrZero/input_<nil>-8                            2.854n ±  3%   2.039n ±  2%  -28.55% (p=0.000 n=10)
IsAnyNilOrZero/input_false-8                            7.269n ±  2%   6.164n ±  3%  -15.21% (p=0.000 n=10)
IsAnyNilOrZero/input_true-8                             8.047n ± 10%   9.090n ± 11%  +12.96% (p=0.003 n=10)
IsAnyNilOrZero/input_<nil>#01-8                         9.114n ±  3%   7.582n ±  2%  -16.81% (p=0.000 n=10)
IsAnyNilOrZero/input_0001-01-01_00:00:00_+0000_UTC-8   10.630n ±  3%   3.871n ±  4%  -63.58% (p=0.000 n=10)
IsAnyNilOrZero/input_2015-06-04_11:04:38_+0000_UTC-8   10.900n ±  4%   4.720n ±  2%  -56.70% (p=0.000 n=10)
IsAnyNilOrZero/input_1s-8                               9.509n ± 13%   9.024n ±  4%        ~ (p=0.393 n=10)
IsAnyNilOrZero/input_0s-8                               8.972n ±  4%   7.608n ±  2%  -15.20% (p=0.000 n=10)
geomean                                                 6.905n         4.772n        -30.89%
```

Part of https://github.com/letsencrypt/boulder/issues/7153
2023-11-15 14:50:59 -08:00