Copyright 2011 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.

package x509

import (
	
	
	
	
	
	
)

type sum224 [sha256.Size224]byte
CertPool is a set of certificates.
type CertPool struct {
	byName map[string][]int // cert.RawSubject => index into lazyCerts
lazyCerts contains funcs that return a certificate, lazily parsing/decompressing it as needed.
haveSum maps from sum224(cert.Raw) to true. It's used only for AddCert duplicate detection, to avoid CertPool.contains calls in the AddCert path (because the contains method can call getCert and otherwise negate savings from lazy getCert funcs).
lazyCert is minimal metadata about a Cert and a func to retrieve it in its normal expanded *Certificate form.
rawSubject is the Certificate.RawSubject value. It's the same as the CertPool.byName key, but in []byte form to make CertPool.Subjects (as used by crypto/tls) do fewer allocations.
getCert returns the certificate. It is not meant to do network operations or anything else where a failure is likely; the func is meant to lazily parse/decompress data that is already known to be good. The error in the signature primarily is meant for use in the case where a cert file existed on local disk when the program started up is deleted later before it's read.
	getCert func() (*Certificate, error)
}
NewCertPool returns a new, empty CertPool.
func () *CertPool {
	return &CertPool{
		byName:  make(map[string][]int),
		haveSum: make(map[sum224]bool),
	}
}
len returns the number of certs in the set. A nil set is a valid empty set.
func ( *CertPool) () int {
	if  == nil {
		return 0
	}
	return len(.lazyCerts)
}
cert returns cert index n in s.
func ( *CertPool) ( int) (*Certificate, error) {
	return .lazyCerts[].getCert()
}

func ( *CertPool) () *CertPool {
	 := &CertPool{
		byName:    make(map[string][]int, len(.byName)),
		lazyCerts: make([]lazyCert, len(.lazyCerts)),
		haveSum:   make(map[sum224]bool, len(.haveSum)),
	}
	for ,  := range .byName {
		 := make([]int, len())
		copy(, )
		.byName[] = 
	}
	for  := range .haveSum {
		.haveSum[] = true
	}
	copy(.lazyCerts, .lazyCerts)
	return 
}
SystemCertPool returns a copy of the system cert pool. On Unix systems other than macOS the environment variables SSL_CERT_FILE and SSL_CERT_DIR can be used to override the system default locations for the SSL certificate file and SSL certificate files directory, respectively. The latter can be a colon-separated list. Any mutations to the returned pool are not written to disk and do not affect any other pool returned by SystemCertPool. New changes in the system cert pool might not be reflected in subsequent calls.
Issue 16736, 18609:
		return nil, errors.New("crypto/x509: system root pool is not available on Windows")
	}

	if  := systemRootsPool();  != nil {
		return .copy(), nil
	}

	return loadSystemRoots()
}
findPotentialParents returns the indexes of certificates in s which might have signed cert.
func ( *CertPool) ( *Certificate) []*Certificate {
	if  == nil {
		return nil
	}
consider all candidates where cert.Issuer matches cert.Subject. when picking possible candidates the list is built in the order of match plausibility as to save cycles in buildChains: AKID and SKID match AKID present, SKID missing / AKID missing, SKID present AKID and SKID don't match
	var , ,  []*Certificate
	for ,  := range .byName[string(.RawIssuer)] {
		,  := .cert()
		if  != nil {
			continue
		}
		 := bytes.Equal(.SubjectKeyId, .AuthorityKeyId)
		switch {
		case :
			 = append(, )
		case (len(.SubjectKeyId) == 0 && len(.AuthorityKeyId) > 0) ||
			(len(.SubjectKeyId) > 0 && len(.AuthorityKeyId) == 0):
			 = append(, )
		default:
			 = append(, )
		}
	}

	 := len() + len() + len()
	if  == 0 {
		return nil
	}
	 := make([]*Certificate, 0, )
	 = append(, ...)
	 = append(, ...)
	 = append(, ...)
	return 
}

func ( *CertPool) ( *Certificate) bool {
	if  == nil {
		return false
	}
	return .haveSum[sha256.Sum224(.Raw)]
}
AddCert adds a certificate to a pool.
func ( *CertPool) ( *Certificate) {
	if  == nil {
		panic("adding nil Certificate to CertPool")
	}
	.addCertFunc(sha256.Sum224(.Raw), string(.RawSubject), func() (*Certificate, error) {
		return , nil
	})
}
addCertFunc adds metadata about a certificate to a pool, along with a func to fetch that certificate later when needed. The rawSubject is Certificate.RawSubject and must be non-empty. The getCert func may be called 0 or more times.
func ( *CertPool) ( sum224,  string,  func() (*Certificate, error)) {
	if  == nil {
		panic("getCert can't be nil")
	}
Check that the certificate isn't being added twice.
	if .haveSum[] {
		return
	}

	.haveSum[] = true
	.lazyCerts = append(.lazyCerts, lazyCert{
		rawSubject: []byte(),
		getCert:    ,
	})
	.byName[] = append(.byName[], len(.lazyCerts)-1)
}
AppendCertsFromPEM attempts to parse a series of PEM encoded certificates. It appends any certificates found to s and reports whether any certificates were successfully parsed. On many Linux systems, /etc/ssl/cert.pem will contain the system wide set of root CAs in a format suitable for this function.
func ( *CertPool) ( []byte) ( bool) {
	for len() > 0 {
		var  *pem.Block
		,  = pem.Decode()
		if  == nil {
			break
		}
		if .Type != "CERTIFICATE" || len(.Headers) != 0 {
			continue
		}

		 := .Bytes
		,  := ParseCertificate()
		if  != nil {
			continue
		}
		var  struct {
			sync.Once
			 *Certificate
		}
		.addCertFunc(sha256.Sum224(.Raw), string(.RawSubject), func() (*Certificate, error) {
This can't fail, as the same bytes already parsed above.
				., _ = ParseCertificate()
				 = nil
			})
			return ., nil
		})
		 = true
	}

	return 
}
Subjects returns a list of the DER-encoded subjects of all of the certificates in the pool.
func ( *CertPool) () [][]byte {
	 := make([][]byte, .len())
	for ,  := range .lazyCerts {
		[] = .rawSubject
	}
	return