Skip to content

Commit

Permalink
Support base64 encoded and PEM encoded certs
Browse files Browse the repository at this point in the history
Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com>
  • Loading branch information
nabokihms committed Sep 16, 2024
1 parent 56f0e08 commit bc8ce4a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 15 deletions.
31 changes: 25 additions & 6 deletions pkg/httpclient/httpclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,46 @@ package httpclient
import (
"crypto/tls"
"crypto/x509"
"encoding/base64"
"fmt"
"net"
"net/http"
"os"
"time"
)

func extractCAs(input []string) [][]byte {
var result [][]byte

Check failure on line 15 in pkg/httpclient/httpclient.go

View workflow job for this annotation

GitHub Actions / Lint

Consider pre-allocating `result` (prealloc)
for _, ca := range input {
if ca == "" {
continue
}

pemData, err := os.ReadFile(ca)
if err != nil {
pemData, err = base64.StdEncoding.DecodeString(ca)
if err != nil {
pemData = []byte(ca)
}
}

result = append(result, pemData)
}
return result
}

func NewHTTPClient(rootCAs []string, insecureSkipVerify bool) (*http.Client, error) {
pool, err := x509.SystemCertPool()
if err != nil {
return nil, err
}

tlsConfig := tls.Config{RootCAs: pool, InsecureSkipVerify: insecureSkipVerify}
for _, rootCA := range rootCAs {
rootCABytes, err := os.ReadFile(rootCA)
if err != nil {
return nil, fmt.Errorf("failed to read root-ca: %v", err)
}
for index, rootCABytes := range extractCAs(rootCAs) {
if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) {
return nil, fmt.Errorf("no certs found in root CA file %q", rootCA)
return nil, fmt.Errorf("rootCAs.%d is not in PEM format, certificate must be "+
"a PEM encoded string, a base64 encoded bytes that contain PEM encoded string, "+
"or a path to a PEM encoded certificate", index)
}
}

Expand Down
34 changes: 25 additions & 9 deletions pkg/httpclient/httpclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package httpclient_test

import (
"crypto/tls"
"encoding/base64"
"fmt"
"io"
"net/http"
"net/http/httptest"
"os"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -20,18 +22,32 @@ func TestRootCAs(t *testing.T) {
assert.Nil(t, err)
defer ts.Close()

rootCAs := []string{"testdata/rootCA.pem"}
testClient, err := httpclient.NewHTTPClient(rootCAs, false)
assert.Nil(t, err)
runTest := func(name string, certs []string) {
t.Run(name, func(t *testing.T) {
rootCAs := certs
testClient, err := httpclient.NewHTTPClient(rootCAs, false)
assert.Nil(t, err)

res, err := testClient.Get(ts.URL)
assert.Nil(t, err)
res, err := testClient.Get(ts.URL)
assert.Nil(t, err)

greeting, err := io.ReadAll(res.Body)
res.Body.Close()
assert.Nil(t, err)
greeting, err := io.ReadAll(res.Body)
res.Body.Close()
assert.Nil(t, err)

assert.Equal(t, "Hello, client", string(greeting))
})
}

runTest("From file", []string{"testdata/rootCA.pem"})

content, err := os.ReadFile("testdata/rootCA.pem")
assert.NoError(t, err)
runTest("From string", []string{string(content)})

contentStr := base64.StdEncoding.EncodeToString(content)
runTest("From bytes", []string{contentStr})

assert.Equal(t, "Hello, client", string(greeting))
}

Check failure on line 51 in pkg/httpclient/httpclient_test.go

View workflow job for this annotation

GitHub Actions / Lint

unnecessary trailing newline (whitespace)

func TestInsecureSkipVerify(t *testing.T) {
Expand Down

0 comments on commit bc8ce4a

Please sign in to comment.