Skip to content

Commit 2296322

Browse files
authored
Extract and unify test certificate creation (#233)
We have a few different places where we create a test certificate. This change creates a new package and updates all the tests to reference.
1 parent 04b0af1 commit 2296322

File tree

6 files changed

+65
-99
lines changed

6 files changed

+65
-99
lines changed

diagnose_test.go

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
package ngrok
22

33
import (
4-
"crypto/ecdsa"
5-
"crypto/elliptic"
6-
"crypto/rand"
74
"crypto/tls"
8-
"crypto/x509"
9-
"crypto/x509/pkix"
105
"encoding/json"
11-
"math/big"
126
"net"
137
"os"
148
"testing"
@@ -20,6 +14,7 @@ import (
2014
muxado "golang.ngrok.com/muxado/v2"
2115

2216
"golang.ngrok.com/ngrok/v2/internal/testcontext"
17+
"golang.ngrok.com/ngrok/v2/internal/tlstest"
2318
"golang.ngrok.com/ngrok/v2/internal/tunnel/proto"
2419
)
2520

@@ -73,22 +68,12 @@ func TestDiagnoseTLSFailure(t *testing.T) {
7368
// TestDiagnoseMuxadoSuccess verifies the full happy path: TCP → TLS → Muxado
7469
// → SrvInfo all succeed against a local test server.
7570
func TestDiagnoseMuxadoSuccess(t *testing.T) {
76-
// Generate a self-signed TLS certificate for the test server.
77-
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
78-
require.NoError(t, err)
79-
80-
template := &x509.Certificate{
81-
SerialNumber: big.NewInt(1),
82-
Subject: pkix.Name{CommonName: "diagnose-test"},
83-
NotBefore: time.Now().Add(-time.Hour),
84-
NotAfter: time.Now().Add(24 * time.Hour),
85-
DNSNames: []string{"localhost"},
71+
cert, err := tlstest.CreateCertificate()
72+
if err != nil {
73+
t.Fatal(err)
8674
}
87-
certDER, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
88-
require.NoError(t, err)
89-
9075
tlsServerCfg := &tls.Config{
91-
Certificates: []tls.Certificate{{Certificate: [][]byte{certDER}, PrivateKey: priv}},
76+
Certificates: []tls.Certificate{*cert},
9277
}
9378

9479
l, err := tls.Listen("tcp", "localhost:0", tlsServerCfg)

internal/integration_tests/agent_tls_termination_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/stretchr/testify/require"
1212
"golang.ngrok.com/ngrok/v2"
1313
"golang.ngrok.com/ngrok/v2/internal/testutil"
14+
"golang.ngrok.com/ngrok/v2/internal/tlstest"
1415
)
1516

1617
// TestAgentTLSTerminationIntegration tests agent-based TLS termination with custom certificates
@@ -19,7 +20,10 @@ func TestAgentTLSTerminationIntegration(t *testing.T) {
1920
t.Parallel()
2021

2122
// Generate test certificate
22-
cert := CreateTestCertificate(t)
23+
cert, err := tlstest.CreateCertificate()
24+
if err != nil {
25+
t.Fatal(err)
26+
}
2327

2428
// Setup agent
2529
agent, ctx := SetupAgent(t)

internal/integration_tests/proxy_proto_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/stretchr/testify/require"
1818
"golang.ngrok.com/ngrok/v2"
1919
"golang.ngrok.com/ngrok/v2/internal/testutil"
20+
"golang.ngrok.com/ngrok/v2/internal/tlstest"
2021
)
2122

2223
// parseProxyProtocolHeader extracts client and server information from a PROXY protocol header.
@@ -132,7 +133,10 @@ func verifyClientAddr(t *testing.T, clientAddr net.Addr) {
132133
// handleTLSConnection handles a TLS connection with PROXY protocol already read
133134
func handleTLSConnection(t *testing.T, conn net.Conn, reader *bufio.Reader, srcAddr net.Addr) {
134135
// Create a server TLS certificate for the handshake
135-
servCert := CreateTestCertificate(t)
136+
servCert, err := tlstest.CreateCertificate()
137+
if err != nil {
138+
t.Fatal(err)
139+
}
136140

137141
// Create TLS configuration for server
138142
config := &tls.Config{

internal/integration_tests/test_utils.go

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,9 @@ package integration_tests
33
import (
44
"bufio"
55
"context"
6-
"crypto/rand"
7-
"crypto/rsa"
86
"crypto/tls"
9-
"crypto/x509"
10-
"crypto/x509/pkix"
117
"fmt"
128
"io"
13-
"math/big"
149
"net"
1510
"net/http"
1611
"os"
@@ -118,36 +113,6 @@ func WaitForForwarderReady(t *testing.T, url string) {
118113
t.Logf("Forwarder endpoint didn't become ready in expected time, continuing anyway")
119114
}
120115

121-
// CreateTestCertificate creates a certificate for testing
122-
func CreateTestCertificate(t *testing.T) *tls.Certificate {
123-
// Generate a self-signed certificate for testing
124-
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
125-
require.NoError(t, err, "Failed to generate private key")
126-
127-
templ := x509.Certificate{
128-
SerialNumber: big.NewInt(1),
129-
Subject: pkix.Name{
130-
CommonName: "localhost",
131-
},
132-
NotBefore: time.Now(),
133-
NotAfter: time.Now().Add(time.Hour),
134-
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
135-
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
136-
BasicConstraintsValid: true,
137-
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
138-
}
139-
140-
certDER, err := x509.CreateCertificate(rand.Reader, &templ, &templ, &privKey.PublicKey, privKey)
141-
require.NoError(t, err, "Failed to create certificate")
142-
143-
cert := tls.Certificate{
144-
Certificate: [][]byte{certDER},
145-
PrivateKey: privKey,
146-
}
147-
148-
return &cert
149-
}
150-
151116
// MakeTCPConnection establishes a TCP connection to the given address
152117
func MakeTCPConnection(t *testing.T, ctx context.Context, address string) (io.ReadWriteCloser, error) {
153118
t.Helper()

internal/tlstest/tlstest.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Package tlstest provides a function for creating a TLS certificate suitable for testing.
2+
package tlstest
3+
4+
import (
5+
"crypto/rand"
6+
"crypto/rsa"
7+
"crypto/tls"
8+
"crypto/x509"
9+
"crypto/x509/pkix"
10+
"math/big"
11+
"net"
12+
"time"
13+
)
14+
15+
// CreateCertificate creates a self-signed localhost TLS certificate with a 24-hour expiry.
16+
func CreateCertificate() (*tls.Certificate, error) {
17+
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
18+
if err != nil {
19+
return nil, err
20+
}
21+
22+
now := time.Now()
23+
template := &x509.Certificate{
24+
SerialNumber: big.NewInt(1),
25+
Subject: pkix.Name{CommonName: "localhost"},
26+
NotBefore: now,
27+
NotAfter: now.Add(24 * time.Hour),
28+
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
29+
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
30+
BasicConstraintsValid: true,
31+
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
32+
}
33+
34+
certDER, err := x509.CreateCertificate(rand.Reader, template, template, &privateKey.PublicKey, privateKey)
35+
if err != nil {
36+
return nil, err
37+
}
38+
39+
return &tls.Certificate{
40+
Certificate: [][]byte{certDER},
41+
PrivateKey: privateKey,
42+
Leaf: template,
43+
}, nil
44+
}

listener_test.go

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,20 @@
11
package ngrok
22

33
import (
4-
"crypto/rand"
5-
"crypto/rsa"
64
"crypto/tls"
7-
"crypto/x509"
8-
"crypto/x509/pkix"
9-
"math/big"
105
"net"
116
"testing"
12-
"time"
13-
)
14-
15-
// createTestCertificate creates a self-signed certificate for testing
16-
func createTestCertificate(t *testing.T) *tls.Certificate {
17-
// Generate a private key
18-
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
19-
if err != nil {
20-
t.Fatalf("Failed to generate private key: %v", err)
21-
}
227

23-
// Create a certificate template
24-
template := x509.Certificate{
25-
SerialNumber: big.NewInt(1),
26-
Subject: pkix.Name{CommonName: "localhost"},
27-
NotBefore: time.Now(),
28-
NotAfter: time.Now().Add(time.Hour * 24), // Valid for 24 hours
29-
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
30-
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
31-
BasicConstraintsValid: true,
32-
}
33-
34-
// Create a self-signed certificate
35-
certBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
36-
if err != nil {
37-
t.Fatalf("Failed to create certificate: %v", err)
38-
}
39-
40-
// Create a TLS certificate
41-
cert := &tls.Certificate{
42-
Certificate: [][]byte{certBytes},
43-
PrivateKey: privateKey,
44-
Leaf: &template,
45-
}
46-
47-
return cert
48-
}
8+
"golang.ngrok.com/ngrok/v2/internal/tlstest"
9+
)
4910

5011
// TestWrapConnWithTLS tests the TLS connection wrapper
5112
func TestWrapConnWithTLS(t *testing.T) {
5213
// Create a test certificate
53-
cert := createTestCertificate(t)
14+
cert, err := tlstest.CreateCertificate()
15+
if err != nil {
16+
t.Fatal(err)
17+
}
5418

5519
// Create a pipe for testing
5620
serverConn, clientConn := net.Pipe()

0 commit comments

Comments
 (0)