Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 28 additions & 21 deletions pkg/httpclient/httpclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"net/http"
"net/http/httptest"
"os"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -16,7 +15,7 @@ import (
)

func TestRootCAs(t *testing.T) {
ts, err := NewLocalHTTPSTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ts, caCertPEM, err := NewLocalHTTPSTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, client")
}))
assert.Nil(t, err)
Expand All @@ -31,26 +30,24 @@ func TestRootCAs(t *testing.T) {
res, err := testClient.Get(ts.URL)
assert.Nil(t, err)

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

assert.Equal(t, "Hello, client", string(greeting))
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)})
runTest("From runtime generated cert", []string{string(caCertPEM)})

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

func TestInsecureSkipVerify(t *testing.T) {
ts, err := NewLocalHTTPSTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ts, _, err := NewLocalHTTPSTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, client")
}))
assert.Nil(t, err)
Expand All @@ -64,20 +61,30 @@ func TestInsecureSkipVerify(t *testing.T) {
res, err := testClient.Get(ts.URL)
assert.Nil(t, err)

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

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

func NewLocalHTTPSTestServer(handler http.Handler) (*httptest.Server, error) {
func NewLocalHTTPSTestServer(handler http.Handler) (*httptest.Server, []byte, error) {
ts := httptest.NewUnstartedServer(handler)
cert, err := tls.LoadX509KeyPair("testdata/server.crt", "testdata/server.key")

// Generate CA and server cert/key once so client and server share trust
caCertPEM, serverCertPEM, serverKeyPEM, err := httpclient.GenerateTestCertificates()
if err != nil {
return nil, err
return nil, nil, err
}

cert, err := tls.X509KeyPair(serverCertPEM, serverKeyPEM)
if err != nil {
return nil, nil, err
}

ts.TLS = &tls.Config{Certificates: []tls.Certificate{cert}}
ts.StartTLS()
return ts, nil
return ts, caCertPEM, nil
}
118 changes: 118 additions & 0 deletions pkg/httpclient/testcerts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package httpclient

import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"net"
"time"
)

// GenerateTestCertificates creates a CA and server certificate pair for testing
func GenerateTestCertificates() (caCertPEM, serverCertPEM, serverKeyPEM []byte, err error) {
// Generate CA private key
caKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, nil, nil, err
}

// Create CA certificate template
caTemplate := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
Country: []string{"US"},
Province: []string{"RandomState"},
Locality: []string{"RandomCity"},
Organization: []string{"Test Organization"},
OrganizationalUnit: []string{"Test Unit"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour), // 1 year
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: true,
}

// Create CA certificate
caCertDER, err := x509.CreateCertificate(rand.Reader, &caTemplate, &caTemplate, &caKey.PublicKey, caKey)
if err != nil {
return nil, nil, nil, err
}

// Encode CA certificate to PEM
caCertPEM = pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: caCertDER,
})

// Generate server private key
serverKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, nil, nil, err
}

// Create server certificate template
serverTemplate := x509.Certificate{
SerialNumber: big.NewInt(2),
Subject: pkix.Name{
Country: []string{"US"},
Province: []string{"RandomState"},
Locality: []string{"RandomCity"},
Organization: []string{"Test Organization"},
OrganizationalUnit: []string{"Test Unit"},
CommonName: "localhost",
},
NotBefore: time.Now(),

Check failure on line 70 in pkg/httpclient/testcerts.go

View workflow job for this annotation

GitHub Actions / Lint

File is not properly formatted (gci)
NotAfter: time.Now().Add(365 * 24 * time.Hour), // 1 year
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1)},
DNSNames: []string{"localhost"},
}

// Parse CA certificate for signing
caCert, err := x509.ParseCertificate(caCertDER)
if err != nil {
return nil, nil, nil, err
}

// Create server certificate signed by CA
serverCertDER, err := x509.CreateCertificate(rand.Reader, &serverTemplate, caCert, &serverKey.PublicKey, caKey)
if err != nil {
return nil, nil, nil, err
}

// Encode server certificate to PEM
serverCertPEM = pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: serverCertDER,
})

// Encode server private key to PEM
serverKeyPEM = pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(serverKey),
})

return caCertPEM, serverCertPEM, serverKeyPEM, nil
}

// CreateTestTLSCertificate creates a tls.Certificate for testing
func CreateTestTLSCertificate() (tls.Certificate, []byte, error) {
caCertPEM, serverCertPEM, serverKeyPEM, err := GenerateTestCertificates()
if err != nil {
return tls.Certificate{}, nil, err
}

cert, err := tls.X509KeyPair(serverCertPEM, serverKeyPEM)
if err != nil {
return tls.Certificate{}, nil, err
}

return cert, caCertPEM, nil
}
27 changes: 0 additions & 27 deletions pkg/httpclient/testdata/rootCA.key

This file was deleted.

23 changes: 0 additions & 23 deletions pkg/httpclient/testdata/rootCA.pem

This file was deleted.

1 change: 0 additions & 1 deletion pkg/httpclient/testdata/rootCA.srl

This file was deleted.

29 changes: 0 additions & 29 deletions pkg/httpclient/testdata/server.crt

This file was deleted.

18 changes: 0 additions & 18 deletions pkg/httpclient/testdata/server.csr

This file was deleted.

14 changes: 0 additions & 14 deletions pkg/httpclient/testdata/server.csr.cnf

This file was deleted.

28 changes: 0 additions & 28 deletions pkg/httpclient/testdata/server.key

This file was deleted.

8 changes: 0 additions & 8 deletions pkg/httpclient/testdata/v3.ext

This file was deleted.

Loading