config_other.go 1.0 KB

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