github.com/v2fly/v2ray-core/v4@v4.45.2/transport/internet/tls/config_other.go (about)

     1  //go:build !windows && !confonly
     2  // +build !windows,!confonly
     3  
     4  package tls
     5  
     6  import (
     7  	"crypto/x509"
     8  	"sync"
     9  )
    10  
    11  type rootCertsCache struct {
    12  	sync.Mutex
    13  	pool *x509.CertPool
    14  }
    15  
    16  func (c *rootCertsCache) load() (*x509.CertPool, error) {
    17  	c.Lock()
    18  	defer c.Unlock()
    19  
    20  	if c.pool != nil {
    21  		return c.pool, nil
    22  	}
    23  
    24  	pool, err := x509.SystemCertPool()
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	c.pool = pool
    29  	return pool, nil
    30  }
    31  
    32  var rootCerts rootCertsCache
    33  
    34  func (c *Config) getCertPool() (*x509.CertPool, error) {
    35  	if c.DisableSystemRoot {
    36  		return c.loadSelfCertPool()
    37  	}
    38  
    39  	if len(c.Certificate) == 0 {
    40  		return rootCerts.load()
    41  	}
    42  
    43  	pool, err := x509.SystemCertPool()
    44  	if err != nil {
    45  		return nil, newError("system root").AtWarning().Base(err)
    46  	}
    47  	for _, cert := range c.Certificate {
    48  		/* Do not treat client certificate authority as a peer certificate authority.
    49  		   This is designed to prevent a client certificate with a permissive key usage from being used to attacker server.
    50  		   In next release, the certificate usage will be enforced strictly.
    51  		   Only a certificate with AUTHORITY_VERIFY usage will be accepted.
    52  		*/
    53  		if cert.Usage == Certificate_AUTHORITY_VERIFY_CLIENT {
    54  			continue
    55  		}
    56  
    57  		if !pool.AppendCertsFromPEM(cert.Certificate) {
    58  			return nil, newError("append cert to root").AtWarning().Base(err)
    59  		}
    60  	}
    61  	return pool, err
    62  }