@@ -5,50 +5,120 @@ 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+ 		// Ignore directories that don't exist 
53+ 		if  os .IsNotExist (err ) {
54+ 			return  certRead , nil 
55+ 		}
56+ 		return  certRead , err 
2457	}
25- 	count  :=  0 
2658
2759	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 )
60+ 		file  :=  filepath .Join (dir , e .Name ())
61+ 		c , err  :=  readCertFile (pool , file , log )
3162		if  err  !=  nil  {
32- 			return  nil , err 
33- 		}
34- 		if  fi .IsDir () {
35- 			log .V (defaultLogLevel ).Info ("skip directory" , "name" , e .Name ())
36- 			continue 
63+ 			return  certRead , err 
3764		}
38- 		log .V (defaultLogLevel ).Info ("load certificate" , "name" , e .Name (), "size" , fi .Size (), "modtime" , fi .ModTime ())
39- 		data , err  :=  os .ReadFile (file )
65+ 		certRead  =  certRead  ||  c 
66+ 	}
67+ 	return  certRead , nil 
68+ }
69+ 
70+ // This function looks explicitly at the SSL environment, and 
71+ // uses it to create a "fresh" system cert pool 
72+ func  systemCertPool (log  logr.Logger ) (* x509.CertPool , error ) {
73+ 	sslCertDir  :=  os .Getenv ("SSL_CERT_DIR" )
74+ 	sslCertFile  :=  os .Getenv ("SSL_CERT_FILE" )
75+ 	if  sslCertDir  ==  ""  &&  sslCertFile  ==  ""  {
76+ 		log .V (defaultLogLevel ).Info ("SystemCertPool: SSL environment not set" )
77+ 		return  x509 .SystemCertPool ()
78+ 	}
79+ 	log .V (defaultLogLevel ).Info ("SystemCertPool: SSL environment set" , "SSL_CERT_DIR" , sslCertDir , "SSL_CERT_FILE" , sslCertFile )
80+ 
81+ 	var  certRead  bool 
82+ 	pool  :=  x509 .NewCertPool ()
83+ 
84+ 	// SSL_CERT_DIR may consist of multiple entries separated by ":" 
85+ 	for  _ , d  :=  range  strings .Split (sslCertDir , ":" ) {
86+ 		c , err  :=  readCertDir (pool , d , log )
4087		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 ++ 
88+ 			return  nil , err 
4689		}
47- 		logPem (data , e .Name (), caDir , "loading certificate file" , log )
90+ 		certRead  =  certRead  ||  c 
91+ 	}
92+ 	// SSL_CERT_FILE may consist of only a single entry 
93+ 	c , err  :=  readCertFile (pool , sslCertFile , log )
94+ 	if  err  !=  nil  {
95+ 		return  nil , err 
96+ 	}
97+ 	certRead  =  certRead  ||  c 
98+ 
99+ 	// If SSL_CERT_DIR and SSL_CERT_FILE resulted in no certs, then return the system cert pool 
100+ 	if  ! certRead  {
101+ 		return  x509 .SystemCertPool ()
102+ 	}
103+ 	return  pool , nil 
104+ }
105+ 
106+ func  NewCertPool (caDir  string , log  logr.Logger ) (* x509.CertPool , error ) {
107+ 	caCertPool , err  :=  systemCertPool (log )
108+ 	if  err  !=  nil  {
109+ 		return  nil , err 
110+ 	}
111+ 
112+ 	if  caDir  ==  ""  {
113+ 		return  caCertPool , nil 
114+ 	}
115+ 	count , err  :=  readCertDir (caCertPool , caDir , log )
116+ 	if  err  !=  nil  {
117+ 		return  nil , err 
48118	}
49119
50120	// Found no certs! 
51- 	if  count   ==   0  {
121+ 	if  ! count  {
52122		return  nil , fmt .Errorf ("no certificates found in %q" , caDir )
53123	}
54124
0 commit comments