|
|
|
@ -2,20 +2,62 @@
|
|
|
|
|
|
|
|
|
|
package tls |
|
|
|
|
|
|
|
|
|
import "crypto/x509" |
|
|
|
|
import ( |
|
|
|
|
"crypto/x509" |
|
|
|
|
"sync" |
|
|
|
|
|
|
|
|
|
func (c *Config) getCertPool() *x509.CertPool { |
|
|
|
|
pool, err := x509.SystemCertPool() |
|
|
|
|
if err != nil { |
|
|
|
|
newError("failed to get system cert pool.").Base(err).WriteToLog() |
|
|
|
|
"v2ray.com/core/common/compare" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
type certPoolCache struct { |
|
|
|
|
sync.Mutex |
|
|
|
|
once sync.Once |
|
|
|
|
pool *x509.CertPool |
|
|
|
|
extraCerts [][]byte |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (c *certPoolCache) hasCert(cert []byte) bool { |
|
|
|
|
for _, xCert := range c.extraCerts { |
|
|
|
|
if compare.BytesEqual(xCert, cert) { |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (c *certPoolCache) get(extraCerts []*Certificate) *x509.CertPool { |
|
|
|
|
c.once.Do(func() { |
|
|
|
|
pool, err := x509.SystemCertPool() |
|
|
|
|
if err != nil { |
|
|
|
|
newError("failed to get system cert pool.").Base(err).WriteToLog() |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
c.pool = pool |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
if c.pool == nil { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
if pool != nil { |
|
|
|
|
for _, cert := range c.Certificate { |
|
|
|
|
if cert.Usage == Certificate_AUTHORITY_VERIFY { |
|
|
|
|
pool.AppendCertsFromPEM(cert.Certificate) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if len(extraCerts) == 0 { |
|
|
|
|
return c.pool |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
c.Lock() |
|
|
|
|
defer c.Unlock() |
|
|
|
|
|
|
|
|
|
for _, cert := range extraCerts { |
|
|
|
|
if !c.hasCert(cert.Certificate) { |
|
|
|
|
c.pool.AppendCertsFromPEM(cert.Certificate) |
|
|
|
|
c.extraCerts = append(c.extraCerts, cert.Certificate) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return pool |
|
|
|
|
|
|
|
|
|
return c.pool |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var combineCertPool certPoolCache |
|
|
|
|
|
|
|
|
|
func (c *Config) getCertPool() *x509.CertPool { |
|
|
|
|
return combineCertPool.get(c.Certificate) |
|
|
|
|
} |
|
|
|
|