From f6a2c2a16610597e5177d5c39933fc5416f18c9e Mon Sep 17 00:00:00 2001 From: Andrey Karpov Date: Tue, 3 Jun 2025 18:17:28 +0200 Subject: [PATCH] Fix panic in `tlsRoundTripper` when CA file is absent Signed-off-by: Andrey Karpov --- config/http_config.go | 3 +++ config/http_config_test.go | 42 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/config/http_config.go b/config/http_config.go index 5d3f1941..3b255282 100644 --- a/config/http_config.go +++ b/config/http_config.go @@ -1377,6 +1377,9 @@ func (t *tlsRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { // using GetClientCertificate. tlsConfig := t.tlsConfig.Clone() if !updateRootCA(tlsConfig, caData) { + if t.settings.CA == nil { + return nil, errors.New("unable to use specified CA cert: none configured") + } return nil, fmt.Errorf("unable to use specified CA cert %s", t.settings.CA.Description()) } rt, err = t.newRT(tlsConfig) diff --git a/config/http_config_test.go b/config/http_config_test.go index 58d13b0d..13fba5a8 100644 --- a/config/http_config_test.go +++ b/config/http_config_test.go @@ -1968,6 +1968,48 @@ func TestModifyTLSCertificates(t *testing.T) { } } +func TestTLSRoundTripper_NoCAConfigured(t *testing.T) { + bs := getCertificateBlobs(t) + + tmpDir, err := os.MkdirTemp("", "tlspanic") + require.NoErrorf(t, err, "Failed to create tmp dir") + defer os.RemoveAll(tmpDir) + cert, key := filepath.Join(tmpDir, "cert"), filepath.Join(tmpDir, "key") + + handler := func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, ExpectedMessage) + } + testServer, err := newTestServer(handler) + require.NoError(t, err) + defer testServer.Close() + + cfg := HTTPClientConfig{ + TLSConfig: TLSConfig{ + CertFile: cert, + KeyFile: key, + InsecureSkipVerify: true, + }, + } + + writeCertificate(bs, ClientCertificatePath, cert) + writeCertificate(bs, ClientKeyNoPassPath, key) + c, err := NewClientFromConfig(cfg, "test") + require.NoErrorf(t, err, "Error creating HTTP Client: %v", err) + + req, err := http.NewRequest(http.MethodGet, testServer.URL, nil) + require.NoErrorf(t, err, "Error creating HTTP request: %v", err) + + r, err := c.Do(req) + require.NoErrorf(t, err, "Can't connect to the test server") + r.Body.Close() + + err = os.WriteFile(cert, []byte("-----BEGIN GARBAGE-----\nabc\n-----END GARBAGE-----\n"), 0o664) + require.NoError(t, err) + + _, err = c.Do(req) + require.ErrorContainsf(t, err, "unable to use specified CA cert: none configured", "Expected error to mention missing CA cert") +} + // loadHTTPConfigJSON parses the JSON input s into a HTTPClientConfig. func loadHTTPConfigJSON(buf []byte) (*HTTPClientConfig, error) { cfg := &HTTPClientConfig{}