default_cert.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // Copyright 2020 Google LLC.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package cert contains certificate tools for Google API clients.
  5. // This package is intended to be used with crypto/tls.Config.GetClientCertificate.
  6. //
  7. // The certificates can be used to satisfy Google's Endpoint Validation.
  8. // See https://cloud.google.com/endpoint-verification/docs/overview
  9. //
  10. // This package is not intended for use by end developers. Use the
  11. // google.golang.org/api/option package to configure API clients.
  12. package cert
  13. import (
  14. "crypto/tls"
  15. "errors"
  16. "sync"
  17. )
  18. // defaultCertData holds all the variables pertaining to
  19. // the default certficate source created by DefaultSource.
  20. //
  21. // A singleton model is used to allow the source to be reused
  22. // by the transport layer.
  23. type defaultCertData struct {
  24. once sync.Once
  25. source Source
  26. err error
  27. }
  28. var (
  29. defaultCert defaultCertData
  30. )
  31. // Source is a function that can be passed into crypto/tls.Config.GetClientCertificate.
  32. type Source func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
  33. // errSourceUnavailable is a sentinel error to indicate certificate source is unavailable.
  34. var errSourceUnavailable = errors.New("certificate source is unavailable")
  35. // DefaultSource returns a certificate source using the preferred EnterpriseCertificateProxySource.
  36. // If EnterpriseCertificateProxySource is not available, fall back to the legacy SecureConnectSource.
  37. //
  38. // If neither source is available (due to missing configurations), a nil Source and a nil Error are
  39. // returned to indicate that a default certificate source is unavailable.
  40. func DefaultSource() (Source, error) {
  41. defaultCert.once.Do(func() {
  42. defaultCert.source, defaultCert.err = NewEnterpriseCertificateProxySource("")
  43. if errors.Is(defaultCert.err, errSourceUnavailable) {
  44. defaultCert.source, defaultCert.err = NewSecureConnectSource("")
  45. if errors.Is(defaultCert.err, errSourceUnavailable) {
  46. defaultCert.source, defaultCert.err = nil, nil
  47. }
  48. }
  49. })
  50. return defaultCert.source, defaultCert.err
  51. }