package x509
import (
)
type InvalidReason int
const (
NotAuthorizedToSign InvalidReason = iota
Expired
CANotAuthorizedForThisName
TooManyIntermediates
IncompatibleUsage
NameMismatch
NameConstraintsWithoutSANs
UnconstrainedName
TooManyConstraints
CANotAuthorizedForExtKeyUsage
NoValidChains
)
type CertificateInvalidError struct {
Cert *Certificate
Reason InvalidReason
Detail string
}
func ( CertificateInvalidError) () string {
switch .Reason {
case NotAuthorizedToSign:
return "x509: certificate is not authorized to sign other certificates"
case Expired:
return "x509: certificate has expired or is not yet valid: " + .Detail
case CANotAuthorizedForThisName:
return "x509: a root or intermediate certificate is not authorized to sign for this name: " + .Detail
case CANotAuthorizedForExtKeyUsage:
return "x509: a root or intermediate certificate is not authorized for an extended key usage: " + .Detail
case TooManyIntermediates:
return "x509: too many intermediates for path length constraint"
case IncompatibleUsage:
return "x509: certificate specifies an incompatible key usage"
case NameMismatch:
return "x509: issuer name does not match subject from issuing certificate"
case NameConstraintsWithoutSANs:
return "x509: issuer has name constraints but leaf doesn't have a SAN extension"
case UnconstrainedName:
return "x509: issuer has name constraints but leaf contains unknown or unconstrained name: " + .Detail
case NoValidChains:
:= "x509: no valid chains built"
if .Detail != "" {
= fmt.Sprintf("%s: %s", , .Detail)
}
return
}
return "x509: unknown error"
}
type HostnameError struct {
Certificate *Certificate
Host string
}
func ( HostnameError) () string {
:= .Certificate
if !.hasSANExtension() && matchHostnames(.Subject.CommonName, .Host) {
return "x509: certificate relies on legacy Common Name field, use SANs instead"
}
var string
if := net.ParseIP(.Host); != nil {
if len(.IPAddresses) == 0 {
return "x509: cannot validate certificate for " + .Host + " because it doesn't contain any IP SANs"
}
for , := range .IPAddresses {
if len() > 0 {
+= ", "
}
+= .String()
}
} else {
= strings.Join(.DNSNames, ", ")
}
if len() == 0 {
return "x509: certificate is not valid for any names, but wanted to match " + .Host
}
return "x509: certificate is valid for " + + ", not " + .Host
}
type UnknownAuthorityError struct {
Cert *Certificate
hintErr error
hintCert *Certificate
}
func ( UnknownAuthorityError) () string {
:= "x509: certificate signed by unknown authority"
if .hintErr != nil {
:= .hintCert.Subject.CommonName
if len() == 0 {
if len(.hintCert.Subject.Organization) > 0 {
= .hintCert.Subject.Organization[0]
} else {
= "serial:" + .hintCert.SerialNumber.String()
}
}
+= fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", .hintErr, )
}
return
}
type SystemRootsError struct {
Err error
}
func ( SystemRootsError) () string {
:= "x509: failed to load system roots and no roots provided"
if .Err != nil {
return + "; " + .Err.Error()
}
return
}
func ( SystemRootsError) () error { return .Err }
var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate")
type VerifyOptions struct {
DNSName string
Intermediates *CertPool
Roots *CertPool
CurrentTime time.Time
KeyUsages []ExtKeyUsage
MaxConstraintComparisions int
CertificatePolicies []OID
inhibitPolicyMapping bool
requireExplicitPolicy bool
inhibitAnyPolicy bool
}
const (
leafCertificate = iota
intermediateCertificate
rootCertificate
)
type rfc2821Mailbox struct {
local, domain string
}
func ( string) ( rfc2821Mailbox, bool) {
if len() == 0 {
return , false
}
:= make([]byte, 0, len()/2)
if [0] == '"' {
= [1:]
:
for {
if len() == 0 {
return , false
}
:= [0]
= [1:]
switch {
case == '"':
break
case == '\\':
if len() == 0 {
return , false
}
if [0] == 11 ||
[0] == 12 ||
(1 <= [0] && [0] <= 9) ||
(14 <= [0] && [0] <= 127) {
= append(, [0])
= [1:]
} else {
return , false
}
case == 11 ||
== 12 ||
== 32 ||
== 33 ||
== 127 ||
(1 <= && <= 8) ||
(14 <= && <= 31) ||
(35 <= && <= 91) ||
(93 <= && <= 126):
= append(, )
default:
return , false
}
}
} else {
:
for len() > 0 {
:= [0]
switch {
case == '\\':
= [1:]
if len() == 0 {
return , false
}
fallthrough
case ('0' <= && <= '9') ||
('a' <= && <= 'z') ||
('A' <= && <= 'Z') ||
== '!' || == '#' || == '$' || == '%' ||
== '&' || == '\'' || == '*' || == '+' ||
== '-' || == '/' || == '=' || == '?' ||
== '^' || == '_' || == '`' || == '{' ||
== '|' || == '}' || == '~' || == '.':
= append(, [0])
= [1:]
default:
break
}
}
if len() == 0 {
return , false
}
:= []byte{'.', '.'}
if [0] == '.' ||
[len()-1] == '.' ||
bytes.Contains(, ) {
return , false
}
}
if len() == 0 || [0] != '@' {
return , false
}
= [1:]
if , := domainToReverseLabels(); ! {
return , false
}
.local = string()
.domain =
return , true
}
func ( string) ( []string, bool) {
for len() > 0 {
if := strings.LastIndexByte(, '.'); == -1 {
= append(, )
= ""
} else {
= append(, [+1:])
= [:]
if == 0 {
= append(, "")
}
}
}
if len() > 0 && len([0]) == 0 {
return nil, false
}
for , := range {
if len() == 0 {
return nil, false
}
for , := range {
if < 33 || > 126 {
return nil, false
}
}
}
return , true
}
func ( rfc2821Mailbox, string) (bool, error) {
if strings.Contains(, "@") {
, := parseRFC2821Mailbox()
if ! {
return false, fmt.Errorf("x509: internal error: cannot parse constraint %q", )
}
return .local == .local && strings.EqualFold(.domain, .domain), nil
}
return matchDomainConstraint(.domain, )
}
func ( *url.URL, string) (bool, error) {
:= .Host
if len() == 0 {
return false, fmt.Errorf("URI with empty host (%q) cannot be matched against constraints", .String())
}
if strings.Contains(, ":") && !strings.HasSuffix(, "]") {
var error
, _, = net.SplitHostPort(.Host)
if != nil {
return false,
}
}
if , := netip.ParseAddr(); == nil || (strings.HasPrefix(, "[") && strings.HasSuffix(, "]")) {
return false, fmt.Errorf("URI with IP (%q) cannot be matched against constraints", .String())
}
return matchDomainConstraint(, )
}
func ( net.IP, *net.IPNet) (bool, error) {
if len() != len(.IP) {
return false, nil
}
for := range {
if := .Mask[]; []& != .IP[]& {
return false, nil
}
}
return true, nil
}
func (, string) (bool, error) {
if len() == 0 {
return true, nil
}
, := domainToReverseLabels()
if ! {
return false, fmt.Errorf("x509: internal error: cannot parse domain %q", )
}
:= false
if [0] == '.' {
= true
= [1:]
}
, := domainToReverseLabels()
if ! {
return false, fmt.Errorf("x509: internal error: cannot parse domain %q", )
}
if len() < len() ||
( && len() == len()) {
return false, nil
}
for , := range {
if !strings.EqualFold(, []) {
return false, nil
}
}
return true, nil
}
func ( *Certificate) ( *int,
int,
string,
string,
any,
func(, any) ( bool, error),
, any) error {
:= reflect.ValueOf()
* += .Len()
if * > {
return CertificateInvalidError{, TooManyConstraints, ""}
}
for := 0; < .Len(); ++ {
:= .Index().Interface()
, := (, )
if != nil {
return CertificateInvalidError{, CANotAuthorizedForThisName, .Error()}
}
if {
return CertificateInvalidError{, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", , , )}
}
}
:= reflect.ValueOf()
* += .Len()
if * > {
return CertificateInvalidError{, TooManyConstraints, ""}
}
:= true
for := 0; < .Len(); ++ {
:= .Index().Interface()
var error
if , = (, ); != nil {
return CertificateInvalidError{, CANotAuthorizedForThisName, .Error()}
}
if {
break
}
}
if ! {
return CertificateInvalidError{, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is not permitted by any constraint", , )}
}
return nil
}
func ( *Certificate) ( int, []*Certificate, *VerifyOptions) error {
if len(.UnhandledCriticalExtensions) > 0 {
return UnhandledCriticalExtension{}
}
if len() > 0 {
:= [len()-1]
if !bytes.Equal(.RawIssuer, .RawSubject) {
return CertificateInvalidError{, NameMismatch, ""}
}
}
:= .CurrentTime
if .IsZero() {
= time.Now()
}
if .Before(.NotBefore) {
return CertificateInvalidError{
Cert: ,
Reason: Expired,
Detail: fmt.Sprintf("current time %s is before %s", .Format(time.RFC3339), .NotBefore.Format(time.RFC3339)),
}
} else if .After(.NotAfter) {
return CertificateInvalidError{
Cert: ,
Reason: Expired,
Detail: fmt.Sprintf("current time %s is after %s", .Format(time.RFC3339), .NotAfter.Format(time.RFC3339)),
}
}
:= .MaxConstraintComparisions
if == 0 {
= 250000
}
:= 0
if == intermediateCertificate || == rootCertificate {
if len() == 0 {
return errors.New("x509: internal error: empty chain when appending CA cert")
}
}
if ( == intermediateCertificate || == rootCertificate) &&
.hasNameConstraints() {
:= []*Certificate{}
for , := range {
if .hasSANExtension() {
= append(, )
}
}
for , := range {
:= forEachSAN(.getSANExtension(), func( int, []byte) error {
switch {
case nameTypeEmail:
:= string()
, := parseRFC2821Mailbox()
if ! {
return fmt.Errorf("x509: cannot parse rfc822Name %q", )
}
if := .checkNameConstraints(&, , "email address", , ,
func(, any) (bool, error) {
return matchEmailConstraint(.(rfc2821Mailbox), .(string))
}, .PermittedEmailAddresses, .ExcludedEmailAddresses); != nil {
return
}
case nameTypeDNS:
:= string()
if , := domainToReverseLabels(); ! {
return fmt.Errorf("x509: cannot parse dnsName %q", )
}
if := .checkNameConstraints(&, , "DNS name", , ,
func(, any) (bool, error) {
return matchDomainConstraint(.(string), .(string))
}, .PermittedDNSDomains, .ExcludedDNSDomains); != nil {
return
}
case nameTypeURI:
:= string()
, := url.Parse()
if != nil {
return fmt.Errorf("x509: internal error: URI SAN %q failed to parse", )
}
if := .checkNameConstraints(&, , "URI", , ,
func(, any) (bool, error) {
return matchURIConstraint(.(*url.URL), .(string))
}, .PermittedURIDomains, .ExcludedURIDomains); != nil {
return
}
case nameTypeIP:
:= net.IP()
if := len(); != net.IPv4len && != net.IPv6len {
return fmt.Errorf("x509: internal error: IP SAN %x failed to parse", )
}
if := .checkNameConstraints(&, , "IP address", .String(), ,
func(, any) (bool, error) {
return matchIPConstraint(.(net.IP), .(*net.IPNet))
}, .PermittedIPRanges, .ExcludedIPRanges); != nil {
return
}
default:
}
return nil
})
if != nil {
return
}
}
}
if == intermediateCertificate && (!.BasicConstraintsValid || !.IsCA) {
return CertificateInvalidError{, NotAuthorizedToSign, ""}
}
if .BasicConstraintsValid && .MaxPathLen >= 0 {
:= len() - 1
if > .MaxPathLen {
return CertificateInvalidError{, TooManyIntermediates, ""}
}
}
return nil
}
func ( *Certificate) ( VerifyOptions) ( [][]*Certificate, error) {
if len(.Raw) == 0 {
return nil, errNotParsed
}
for := 0; < .Intermediates.len(); ++ {
, , := .Intermediates.cert()
if != nil {
return nil, fmt.Errorf("crypto/x509: error fetching intermediate: %w", )
}
if len(.Raw) == 0 {
return nil, errNotParsed
}
}
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
:= systemRootsPool()
if .Roots == nil && ( == nil || .systemPool) {
return .systemVerify(&)
}
if .Roots != nil && .Roots.systemPool {
, := .systemVerify(&)
if == nil || .Roots.len() == 0 {
return ,
}
}
}
if .Roots == nil {
.Roots = systemRootsPool()
if .Roots == nil {
return nil, SystemRootsError{systemRootsErr}
}
}
= .isValid(leafCertificate, nil, &)
if != nil {
return
}
if len(.DNSName) > 0 {
= .VerifyHostname(.DNSName)
if != nil {
return
}
}
var [][]*Certificate
if .Roots.contains() {
= [][]*Certificate{{}}
} else {
, = .buildChains([]*Certificate{}, nil, &)
if != nil {
return nil,
}
}
= make([][]*Certificate, 0, len())
var int
for , := range {
if !policiesValid(, ) {
++
continue
}
= append(, )
}
if len() == 0 {
return nil, CertificateInvalidError{, NoValidChains, "all candidate chains have invalid policies"}
}
for , := range .KeyUsages {
if == ExtKeyUsageAny {
return , nil
}
}
if len(.KeyUsages) == 0 {
.KeyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
}
=
= [:0]
var int
for , := range {
if !checkChainForKeyUsage(, .KeyUsages) {
++
continue
}
= append(, )
}
if len() == 0 {
var []string
if > 0 {
if == 0 {
return nil, CertificateInvalidError{, IncompatibleUsage, ""}
}
= append(, fmt.Sprintf("%d chains with incompatible key usage", ))
}
if > 0 {
= append(, fmt.Sprintf("%d chains with invalid policies", ))
}
= CertificateInvalidError{, NoValidChains, strings.Join(, ", ")}
return nil,
}
return , nil
}
func ( []*Certificate, *Certificate) []*Certificate {
:= make([]*Certificate, len()+1)
copy(, )
[len()] =
return
}
func ( *Certificate, []*Certificate) bool {
type interface {
(crypto.PublicKey) bool
}
var *pkix.Extension
for , := range .Extensions {
if .Id.Equal(oidExtensionSubjectAltName) {
= &
break
}
}
for , := range {
if !bytes.Equal(.RawSubject, .RawSubject) {
continue
}
if !.PublicKey.().(.PublicKey) {
continue
}
var *pkix.Extension
for , := range .Extensions {
if .Id.Equal(oidExtensionSubjectAltName) {
= &
break
}
}
if == nil && == nil {
return true
} else if == nil || == nil {
return false
}
if bytes.Equal(.Value, .Value) {
return true
}
}
return false
}
const maxChainSignatureChecks = 100
func ( *Certificate) ( []*Certificate, *int, *VerifyOptions) ( [][]*Certificate, error) {
var (
error
*Certificate
)
:= func( int, potentialParent) {
if .cert.PublicKey == nil || alreadyInChain(.cert, ) {
return
}
if == nil {
= new(int)
}
*++
if * > maxChainSignatureChecks {
= errors.New("x509: signature check attempts limit reached while verifying certificate chain")
return
}
if := .CheckSignatureFrom(.cert); != nil {
if == nil {
=
= .cert
}
return
}
= .cert.isValid(, , )
if != nil {
if == nil {
=
= .cert
}
return
}
if .constraint != nil {
if := .constraint(); != nil {
if == nil {
=
= .cert
}
return
}
}
switch {
case rootCertificate:
= append(, appendToFreshChain(, .cert))
case intermediateCertificate:
var [][]*Certificate
, = .cert.(appendToFreshChain(, .cert), , )
= append(, ...)
}
}
for , := range .Roots.findPotentialParents() {
(rootCertificate, )
}
for , := range .Intermediates.findPotentialParents() {
(intermediateCertificate, )
}
if len() > 0 {
= nil
}
if len() == 0 && == nil {
= UnknownAuthorityError{, , }
}
return
}
func ( string) bool { return validHostname(, true) }
func ( string) bool { return validHostname(, false) }
func ( string, bool) bool {
if ! {
= strings.TrimSuffix(, ".")
}
if len() == 0 {
return false
}
if == "*" {
return false
}
for , := range strings.Split(, ".") {
if == "" {
return false
}
if && == 0 && == "*" {
continue
}
for , := range {
if 'a' <= && <= 'z' {
continue
}
if '0' <= && <= '9' {
continue
}
if 'A' <= && <= 'Z' {
continue
}
if == '-' && != 0 {
continue
}
if == '_' {
continue
}
return false
}
}
return true
}
func (, string) bool {
if == "" || == "." || == "" || == "." {
return false
}
return toLowerCaseASCII() == toLowerCaseASCII()
}
func (, string) bool {
= toLowerCaseASCII()
= toLowerCaseASCII(strings.TrimSuffix(, "."))
if len() == 0 || len() == 0 {
return false
}
:= strings.Split(, ".")
:= strings.Split(, ".")
if len() != len() {
return false
}
for , := range {
if == 0 && == "*" {
continue
}
if != [] {
return false
}
}
return true
}
func ( string) string {
:= true
for , := range {
if == utf8.RuneError {
= false
break
}
if 'A' <= && <= 'Z' {
= false
break
}
}
if {
return
}
:= []byte()
for , := range {
if 'A' <= && <= 'Z' {
[] += 'a' - 'A'
}
}
return string()
}
func ( *Certificate) ( string) error {
:=
if len() >= 3 && [0] == '[' && [len()-1] == ']' {
= [1 : len()-1]
}
if := net.ParseIP(); != nil {
for , := range .IPAddresses {
if .Equal() {
return nil
}
}
return HostnameError{, }
}
:= toLowerCaseASCII()
:= validHostnameInput()
for , := range .DNSNames {
if && validHostnamePattern() {
if matchHostnames(, ) {
return nil
}
} else {
if matchExactly(, ) {
return nil
}
}
}
return HostnameError{, }
}
func ( []*Certificate, []ExtKeyUsage) bool {
:= make([]ExtKeyUsage, len())
copy(, )
if len() == 0 {
return false
}
:= len()
:
for := len() - 1; >= 0; -- {
:= []
if len(.ExtKeyUsage) == 0 && len(.UnknownExtKeyUsage) == 0 {
continue
}
for , := range .ExtKeyUsage {
if == ExtKeyUsageAny {
continue
}
}
const ExtKeyUsage = -1
:
for , := range {
if == {
continue
}
for , := range .ExtKeyUsage {
if == {
continue
}
}
[] =
--
if == 0 {
return false
}
}
}
return true
}
func ( []uint64) OID {
, := OIDFromInts()
if != nil {
panic(fmt.Sprintf("OIDFromInts(%v) unexpected error: %v", , ))
}
return
}
type policyGraphNode struct {
validPolicy OID
expectedPolicySet []OID
parents map[*policyGraphNode]bool
children map[*policyGraphNode]bool
}
func ( OID, []*policyGraphNode) *policyGraphNode {
:= &policyGraphNode{
validPolicy: ,
expectedPolicySet: []OID{},
children: map[*policyGraphNode]bool{},
parents: map[*policyGraphNode]bool{},
}
for , := range {
.children[] = true
.parents[] = true
}
return
}
type policyGraph struct {
strata []map[string]*policyGraphNode
parentIndex map[string][]*policyGraphNode
depth int
}
var anyPolicyOID = mustNewOIDFromInts([]uint64{2, 5, 29, 32, 0})
func () *policyGraph {
:= policyGraphNode{
validPolicy: anyPolicyOID,
expectedPolicySet: []OID{anyPolicyOID},
children: map[*policyGraphNode]bool{},
parents: map[*policyGraphNode]bool{},
}
return &policyGraph{
depth: 0,
strata: []map[string]*policyGraphNode{{string(anyPolicyOID.der): &}},
}
}
func ( *policyGraph) ( *policyGraphNode) {
.strata[.depth][string(.validPolicy.der)] =
}
func ( *policyGraph) ( OID) []*policyGraphNode {
if .depth == 0 {
return nil
}
return .parentIndex[string(.der)]
}
func ( *policyGraph) () *policyGraphNode {
if .depth == 0 {
return nil
}
return .strata[.depth-1][string(anyPolicyOID.der)]
}
func ( *policyGraph) () iter.Seq[*policyGraphNode] {
if .depth == 0 {
return nil
}
return maps.Values(.strata[.depth-1])
}
func ( *policyGraph) () map[string]*policyGraphNode {
return .strata[.depth]
}
func ( *policyGraph) ( OID) *policyGraphNode {
return .strata[.depth][string(.der)]
}
func ( *policyGraph) ( OID) {
:= .strata[.depth][string(.der)]
if == nil {
return
}
for := range .parents {
delete(.children, )
}
for := range .children {
delete(.parents, )
}
delete(.strata[.depth], string(.der))
}
func ( *policyGraph) () []*policyGraphNode {
var []*policyGraphNode
for := .depth; >= 0; -- {
for , := range .strata[] {
if .validPolicy.Equal(anyPolicyOID) {
continue
}
if len(.parents) == 1 {
for := range .parents {
if .validPolicy.Equal(anyPolicyOID) {
= append(, )
}
}
}
}
}
return
}
func ( *policyGraph) () {
for := .depth - 1; > 0; -- {
for , := range .strata[] {
if len(.children) == 0 {
for := range .parents {
delete(.children, )
}
delete(.strata[], string(.validPolicy.der))
}
}
}
}
func ( *policyGraph) () {
.parentIndex = map[string][]*policyGraphNode{}
for , := range .strata[.depth] {
for , := range .expectedPolicySet {
.parentIndex[string(.der)] = append(.parentIndex[string(.der)], )
}
}
.depth++
.strata = append(.strata, map[string]*policyGraphNode{})
}
func ( []*Certificate, VerifyOptions) bool {
if len() == 1 {
return true
}
:= len() - 1
:= newPolicyGraph()
var , , int
if !.inhibitAnyPolicy {
= + 1
}
if !.requireExplicitPolicy {
= + 1
}
if !.inhibitPolicyMapping {
= + 1
}
:= map[string]bool{}
for , := range .CertificatePolicies {
[string(.der)] = true
}
if len() == 0 {
[string(anyPolicyOID.der)] = true
}
for := - 1; >= 0; -- {
:= []
:= bytes.Equal(.RawIssuer, .RawSubject)
if len(.Policies) == 0 {
= nil
}
if == 0 && == nil {
return false
}
if != nil {
.incrDepth()
:= map[string]bool{}
for , := range .Policies {
[string(.der)] = true
if .Equal(anyPolicyOID) {
continue
}
:= .parentsWithExpected()
if len() == 0 {
if := .parentWithAnyPolicy(); != nil {
= []*policyGraphNode{}
}
}
if len() > 0 {
.insert(newPolicyGraphNode(, ))
}
}
if [string(anyPolicyOID.der)] && ( > 0 || (- < && )) {
:= map[string][]*policyGraphNode{}
:= .leaves()
for := range .parents() {
for , := range .expectedPolicySet {
if [string(.der)] == nil {
[string(.der)] = append([string(.der)], )
}
}
}
for , := range {
.insert(newPolicyGraphNode(OID{der: []byte()}, ))
}
}
.prune()
if != 0 {
if len(.PolicyMappings) > 0 {
:= map[string][]OID{}
for , := range .PolicyMappings {
if > 0 {
if .IssuerDomainPolicy.Equal(anyPolicyOID) || .SubjectDomainPolicy.Equal(anyPolicyOID) {
return false
}
[string(.IssuerDomainPolicy.der)] = append([string(.IssuerDomainPolicy.der)], .SubjectDomainPolicy)
} else {
.deleteLeaf(.IssuerDomainPolicy)
.prune()
}
}
for , := range {
if := .leafWithPolicy(OID{der: []byte()}); != nil {
.expectedPolicySet =
} else if := .leafWithPolicy(anyPolicyOID); != nil {
:= newPolicyGraphNode(OID{der: []byte()}, []*policyGraphNode{})
.expectedPolicySet =
.insert()
}
}
}
}
}
if != 0 {
if ! {
if > 0 {
--
}
if > 0 {
--
}
if > 0 {
--
}
}
if (.RequireExplicitPolicy > 0 || .RequireExplicitPolicyZero) && .RequireExplicitPolicy < {
= .RequireExplicitPolicy
}
if (.InhibitPolicyMapping > 0 || .InhibitPolicyMappingZero) && .InhibitPolicyMapping < {
= .InhibitPolicyMapping
}
if (.InhibitAnyPolicy > 0 || .InhibitAnyPolicyZero) && .InhibitAnyPolicy < {
= .InhibitAnyPolicy
}
}
}
if > 0 {
--
}
if [0].RequireExplicitPolicyZero {
= 0
}
var []*policyGraphNode
if != nil {
= .validPolicyNodes()
if := .leafWithPolicy(anyPolicyOID); != nil {
= append(, )
}
}
:= map[string]bool{}
for , := range {
[string(.validPolicy.der)] = true
}
:= maps.Clone()
if len() != 1 || ![string(anyPolicyOID.der)] {
for := range {
if ![] {
delete(, )
}
}
if [string(anyPolicyOID.der)] {
for := range {
[] = true
}
}
}
if == 0 && len() == 0 {
return false
}
return true
}