@@ -5,50 +5,116 @@ import (
55 "fmt"
66 "os"
77 "path/filepath"
8+ "strings"
89
910 "github.com/go-logr/logr"
1011)
1112
12- func NewCertPool (caDir string , log logr.Logger ) (* x509.CertPool , error ) {
13- caCertPool , err := x509 .SystemCertPool ()
13+ func readCertFile (pool * x509.CertPool , file string , log logr.Logger ) (bool , error ) {
14+ var certRead bool
15+ if file == "" {
16+ return certRead , nil
17+ }
18+ // These might be symlinks pointing to directories, so use Stat() to resolve
19+ fi , err := os .Stat (file )
1420 if err != nil {
15- return nil , err
21+ // Ignore files that don't exist
22+ if os .IsNotExist (err ) {
23+ return certRead , nil
24+ }
25+ return certRead , err
1626 }
17- if caDir == "" {
18- return caCertPool , nil
27+ if fi .IsDir () {
28+ log .V (defaultLogLevel ).Info ("skip directory" , "name" , file )
29+ return certRead , nil
1930 }
31+ log .V (defaultLogLevel ).Info ("load certificate" , "name" , file , "size" , fi .Size (), "modtime" , fi .ModTime ())
32+ data , err := os .ReadFile (file )
33+ if err != nil {
34+ return certRead , fmt .Errorf ("error reading cert file %q: %w" , file , err )
35+ }
36+ // The return indicates if any certs were added
37+ if pool .AppendCertsFromPEM (data ) {
38+ certRead = true
39+ }
40+ logPem (data , filepath .Base (file ), filepath .Dir (file ), "loading certificate file" , log )
41+
42+ return certRead , nil
43+ }
2044
21- dirEntries , err := os .ReadDir (caDir )
45+ func readCertDir (pool * x509.CertPool , dir string , log logr.Logger ) (bool , error ) {
46+ var certRead bool
47+ if dir == "" {
48+ return certRead , nil
49+ }
50+ dirEntries , err := os .ReadDir (dir )
2251 if err != nil {
23- return nil , err
52+ return certRead , err
2453 }
25- count := 0
2654
2755 for _ , e := range dirEntries {
28- file := filepath .Join (caDir , e .Name ())
29- // These might be symlinks pointing to directories, so use Stat() to resolve
30- fi , err := os .Stat (file )
56+ file := filepath .Join (dir , e .Name ())
57+ c , err := readCertFile (pool , file , log )
3158 if err != nil {
32- return nil , err
59+ return certRead , err
3360 }
34- if fi .IsDir () {
35- log .V (defaultLogLevel ).Info ("skip directory" , "name" , e .Name ())
36- continue
37- }
38- log .V (defaultLogLevel ).Info ("load certificate" , "name" , e .Name (), "size" , fi .Size (), "modtime" , fi .ModTime ())
39- data , err := os .ReadFile (file )
61+ certRead = certRead || c
62+ }
63+ return certRead , nil
64+ }
65+
66+ // This function looks explicitly at the SSL environment, and
67+ // uses it to create a "fresh" system cert pool
68+ func systemCertPool (log logr.Logger ) (* x509.CertPool , error ) {
69+ sslCertDir := os .Getenv ("SSL_CERT_DIR" )
70+ sslCertFile := os .Getenv ("SSL_CERT_FILE" )
71+ if sslCertDir == "" && sslCertFile == "" {
72+ log .V (defaultLogLevel ).Info ("SystemCertPool: SSL environment not set" )
73+ return x509 .SystemCertPool ()
74+ }
75+ log .V (defaultLogLevel ).Info ("SystemCertPool: SSL environment set" , "SSL_CERT_DIR" , sslCertDir , "SSL_CERT_FILE" , sslCertFile )
76+
77+ var certRead bool
78+ pool := x509 .NewCertPool ()
79+
80+ // SSL_CERT_DIR may consist of multiple entries separated by ":"
81+ for _ , d := range strings .Split (sslCertDir , ":" ) {
82+ c , err := readCertDir (pool , d , log )
4083 if err != nil {
41- return nil , fmt .Errorf ("error reading cert file %q: %w" , file , err )
42- }
43- // The return indicates if any certs were added
44- if caCertPool .AppendCertsFromPEM (data ) {
45- count ++
84+ return nil , err
4685 }
47- logPem (data , e .Name (), caDir , "loading certificate file" , log )
86+ certRead = certRead || c
87+ }
88+ // SSL_CERT_FILE may consist of only a single entry
89+ c , err := readCertFile (pool , sslCertFile , log )
90+ if err != nil {
91+ return nil , err
92+ }
93+ certRead = certRead || c
94+
95+ // If SSL_CERT_DIR and SSL_CERT_FILE resulted in no certs, then return the system cert pool
96+ if ! certRead {
97+ return x509 .SystemCertPool ()
98+ }
99+ return pool , nil
100+ }
101+
102+ func NewCertPool (caDir string , log logr.Logger ) (* x509.CertPool , error ) {
103+ caCertPool , err := systemCertPool (log )
104+ if err != nil {
105+ return nil , err
106+ }
107+
108+ if caDir == "" {
109+ return caCertPool , nil
110+ }
111+ count , err := readCertDir (caCertPool , caDir , log )
112+ if err != nil {
113+ return nil , err
48114 }
49115
50116 // Found no certs!
51- if count == 0 {
117+ if ! count {
52118 return nil , fmt .Errorf ("no certificates found in %q" , caDir )
53119 }
54120
0 commit comments