Skip to content

Commit 6b58241

Browse files
authored
feat: extended support of cert pool (#1565)
- `LEGO_CA_CERTIFICATES` now accepts multiple file paths to be added by using `os.PathListSeparator` (`:` on POSIX, `;` on Windows) as a separator. - `LEGO_CA_SYSTEM_CERT_POOL` initiates the cert pool with a copy of the system cert pool.
1 parent bbec0a6 commit 6b58241

File tree

1 file changed

+40
-12
lines changed

1 file changed

+40
-12
lines changed

lego/client_config.go

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
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 (
1618
const (
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.
8896
func 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

Comments
 (0)