diff --git a/x509roots/fallback/bundle/bundle126_test.go b/x509roots/fallback/bundle/bundle126_test.go new file mode 100644 index 0000000..5e18bc7 --- /dev/null +++ b/x509roots/fallback/bundle/bundle126_test.go @@ -0,0 +1,47 @@ +// Copyright 2026 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.27 + +package bundle + +import ( + "encoding/asn1" + "encoding/hex" + "regexp" +) + +// subjectsEqual reports whether two RFC 2253 DN strings match. +// +// When testing with Go 1.27 or newer, it requires subjects to match exactly. +// When testing with Go 1.26, it tolerates the rendering difference introduced in Go 1.27, +// where string-typed attribute values for OIDs outside attributeTypeNames are rendered +// as strings rather than hex-encoded DER (see Go CL 773800). +// +// When Go 1.26 is no longer supported, +// the Go 1.26 version can be removed and +// the Go 1.27+ version can be inlined. +func subjectsEqual(a, b string) bool { + return a == b || normalizeHexValues(a) == normalizeHexValues(b) +} + +// normalizeHexValues rewrites any "oid=#hex" to the equivalent "oid=value" +// rendering produced by Go 1.27+. +func normalizeHexValues(s string) string { + return hexAttrRE.ReplaceAllStringFunc(s, func(match string) string { + m := hexAttrRE.FindStringSubmatch(match) + der, err := hex.DecodeString(m[2]) + if err != nil { + return match + } + var v string + if rest, err := asn1.Unmarshal(der, &v); err != nil || len(rest) != 0 { + return match + } + return m[1] + "=" + v + }) +} + +// hexAttrRE matches a "oid=#hex" attribute value in an RFC 2253 DN string. +var hexAttrRE = regexp.MustCompile(`([\d.]+)=#([[:xdigit:]]+)`) diff --git a/x509roots/fallback/bundle/bundle127_test.go b/x509roots/fallback/bundle/bundle127_test.go new file mode 100644 index 0000000..d965aa3 --- /dev/null +++ b/x509roots/fallback/bundle/bundle127_test.go @@ -0,0 +1,21 @@ +// Copyright 2026 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.27 + +package bundle + +// subjectsEqual reports whether two RFC 2253 DN strings match. +// +// When testing with Go 1.27 or newer, it requires subjects to match exactly. +// When testing with Go 1.26, it tolerates the rendering difference introduced in Go 1.27, +// where string-typed attribute values for OIDs outside attributeTypeNames are rendered +// as strings rather than hex-encoded DER (see Go CL 773800). +// +// When Go 1.26 is no longer supported, +// the Go 1.26 version can be removed and +// the Go 1.27+ version can be inlined. +func subjectsEqual(a, b string) bool { + return a == b +} diff --git a/x509roots/fallback/bundle/bundle_test.go b/x509roots/fallback/bundle/bundle_test.go index 222e76c..f2ef97d 100644 --- a/x509roots/fallback/bundle/bundle_test.go +++ b/x509roots/fallback/bundle/bundle_test.go @@ -7,9 +7,7 @@ package bundle import ( "crypto/sha256" "crypto/x509" - "encoding/asn1" "encoding/hex" - "regexp" "testing" ) @@ -32,34 +30,3 @@ func TestBundle(t *testing.T) { } } } - -// subjectsEqual reports whether two RFC 2253 DN strings match. -// -// It tolerates the rendering difference introduced in Go 1.27, where -// string-typed attribute values for OIDs outside attributeTypeNames are -// rendered as strings rather than hex-encoded DER (see Go CL 773800). -// -// This can be removed when Go 1.25/1.26 are no longer supported. -func subjectsEqual(a, b string) bool { - return a == b || normalizeHexValues(a) == normalizeHexValues(b) -} - -// normalizeHexValues rewrites any "oid=#hex" to the equivalent "oid=value" -// rendering produced by Go 1.27+. -func normalizeHexValues(s string) string { - return hexAttrRE.ReplaceAllStringFunc(s, func(match string) string { - m := hexAttrRE.FindStringSubmatch(match) - der, err := hex.DecodeString(m[2]) - if err != nil { - return match - } - var v string - if rest, err := asn1.Unmarshal(der, &v); err != nil || len(rest) != 0 { - return match - } - return m[1] + "=" + v - }) -} - -// hexAttrRE matches a "oid=#hex" attribute value in an RFC 2253 DN string. -var hexAttrRE = regexp.MustCompile(`([\d.]+)=#([[:xdigit:]]+)`)