crypto/x509: normalize IP name constraints with non-zero host bits

Name constraint IP subtrees are encoded as a network address followed by
a mask. RFC 5280 permits the network address to carry non-zero host bits
(e.g. 10.10.10.10/16, denoting 10.10.0.0/16), and some CA tooling emits
this verbatim. parseNameConstraintsExtension stores the address exactly
as encoded.

The sub-quadratic constraint matcher added in Go 1.26 (constraints.go)
binary-searches the sorted constraint set using the raw stored IP and
then checks only the nearest lower-bound entry with net.IPNet.Contains.
That relies on the stored IP being the canonical masked network address.
When the address has host bits set, the containing network can sort above
the target while a lower-addressed constraint occupies the neighbor slot,
so the containing network is never tested and search reports no match.

Because this only ever yields false negatives, an excluded constraint
with host bits set could fail to match an address inside its network,
silently accepting a certificate the constraint should have rejected.

Normalize the host bits in newIPNetConstraints, where the matcher builds
its sorted set, instead of in the parser. This restores the matcher's
invariant while leaving the parsed PermittedIPRanges and ExcludedIPRanges
with the address exactly as encoded in the certificate.

Fixes #79833

Change-Id: I7ec6b0452871d32a2f3db2eb9d46802ce64ecd78
Reviewed-on: https://go-review.googlesource.com/c/go/+/787220
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
2 files changed
tree: 442efba8d48c38206221e1bd82f210f54b8141bf
  1. .github/
  2. api/
  3. doc/
  4. lib/
  5. misc/
  6. src/
  7. test/
  8. .gitattributes
  9. .gitignore
  10. codereview.cfg
  11. CONTRIBUTING.md
  12. go.env
  13. LICENSE
  14. PATENTS
  15. README.md
  16. SECURITY.md
README.md

The Go Programming Language

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.

Gopher image Gopher image by Renee French, licensed under Creative Commons 4.0 Attribution license.

Our canonical Git repository is located at https://go.googlesource.com/go. There is a mirror of the repository at https://github.com/golang/go.

Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.

Download and Install

Binary Distributions

Official binary distributions are available at https://go.dev/dl/.

After downloading a binary release, visit https://go.dev/doc/install for installation instructions.

Install From Source

If a binary distribution is not available for your combination of operating system and architecture, visit https://go.dev/doc/install/source for source installation instructions.

Contributing

Go is the work of thousands of contributors. We appreciate your help!

To contribute, please read the contribution guidelines at https://go.dev/doc/contribute.

Note that the Go project uses the issue tracker for bug reports and proposals only. See https://go.dev/wiki/Questions for a list of places to ask questions about the Go language.