This commit is contained in:
Mateusz Poliwczak 2025-06-20 15:37:12 -04:00 committed by GitHub
commit a499e4f31c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 18 additions and 33 deletions

View File

@ -15,7 +15,6 @@ import (
"net" "net"
"net/netip" "net/netip"
"net/url" "net/url"
"reflect"
"runtime" "runtime"
"strings" "strings"
"time" "time"
@ -537,44 +536,38 @@ func matchDomainConstraint(domain, constraint string) (bool, error) {
// form of name, suitable for passing to the match function. The total number // form of name, suitable for passing to the match function. The total number
// of comparisons is tracked in the given count and should not exceed the given // of comparisons is tracked in the given count and should not exceed the given
// limit. // limit.
func (c *Certificate) checkNameConstraints(count *int, func checkNameConstraints[T1 any, T2 any](c *Certificate,
count *int,
maxConstraintComparisons int, maxConstraintComparisons int,
nameType string, nameType string,
name string, name string,
parsedName any, parsedName T1,
match func(parsedName, constraint any) (match bool, err error), match func(parsedName T1, constraint T2) (match bool, err error),
permitted, excluded any) error { permitted, excluded []T2) error {
excludedValue := reflect.ValueOf(excluded) *count += len(excluded)
*count += excludedValue.Len()
if *count > maxConstraintComparisons { if *count > maxConstraintComparisons {
return CertificateInvalidError{c, TooManyConstraints, ""} return CertificateInvalidError{c, TooManyConstraints, ""}
} }
for i := 0; i < excludedValue.Len(); i++ { for _, constraint := range excluded {
constraint := excludedValue.Index(i).Interface()
match, err := match(parsedName, constraint) match, err := match(parsedName, constraint)
if err != nil { if err != nil {
return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()} return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
} }
if match { if match {
return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", nameType, name, constraint)} return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", nameType, name, any(constraint))}
} }
} }
permittedValue := reflect.ValueOf(permitted) *count += len(permitted)
*count += permittedValue.Len()
if *count > maxConstraintComparisons { if *count > maxConstraintComparisons {
return CertificateInvalidError{c, TooManyConstraints, ""} return CertificateInvalidError{c, TooManyConstraints, ""}
} }
ok := true ok := true
for i := 0; i < permittedValue.Len(); i++ { for _, constraint := range permitted {
constraint := permittedValue.Index(i).Interface()
var err error var err error
if ok, err = match(parsedName, constraint); err != nil { if ok, err = match(parsedName, constraint); err != nil {
return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()} return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
@ -654,10 +647,8 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox) return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox)
} }
if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox, if err := checkNameConstraints(c, &comparisonCount, maxConstraintComparisons, "email address", name, mailbox,
func(parsedName, constraint any) (bool, error) { matchEmailConstraint, c.PermittedEmailAddresses, c.ExcludedEmailAddresses); err != nil {
return matchEmailConstraint(parsedName.(rfc2821Mailbox), constraint.(string))
}, c.PermittedEmailAddresses, c.ExcludedEmailAddresses); err != nil {
return err return err
} }
@ -667,10 +658,8 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
return fmt.Errorf("x509: cannot parse dnsName %q", name) return fmt.Errorf("x509: cannot parse dnsName %q", name)
} }
if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name, if err := checkNameConstraints(c, &comparisonCount, maxConstraintComparisons, "DNS name", name, name,
func(parsedName, constraint any) (bool, error) { matchDomainConstraint, c.PermittedDNSDomains, c.ExcludedDNSDomains); err != nil {
return matchDomainConstraint(parsedName.(string), constraint.(string))
}, c.PermittedDNSDomains, c.ExcludedDNSDomains); err != nil {
return err return err
} }
@ -681,10 +670,8 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
return fmt.Errorf("x509: internal error: URI SAN %q failed to parse", name) return fmt.Errorf("x509: internal error: URI SAN %q failed to parse", name)
} }
if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "URI", name, uri, if err := checkNameConstraints(c, &comparisonCount, maxConstraintComparisons, "URI", name, uri,
func(parsedName, constraint any) (bool, error) { matchURIConstraint, c.PermittedURIDomains, c.ExcludedURIDomains); err != nil {
return matchURIConstraint(parsedName.(*url.URL), constraint.(string))
}, c.PermittedURIDomains, c.ExcludedURIDomains); err != nil {
return err return err
} }
@ -694,10 +681,8 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
return fmt.Errorf("x509: internal error: IP SAN %x failed to parse", data) return fmt.Errorf("x509: internal error: IP SAN %x failed to parse", data)
} }
if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "IP address", ip.String(), ip, if err := checkNameConstraints(c, &comparisonCount, maxConstraintComparisons, "IP address", ip.String(), ip,
func(parsedName, constraint any) (bool, error) { matchIPConstraint, c.PermittedIPRanges, c.ExcludedIPRanges); err != nil {
return matchIPConstraint(parsedName.(net.IP), constraint.(*net.IPNet))
}, c.PermittedIPRanges, c.ExcludedIPRanges); err != nil {
return err return err
} }