config_other.go 1.3 KB

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