77 "net"
88 "net/http"
99 "os"
10+ "strconv"
11+ "strings"
1012 "time"
1113
1214 "github.com/go-acme/lego/v4/certcrypto"
@@ -16,10 +18,15 @@ import (
1618const (
1719 // caCertificatesEnvVar is the environment variable name that can be used to
1820 // specify the path to PEM encoded CA Certificates that can be used to
19- // authenticate an ACME server with a HTTPS certificate not issued by a CA in
21+ // authenticate an ACME server with an HTTPS certificate not issued by a CA in
2022 // the system-wide trusted root list.
23+ // Multiple file paths can be added by using os.PathListSeparator as a separator.
2124 caCertificatesEnvVar = "LEGO_CA_CERTIFICATES"
2225
26+ // caSystemCertPool is the environment variable name that can be used to define
27+ // if the certificates pool must use a copy of the system cert pool.
28+ caSystemCertPool = "LEGO_CA_SYSTEM_CERT_POOL"
29+
2330 // caServerNameEnvVar is the environment variable name that can be used to
2431 // specify the CA server name that can be used to
2532 // authenticate an ACME server with a HTTPS certificate not issued by a CA in
@@ -81,23 +88,44 @@ func createDefaultHTTPClient() *http.Client {
8188}
8289
8390// initCertPool creates a *x509.CertPool populated with the PEM certificates
84- // found in the filepath specified in the caCertificatesEnvVar OS environment
85- // variable. If the caCertificatesEnvVar is not set then initCertPool will
86- // return nil. If there is an error creating a *x509.CertPool from the provided
87- // caCertificatesEnvVar value then initCertPool will panic.
91+ // found in the filepath specified in the caCertificatesEnvVar OS environment variable.
92+ // If the caCertificatesEnvVar is not set then initCertPool will return nil.
93+ // If there is an error creating a *x509.CertPool from the provided caCertificatesEnvVar value then initCertPool will panic.
94+ // If the caSystemCertPool is set to a "truthy value" (`1`, `t`, `T`, `TRUE`, `true`, `True`) then a copy of system cert pool will be used.
95+ // caSystemCertPool requires caCertificatesEnvVar to be set.
8896func initCertPool () * x509.CertPool {
89- if customCACertsPath := os .Getenv (caCertificatesEnvVar ); customCACertsPath != "" {
90- customCAs , err := os .ReadFile (customCACertsPath )
97+ customCACertsPath := os .Getenv (caCertificatesEnvVar )
98+ if customCACertsPath == "" {
99+ return nil
100+ }
101+
102+ certPool := getCertPool ()
103+
104+ for _ , customPath := range strings .Split (customCACertsPath , string (os .PathListSeparator )) {
105+ customCAs , err := os .ReadFile (customPath )
91106 if err != nil {
92107 panic (fmt .Sprintf ("error reading %s=%q: %v" ,
93- caCertificatesEnvVar , customCACertsPath , err ))
108+ caCertificatesEnvVar , customPath , err ))
94109 }
95- certPool := x509 . NewCertPool ()
110+
96111 if ok := certPool .AppendCertsFromPEM (customCAs ); ! ok {
97112 panic (fmt .Sprintf ("error creating x509 cert pool from %s=%q: %v" ,
98- caCertificatesEnvVar , customCACertsPath , err ))
113+ caCertificatesEnvVar , customPath , err ))
99114 }
100- return certPool
101115 }
102- return nil
116+
117+ return certPool
118+ }
119+
120+ func getCertPool () * x509.CertPool {
121+ useSystemCertPool , _ := strconv .ParseBool (os .Getenv (caSystemCertPool ))
122+ if ! useSystemCertPool {
123+ return x509 .NewCertPool ()
124+ }
125+
126+ pool , err := x509 .SystemCertPool ()
127+ if err == nil {
128+ return pool
129+ }
130+ return x509 .NewCertPool ()
103131}
0 commit comments