forked from mediocregopher/radix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tls_test.go
182 lines (161 loc) · 5.71 KB
/
tls_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package radix
import (
"crypto/tls"
"net"
"strings"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDialUseTLS(t *testing.T) {
// In order to test a TLS connection we need to start a TLS terminating proxy
// Both the key and the certificate were generated by running the following command:
// go run $GOROOT/src/crypto/tls/generate_cert.go --host localhost
// This function is used to avoid static code analysis from identifying the private key
testingKey := func(s string) string { return strings.Replace(s, "TESTING KEY", "PRIVATE KEY", 2) }
var rsaCertPEM = `-----BEGIN CERTIFICATE-----
MIIC+TCCAeGgAwIBAgIQJ0gZjEJuKoZtra6oAYs54zANBgkqhkiG9w0BAQsFADAS
MRAwDgYDVQQKEwdBY21lIENvMB4XDTE5MDkxMjE5MzAyN1oXDTIwMDkxMTE5MzAy
N1owEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAOSDBT4IYzLU1lAbLMU+JmkiZilfkJ+/iUEoSz2jTVyyntY6+r2x2Sfc
HVVKTo08qGsNdgSr09GPBHytWBWXbgH1h4ipnRt8iBtDPFzmqMlK/SVn2fFwlkl4
XqDJSQzeuK2LrbjaiI7TFNJ7mwGDgOIsqi/8am2Te/sQGmZomkR6Pysr92jbZLEm
zxEvv7vQjknNVbRsotincEVtkhT3vAstl1YZPOflsP6J0XtmOXst9WhE96U2Lsh5
cJK1Xi8y1q2u4yScljhrnsURHQKoF0WXyT+5vo1NcZsECscsjiVqqXUdwX91J753
UAM/r75Zc8lMyfU7QPQIafebT4rk1hMCAwEAAaNLMEkwDgYDVR0PAQH/BAQDAgWg
MBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFAYDVR0RBA0wC4IJ
bG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQBZf1tHwem38Cp4tTUyhBV849fz
GVs1FlDLX11PRF9TaAyQf4QKpWDXQV9baQF90krwBDTMjb8f5pVfI1uaEFu3zQZ7
DFNnw628wzGOKPr0fivXaycN3Gt0Qs9UvM5uiI+cNU4tKofd1dkVrnPzJXYaTbAn
lJf4OgVAHa6RtNpZXicARXb+jqKiMOWZH8A3Tj1jQIXgv+orW3ha1R2y2HzZEbnj
NyklAu0YelMXI5nbkptdXBsWVMU/2z/d00AEQRlQoDRXamE0FCURL+J1odzifk80
PdMm11Wq+2LeY0h/4SGwP+cmpNMOV5bMvHBohmGxMZMVISyvSuw7JMMcydR4
-----END CERTIFICATE-----
`
var rsaKeyPEM = testingKey(`-----BEGIN TESTING KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDkgwU+CGMy1NZQ
GyzFPiZpImYpX5Cfv4lBKEs9o01csp7WOvq9sdkn3B1VSk6NPKhrDXYEq9PRjwR8
rVgVl24B9YeIqZ0bfIgbQzxc5qjJSv0lZ9nxcJZJeF6gyUkM3riti6242oiO0xTS
e5sBg4DiLKov/Gptk3v7EBpmaJpEej8rK/do22SxJs8RL7+70I5JzVW0bKLYp3BF
bZIU97wLLZdWGTzn5bD+idF7Zjl7LfVoRPelNi7IeXCStV4vMtatruMknJY4a57F
ER0CqBdFl8k/ub6NTXGbBArHLI4laql1HcF/dSe+d1ADP6++WXPJTMn1O0D0CGn3
m0+K5NYTAgMBAAECggEABdx6ePHcIYSmDp3z0wdaEt5IAo2p9v8BtUMkUutqY5NN
Ua9nmRADwur5caObSjIhG8XXnh0OLNTfR5dmp/8fWjuDA3VeS0MxdomN9dAQykD7
J0d3pqK9qBrHSpZ/Ii5gTEtF5HTuhcNSSGfVPP+zgZmlr99ol3DuAC2Uj8XlFxaD
NNhgLsB5v3vPGSqiW7joKRaSa2OGqbXdOz6dTWkS0PWYXGSfIMI4Js4EmU7sqi6w
aVG25XWjiQ57VNH2ZoE0rY3yVbWH5CJ2CD58jIO/LpWfWCXvwGMRHNl6GN0cSv/h
g+BBsTz2VzvoN6/ZvdxccQ63KBDpb0/Ovd2Ri/kjYQKBgQDkmSsUBrOjHWCSZqpg
BIdcFGYBjTFCm4JXrBBZsEHjxBqKXKcCY5DkwW580Yug/Vmn8j2bJgJ3mbYccPqB
WkjrnnjS+lhe9ciNNdA/YqmN0ONlyEvEtb1fOOilZDq+SPrVnaQ8xT/+UCfWnbQI
NNySy4rlMERAcv2G0z9EmqK6AwKBgQD/5zKH1mekV/3i+IjL8KizMwH6ddJwpnMT
3Iwx11PjPM7tmrlrzRK3rQOqDHVTo9kV37L1rKfC9JXjFhxydj/IOLD6cKUiJJUI
UJVEHb21HNzommnhHyq5AGYtv6hiWPvbMEtws7Y3QmnAbP9UbjZSiTs8hZoHUrWY
uMub1hy+sQKBgDiaxNP8pNarG5Kk4WNNO8dNNcUElUINB8V10cajom0nzfqc3q30
wZgjXZyCtrRyh5TSovab/thms3VvdFg7ZvsRDpIPc3pwGez9ekd3wsxfAS/e3QQk
jHPbv5/UpccggxwKIPT7UtFCP9sgyceOb1/aDtaZkQz0bFrKTExMjibJAoGAE7ID
nZjO2UM8cx+Vx7x5/3DJkjFHRQxKhxjOYXelKTQg6QCjjLx32FMkmQ3kac+OgbR5
3ZawQrz4XEXzYovfVNWoKV5KF1qhbcZl9pwjYbEa/3wC8iSn8R0qwBKkLw2SNMh+
xenO+GnQIdNBw4nH/Io7WOkfdbjT6TEv2oqcI8ECgYBIppEhekL3lzN5qNqUqaQS
64gtm/esLUQLkXFmrv/KZ/QMhOtGNb2Hipc1KOomMTm5zJf2gRMZice97EoBpIiq
/syezw2OV/TjSCLzFrikz8W/lHkpbzwk71s1f0FKMIK863lB4fqj5bCXMXGyiXUt
Baas4jyR6hQ0qRSe4PmQrA==
-----END TESTING KEY-----
`)
pem := []byte(rsaCertPEM + rsaKeyPEM)
cert, err := tls.X509KeyPair(pem, pem)
require.NoError(t, err)
// The following TLS proxy is based on https://gist.github.com/cs8425/a742349a55596f1b251a#file-tls2tcp_server-go
listener, err := tls.Listen("tcp", ":63790", &tls.Config{
Certificates: []tls.Certificate{cert},
})
require.NoError(t, err)
// Used to prevent a race during shutdown failing the test
m := sync.Mutex{}
shuttingDown := false
defer func() {
m.Lock()
shuttingDown = true
m.Unlock()
listener.Close()
}()
// Dials 127.0.0.1:6379 and proxies traffic
proxyConnection := func(lConn net.Conn) {
defer lConn.Close()
rConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
IP: net.IPv4(127, 0, 0, 1),
Port: 6379,
})
require.NoError(t, err)
defer rConn.Close()
chanFromConn := func(conn net.Conn) chan []byte {
c := make(chan []byte)
go func() {
b := make([]byte, 1024)
for {
n, err := conn.Read(b)
if n > 0 {
res := make([]byte, n)
// Copy the buffer so it doesn't get changed while read by the recipient.
copy(res, b[:n])
c <- res
}
if err != nil {
c <- nil
break
}
}
}()
return c
}
lChan := chanFromConn(lConn)
rChan := chanFromConn(rConn)
for {
select {
case b1 := <-lChan:
if b1 == nil {
return
}
_, err = rConn.Write(b1)
require.NoError(t, err)
case b2 := <-rChan:
if b2 == nil {
return
}
_, err = lConn.Write(b2)
require.NoError(t, err)
}
}
}
// Accept new connections
go func() {
for {
lConn, err := listener.Accept()
if err != nil {
// Accept unblocks and returns an error after Shutdown is called on listener
m.Lock()
defer m.Unlock()
if shuttingDown {
// Exit
break
} else {
require.NoError(t, err)
}
}
go proxyConnection(lConn)
}
}()
// Connect to the proxy, passing in an insecure flag as we are self-signed
c, err := Dial("tcp", "127.0.0.1:63790", DialUseTLS(&tls.Config{
InsecureSkipVerify: true,
}))
if err != nil {
t.Fatal(err)
} else if err := c.Do(Cmd(nil, "PING")); err != nil {
t.Fatal(err)
}
// Confirm that the connection fails if verifying certificate
_, err = Dial("tcp", "127.0.0.1:63790", DialUseTLS(nil), DialConnectTimeout(60*time.Minute))
assert.Error(t, err)
}