From 834a9089f143e3407b3f5c8b93a0e285ba231fe2 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Thu, 13 Jun 2024 23:10:59 +0200 Subject: [PATCH] feat: expose certificates pool creation (#2210) --- challenge/http01/domain_matcher.go | 2 +- lego/client_config.go | 42 ++++++++++++++++++--------- providers/dns/acmedns/acmedns_test.go | 2 +- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/challenge/http01/domain_matcher.go b/challenge/http01/domain_matcher.go index ae681c64..5c755c4b 100644 --- a/challenge/http01/domain_matcher.go +++ b/challenge/http01/domain_matcher.go @@ -57,7 +57,7 @@ func (m *hostMatcher) matches(r *http.Request, domain string) bool { return strings.HasPrefix(r.Host, domain) } -// hostMatcher checks whether the specified (*net/http.Request).Header value starts with a domain name. +// arbitraryMatcher checks whether the specified (*net/http.Request).Header value starts with a domain name. type arbitraryMatcher string func (m arbitraryMatcher) name() string { diff --git a/lego/client_config.go b/lego/client_config.go index 7ce6394c..fdf1a55f 100644 --- a/lego/client_config.go +++ b/lego/client_config.go @@ -100,26 +100,41 @@ func initCertPool() *x509.CertPool { return nil } - certPool := getCertPool() + useSystemCertPool, _ := strconv.ParseBool(os.Getenv(caSystemCertPool)) - for _, customPath := range strings.Split(customCACertsPath, string(os.PathListSeparator)) { - customCAs, err := os.ReadFile(customPath) - if err != nil { - panic(fmt.Sprintf("error reading %s=%q: %v", - caCertificatesEnvVar, customPath, err)) - } + caCerts := strings.Split(customCACertsPath, string(os.PathListSeparator)) - if ok := certPool.AppendCertsFromPEM(customCAs); !ok { - panic(fmt.Sprintf("error creating x509 cert pool from %s=%q: %v", - caCertificatesEnvVar, customPath, err)) - } + certPool, err := CreateCertPool(caCerts, useSystemCertPool) + if err != nil { + panic(fmt.Sprintf("create certificates pool: %v", err)) } return certPool } -func getCertPool() *x509.CertPool { - useSystemCertPool, _ := strconv.ParseBool(os.Getenv(caSystemCertPool)) +// CreateCertPool creates a *x509.CertPool populated with the PEM certificates. +func CreateCertPool(caCerts []string, useSystemCertPool bool) (*x509.CertPool, error) { + if len(caCerts) == 0 { + return nil, nil + } + + certPool := newCertPool(useSystemCertPool) + + for _, customPath := range caCerts { + customCAs, err := os.ReadFile(customPath) + if err != nil { + return nil, fmt.Errorf("error reading %q: %w", customPath, err) + } + + if ok := certPool.AppendCertsFromPEM(customCAs); !ok { + return nil, fmt.Errorf("error creating x509 cert pool from %q: %w", customPath, err) + } + } + + return certPool, nil +} + +func newCertPool(useSystemCertPool bool) *x509.CertPool { if !useSystemCertPool { return x509.NewCertPool() } @@ -128,5 +143,6 @@ func getCertPool() *x509.CertPool { if err == nil { return pool } + return x509.NewCertPool() } diff --git a/providers/dns/acmedns/acmedns_test.go b/providers/dns/acmedns/acmedns_test.go index bce36c7a..68e8f740 100644 --- a/providers/dns/acmedns/acmedns_test.go +++ b/providers/dns/acmedns/acmedns_test.go @@ -59,7 +59,7 @@ func (c mockUpdateClient) UpdateTXTRecord(acct goacmedns.Account, value string) return nil } -// errorRegisterClient is a mock implementing the acmeDNSClient interface that always +// errorUpdateClient is a mock implementing the acmeDNSClient interface that always // returns errors from errorUpdateClient. type errorUpdateClient struct { mockClient