provider.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package roots
  2. import (
  3. "crypto/sha256"
  4. "crypto/x509"
  5. "errors"
  6. "os"
  7. "github.com/cloudflare/cfssl/helpers"
  8. "github.com/cloudflare/cfssl/transport/core"
  9. "github.com/cloudflare/cfssl/transport/roots/system"
  10. )
  11. // Providers is a mapping of supported providers and the functions
  12. // that can build them.
  13. var Providers = map[string]func(map[string]string) ([]*x509.Certificate, error){
  14. "system": system.New,
  15. "cfssl": NewCFSSL,
  16. "file": TrustPEM,
  17. }
  18. // A TrustStore contains a pool of certificate that are trusted for a
  19. // given TLS configuration.
  20. type TrustStore struct {
  21. roots map[string]*x509.Certificate
  22. }
  23. // Pool returns a certificate pool containing the certificates
  24. // loaded into the provider.
  25. func (ts *TrustStore) Pool() *x509.CertPool {
  26. var pool = x509.NewCertPool()
  27. for _, cert := range ts.roots {
  28. pool.AddCert(cert)
  29. }
  30. return pool
  31. }
  32. // Certificates returns a slice of the loaded certificates.
  33. func (ts *TrustStore) Certificates() []*x509.Certificate {
  34. var roots = make([]*x509.Certificate, 0, len(ts.roots))
  35. for _, cert := range ts.roots {
  36. roots = append(roots, cert)
  37. }
  38. return roots
  39. }
  40. func (ts *TrustStore) addCerts(certs []*x509.Certificate) {
  41. if ts.roots == nil {
  42. ts.roots = map[string]*x509.Certificate{}
  43. }
  44. for _, cert := range certs {
  45. digest := sha256.Sum256(cert.Raw)
  46. ts.roots[string(digest[:])] = cert
  47. }
  48. }
  49. // Trusted contains a store of trusted certificates.
  50. type Trusted interface {
  51. // Certificates returns a slice containing the certificates
  52. // that are loaded into the provider.
  53. Certificates() []*x509.Certificate
  54. // AddCert adds a new certificate into the certificate pool.
  55. AddCert(cert *x509.Certificate)
  56. // AddPEM adds a one or more PEM-encoded certificates into the
  57. // certificate pool.
  58. AddPEM(cert []byte) bool
  59. }
  60. // New produces a new trusted root provider from a collection of
  61. // roots. If there are no roots, the system roots will be used.
  62. func New(rootDefs []*core.Root) (*TrustStore, error) {
  63. var err error
  64. var store = &TrustStore{}
  65. var roots []*x509.Certificate
  66. if len(rootDefs) == 0 {
  67. roots, err = system.New(nil)
  68. if err != nil {
  69. return nil, err
  70. }
  71. store.addCerts(roots)
  72. return store, nil
  73. }
  74. err = errors.New("transport: no supported root providers found")
  75. for _, root := range rootDefs {
  76. pfn, ok := Providers[root.Type]
  77. if ok {
  78. roots, err = pfn(root.Metadata)
  79. if err != nil {
  80. break
  81. }
  82. store.addCerts(roots)
  83. }
  84. }
  85. if err != nil {
  86. store = nil
  87. }
  88. return store, err
  89. }
  90. // TrustPEM takes a source file containing one or more certificates
  91. // and adds them to the trust store.
  92. func TrustPEM(metadata map[string]string) ([]*x509.Certificate, error) {
  93. sourceFile, ok := metadata["source"]
  94. if !ok {
  95. return nil, errors.New("transport: PEM source requires a source file")
  96. }
  97. in, err := os.ReadFile(sourceFile)
  98. if err != nil {
  99. return nil, err
  100. }
  101. return helpers.ParseCertificatesPEM(in)
  102. }