Skip to content

Commit 7dbb999

Browse files
doodlesbykumbiszh
authored andcommitted
Use httptest package for self-signed cert tests
1 parent 8ade942 commit 7dbb999

File tree

3 files changed

+69
-82
lines changed

3 files changed

+69
-82
lines changed

pkg/cmd/init_test.go

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package cmd
22

33
import (
44
"fmt"
5+
"net"
6+
"net/http"
7+
"net/http/httptest"
58
"os"
69
"path/filepath"
710
"testing"
@@ -20,7 +23,7 @@ var initCmdTestCases = []struct {
2023
// https://github.com/go-survey/survey/issues/394
2124
// This flag is used to enable Pipe-based, and not PTY-based, tests.
2225
pipe bool
23-
beforeTest func(t *testing.T, conjurrcInTmpDir string)
26+
beforeTest func(t *testing.T, conjurrcInTmpDir string) func()
2427
assert func(t *testing.T, conjurrcInTmpDir string, stdout string)
2528
}{
2629
{
@@ -94,8 +97,9 @@ appliance_url: http://conjur
9497
},
9598
},
9699
pipe: true,
97-
beforeTest: func(t *testing.T, conjurrcInTmpDir string) {
100+
beforeTest: func(t *testing.T, conjurrcInTmpDir string) func() {
98101
os.WriteFile(conjurrcInTmpDir, []byte("something"), 0644)
102+
return nil
99103
},
100104
assert: func(t *testing.T, conjurrcInTmpDir string, stdout string) {
101105
// Assert that file is not overwritten
@@ -113,8 +117,9 @@ appliance_url: http://conjur
113117
},
114118
},
115119
pipe: true,
116-
beforeTest: func(t *testing.T, conjurrcInTmpDir string) {
120+
beforeTest: func(t *testing.T, conjurrcInTmpDir string) func() {
117121
os.WriteFile(conjurrcInTmpDir, []byte("something"), 0644)
122+
return nil
118123
},
119124
assert: func(t *testing.T, conjurrcInTmpDir string, stdout string) {
120125
// Assert that file is overwritten
@@ -142,8 +147,9 @@ credential_storage: file
142147
{
143148
name: "force overwrite",
144149
args: []string{"init", "-u=http://host", "-a=yet-another-test-account", "--force", "-i"},
145-
beforeTest: func(t *testing.T, conjurrcInTmpDir string) {
150+
beforeTest: func(t *testing.T, conjurrcInTmpDir string) func() {
146151
os.WriteFile(conjurrcInTmpDir, []byte("something"), 0644)
152+
return nil
147153
},
148154
assert: func(t *testing.T, conjurrcInTmpDir string, stdout string) {
149155
// Assert that file is overwritten
@@ -205,23 +211,30 @@ appliance_url: http://host
205211
},
206212
{
207213
name: "fails for self-signed certificate",
208-
args: []string{"init", "-u=https://self-signed.badssl.com", "-a=test-account"},
214+
args: []string{"init", "-u=https://localhost:8080", "-a=test-account"},
215+
beforeTest: func(t *testing.T, conjurrcInTmpDir string) func() {
216+
return startSelfSignedServer(t, 8080)
217+
},
209218
assert: func(t *testing.T, conjurrcInTmpDir string, stdout string) {
210219
assert.Contains(t, stdout, "Unable to retrieve and validate certificate")
220+
assert.Contains(t, stdout, "x509")
211221
assert.Contains(t, stdout, "If you're attempting to use a self-signed certificate, re-run the init command with the `--self-signed` flag")
212222
assertFetchCertFailed(t, conjurrcInTmpDir)
213223
},
214224
},
215225
{
216226
name: "succeeds for self-signed certificate with --self-signed flag",
217-
args: []string{"init", "-u=https://self-signed.badssl.com", "-a=test-account", "--self-signed"},
227+
args: []string{"init", "-u=https://localhost:8080", "-a=test-account", "--self-signed"},
218228
promptResponses: []promptResponse{
219229
{
220230
prompt: "Trust this certificate?",
221231
response: "y",
222232
},
223233
},
224234
pipe: true,
235+
beforeTest: func(t *testing.T, conjurrcInTmpDir string) func() {
236+
return startSelfSignedServer(t, 8080)
237+
},
225238
assert: func(t *testing.T, conjurrcInTmpDir string, stdout string) {
226239
assert.Contains(t, stdout, "Warning: Using self-signed certificates is not recommended and could lead to exposure of sensitive data")
227240
assertCertWritten(t, conjurrcInTmpDir, stdout)
@@ -307,7 +320,10 @@ func TestInitCmd(t *testing.T) {
307320
conjurrcInTmpDir := tempDir + "/.conjurrc"
308321

309322
if tc.beforeTest != nil {
310-
tc.beforeTest(t, conjurrcInTmpDir)
323+
cleanup := tc.beforeTest(t, conjurrcInTmpDir)
324+
if cleanup != nil {
325+
defer cleanup()
326+
}
311327
}
312328

313329
// --file default to conjurrcInTmpDir. It can always be overwritten in each test case
@@ -389,3 +405,18 @@ func assertCertWritten(t *testing.T, conjurrcInTmpDir string, stdout string) {
389405
data, _ = os.ReadFile(expectedCertPath)
390406
assert.Contains(t, string(data), "-----BEGIN CERTIFICATE-----")
391407
}
408+
409+
func startSelfSignedServer(t *testing.T, port int) func() {
410+
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
411+
fmt.Fprintln(w, "Hello, client")
412+
}))
413+
l, err := net.Listen("tcp", "localhost:8080")
414+
if err != nil {
415+
assert.NoError(t, err, "unabled to start test server")
416+
}
417+
418+
server.Listener = l
419+
server.StartTLS()
420+
421+
return func() { server.Close() }
422+
}

pkg/utils/tls.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package utils
22

33
import (
4-
"bytes"
54
"crypto/sha1"
65
"crypto/tls"
76
"crypto/x509"
@@ -65,13 +64,6 @@ func GetServerCert(host string, allowSelfSigned bool) (ServerCert, error) {
6564
}
6665

6766
func getSha1Fingerprint(cert []byte) string {
68-
sum := sha1.Sum(cert)
69-
var buf bytes.Buffer
70-
for i, f := range sum {
71-
if i > 0 {
72-
buf.WriteString(":")
73-
}
74-
fmt.Fprintf(&buf, "%02X", f)
75-
}
76-
return buf.String()
67+
sha1sum := sha1.Sum(cert)
68+
return strings.ToUpper(fmt.Sprintf("%x", sha1sum))
7769
}

pkg/utils/tls_test.go

Lines changed: 29 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,36 @@
11
package utils
22

33
import (
4-
"strings"
4+
"fmt"
5+
"net"
6+
"net/http"
7+
"net/http/httptest"
58
"testing"
69

710
"github.com/stretchr/testify/assert"
811
)
912

1013
func TestGetServerCert(t *testing.T) {
11-
// Note: this will change every few years when GitHub renews their TLS certificate
12-
githubFingerprint := "A3:B5:9E:5F:E8:84:EE:1F:34:D9:8E:EF:85:8E:3F:B6:62:AC:10:4A"
13-
githubCert := `-----BEGIN CERTIFICATE-----
14-
MIIFajCCBPGgAwIBAgIQDNCovsYyz+ZF7KCpsIT7HDAKBggqhkjOPQQDAzBWMQsw
15-
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMTAwLgYDVQQDEydEaWdp
16-
Q2VydCBUTFMgSHlicmlkIEVDQyBTSEEzODQgMjAyMCBDQTEwHhcNMjMwMjE0MDAw
17-
MDAwWhcNMjQwMzE0MjM1OTU5WjBmMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs
18-
aWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHVi
19-
LCBJbmMuMRMwEQYDVQQDEwpnaXRodWIuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D
20-
AQcDQgAEo6QDRgPfRlFWy8k5qyLN52xZlnqToPu5QByQMog2xgl2nFD1Vfd2Xmgg
21-
nO4i7YMMFTAQQUReMqyQodWq8uVDs6OCA48wggOLMB8GA1UdIwQYMBaAFAq8CCkX
22-
jKU5bXoOzjPHLrPt+8N6MB0GA1UdDgQWBBTHByd4hfKdM8lMXlZ9XNaOcmfr3jAl
23-
BgNVHREEHjAcggpnaXRodWIuY29tgg53d3cuZ2l0aHViLmNvbTAOBgNVHQ8BAf8E
24-
BAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMIGbBgNVHR8EgZMw
25-
gZAwRqBEoEKGQGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRMU0h5
26-
YnJpZEVDQ1NIQTM4NDIwMjBDQTEtMS5jcmwwRqBEoEKGQGh0dHA6Ly9jcmw0LmRp
27-
Z2ljZXJ0LmNvbS9EaWdpQ2VydFRMU0h5YnJpZEVDQ1NIQTM4NDIwMjBDQTEtMS5j
28-
cmwwPgYDVR0gBDcwNTAzBgZngQwBAgIwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3
29-
dy5kaWdpY2VydC5jb20vQ1BTMIGFBggrBgEFBQcBAQR5MHcwJAYIKwYBBQUHMAGG
30-
GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBPBggrBgEFBQcwAoZDaHR0cDovL2Nh
31-
Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTSHlicmlkRUNDU0hBMzg0MjAy
32-
MENBMS0xLmNydDAJBgNVHRMEAjAAMIIBgAYKKwYBBAHWeQIEAgSCAXAEggFsAWoA
33-
dwDuzdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYZQ3Rv6AAAEAwBI
34-
MEYCIQDkFq7T4iy6gp+pefJLxpRS7U3gh8xQymmxtI8FdzqU6wIhALWfw/nLD63Q
35-
YPIwG3EFchINvWUfB6mcU0t2lRIEpr8uAHYASLDja9qmRzQP5WoC+p0w6xxSActW
36-
3SyB2bu/qznYhHMAAAGGUN0cKwAABAMARzBFAiAePGAyfiBR9dbhr31N9ZfESC5G
37-
V2uGBTcyTyUENrH3twIhAPwJfsB8A4MmNr2nW+sdE1n2YiCObW+3DTHr2/UR7lvU
38-
AHcAO1N3dT4tuYBOizBbBv5AO2fYT8P0x70ADS1yb+H61BcAAAGGUN0cOgAABAMA
39-
SDBGAiEAzOBr9OZ0+6OSZyFTiywN64PysN0FLeLRyL5jmEsYrDYCIQDu0jtgWiMI
40-
KU6CM0dKcqUWLkaFE23c2iWAhYAHqrFRRzAKBggqhkjOPQQDAwNnADBkAjAE3A3U
41-
3jSZCpwfqOHBdlxi9ASgKTU+wg0qw3FqtfQ31OwLYFdxh0MlNk/HwkjRSWgCMFbQ
42-
vMkXEPvNvv4t30K6xtpG26qmZ+6OiISBIIXMljWnsiYR1gyZnTzIg3AQSw4Vmw==
43-
-----END CERTIFICATE-----`
44-
45-
// Note: this will change whenever certs are renewed for self-signed.badssl.com
46-
selfSignedFingerprint := "42:B0:D7:0D:41:C3:7C:E7:09:9F:55:97:56:BC:51:E5:D0:34:24:51"
47-
48-
t.Run("Returns the right certificate from github.com", func(t *testing.T) {
49-
cert, err := GetServerCert("github.com", false)
50-
assert.NoError(t, err)
51-
52-
assert.Equal(t, githubCert, strings.TrimSpace(cert.Cert))
53-
assert.Equal(t, githubFingerprint, cert.Fingerprint)
54-
})
55-
56-
t.Run("Returns the right certificate from github.com:443", func(t *testing.T) {
57-
cert, err := GetServerCert("github.com:443", false)
58-
assert.NoError(t, err)
59-
60-
assert.Equal(t, githubCert, strings.TrimSpace(cert.Cert))
61-
assert.Equal(t, githubFingerprint, cert.Fingerprint)
62-
})
63-
64-
t.Run("Returns the right certificate from github.com when self-signed is allowed", func(t *testing.T) {
65-
// Ensure that allowing self-signed certs doesn't break support for normal certs
66-
cert, err := GetServerCert("github.com", true)
67-
assert.NoError(t, err)
68-
69-
assert.Equal(t, githubCert, strings.TrimSpace(cert.Cert))
70-
assert.Equal(t, githubFingerprint, cert.Fingerprint)
71-
})
72-
7314
t.Run("Returns an error when the server doesn't exist", func(t *testing.T) {
7415
_, err := GetServerCert("example.com:444", false)
7516
assert.Error(t, err)
7617
})
7718

7819
t.Run("Returns an error for self-signed certificates", func(t *testing.T) {
79-
_, err := GetServerCert("self-signed.badssl.com", false)
20+
server := startSelfSignedServer(t, 8080)
21+
defer server.Close()
22+
23+
_, err := GetServerCert("localhost:8080", false)
8024
assert.Error(t, err)
8125
})
8226

8327
t.Run("Returns the right certificate for self-signed certificates when allowed", func(t *testing.T) {
84-
cert, err := GetServerCert("self-signed.badssl.com", true)
28+
server := startSelfSignedServer(t, 8080)
29+
defer server.Close()
30+
31+
selfSignedFingerprint := getSha1Fingerprint(server.Certificate().Raw)
32+
33+
cert, err := GetServerCert("localhost:8080", true)
8534
assert.NoError(t, err)
8635

8736
assert.Equal(t, selfSignedFingerprint, cert.Fingerprint)
@@ -97,3 +46,18 @@ vMkXEPvNvv4t30K6xtpG26qmZ+6OiISBIIXMljWnsiYR1gyZnTzIg3AQSw4Vmw==
9746
assert.Error(t, err)
9847
})
9948
}
49+
50+
func startSelfSignedServer(t *testing.T, port int) *httptest.Server {
51+
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
52+
fmt.Fprintln(w, "Hello, client")
53+
}))
54+
l, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
55+
if err != nil {
56+
assert.NoError(t, err, "unabled to start test server")
57+
}
58+
59+
server.Listener = l
60+
server.StartTLS()
61+
62+
return server
63+
}

0 commit comments

Comments
 (0)