config_other.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // +build !windows
  2. package tls
  3. import (
  4. "crypto/x509"
  5. "sync"
  6. "v2ray.com/core/common/compare"
  7. )
  8. type certPoolCache struct {
  9. sync.Mutex
  10. once sync.Once
  11. pool *x509.CertPool
  12. extraCerts [][]byte
  13. }
  14. func (c *certPoolCache) hasCert(cert []byte) bool {
  15. for _, xCert := range c.extraCerts {
  16. if compare.BytesEqual(xCert, cert) {
  17. return true
  18. }
  19. }
  20. return false
  21. }
  22. func (c *certPoolCache) get(extraCerts []*Certificate) *x509.CertPool {
  23. c.once.Do(func() {
  24. pool, err := x509.SystemCertPool()
  25. if err != nil {
  26. newError("failed to get system cert pool.").Base(err).WriteToLog()
  27. return
  28. }
  29. c.pool = pool
  30. })
  31. if c.pool == nil {
  32. return nil
  33. }
  34. if len(extraCerts) == 0 {
  35. return c.pool
  36. }
  37. c.Lock()
  38. defer c.Unlock()
  39. for _, cert := range extraCerts {
  40. if !c.hasCert(cert.Certificate) {
  41. c.pool.AppendCertsFromPEM(cert.Certificate)
  42. c.extraCerts = append(c.extraCerts, cert.Certificate)
  43. }
  44. }
  45. return c.pool
  46. }
  47. var combineCertPool certPoolCache
  48. func (c *Config) getCertPool() *x509.CertPool {
  49. return combineCertPool.get(c.Certificate)
  50. }