Source file
src/crypto/tls/bogo_shim_test.go
1 package tls
2
3 import (
4 "crypto/x509"
5 "encoding/binary"
6 "encoding/json"
7 "encoding/pem"
8 "flag"
9 "fmt"
10 "internal/testenv"
11 "io"
12 "log"
13 "net"
14 "os"
15 "os/exec"
16 "path/filepath"
17 "runtime"
18 "testing"
19 )
20
21 var (
22 port = flag.String("port", "", "")
23 server = flag.Bool("server", false, "")
24
25 isHandshakerSupported = flag.Bool("is-handshaker-supported", false, "")
26
27 keyfile = flag.String("key-file", "", "")
28 certfile = flag.String("cert-file", "", "")
29
30 trustCert = flag.String("trust-cert", "", "")
31
32 minVersion = flag.Int("min-version", VersionSSL30, "")
33 maxVersion = flag.Int("max-version", VersionTLS13, "")
34
35 noTLS13 = flag.Bool("no-tls13", false, "")
36
37 requireAnyClientCertificate = flag.Bool("require-any-client-certificate", false, "")
38
39 shimWritesFirst = flag.Bool("shim-writes-first", false, "")
40
41 resumeCount = flag.Int("resume-count", 0, "")
42
43 shimID = flag.Uint64("shim-id", 0, "")
44 _ = flag.Bool("ipv6", false, "")
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 func bogoShim() {
136 if *isHandshakerSupported {
137 fmt.Println("No")
138 return
139 }
140
141 cfg := &Config{
142 ServerName: "test",
143
144 MinVersion: uint16(*minVersion),
145 MaxVersion: uint16(*maxVersion),
146
147 ClientSessionCache: NewLRUClientSessionCache(0),
148 }
149
150 if *noTLS13 && cfg.MaxVersion == VersionTLS13 {
151 cfg.MaxVersion = VersionTLS12
152 }
153
154 if *keyfile != "" || *certfile != "" {
155 pair, err := LoadX509KeyPair(*certfile, *keyfile)
156 if err != nil {
157 log.Fatalf("load key-file err: %s", err)
158 }
159 cfg.Certificates = []Certificate{pair}
160 }
161 if *trustCert != "" {
162 pool := x509.NewCertPool()
163 certFile, err := os.ReadFile(*trustCert)
164 if err != nil {
165 log.Fatalf("load trust-cert err: %s", err)
166 }
167 block, _ := pem.Decode(certFile)
168 cert, err := x509.ParseCertificate(block.Bytes)
169 if err != nil {
170 log.Fatalf("parse trust-cert err: %s", err)
171 }
172 pool.AddCert(cert)
173 cfg.RootCAs = pool
174 }
175
176 if *requireAnyClientCertificate {
177 cfg.ClientAuth = RequireAnyClientCert
178 }
179
180 for i := 0; i < *resumeCount+1; i++ {
181 conn, err := net.Dial("tcp", net.JoinHostPort("localhost", *port))
182 if err != nil {
183 log.Fatalf("dial err: %s", err)
184 }
185 defer conn.Close()
186
187
188 shimIDBytes := make([]byte, 8)
189 binary.LittleEndian.PutUint64(shimIDBytes, *shimID)
190 if _, err := conn.Write(shimIDBytes); err != nil {
191 log.Fatalf("failed to write shim id: %s", err)
192 }
193
194 var tlsConn *Conn
195 if *server {
196 tlsConn = Server(conn, cfg)
197 } else {
198 tlsConn = Client(conn, cfg)
199 }
200
201 if *shimWritesFirst {
202 if _, err := tlsConn.Write([]byte("hello")); err != nil {
203 log.Fatalf("write err: %s", err)
204 }
205 }
206
207 for {
208 buf := make([]byte, 500)
209 n, err := tlsConn.Read(buf)
210 if err == io.EOF {
211 break
212 }
213 if err != nil {
214 log.Fatalf("read err: %s", err)
215 }
216 buf = buf[:n]
217 for i := range buf {
218 buf[i] ^= 0xff
219 }
220 if _, err := tlsConn.Write(buf); err != nil {
221 log.Fatalf("write err: %s", err)
222 }
223 }
224 }
225 }
226
227 func TestBogoSuite(t *testing.T) {
228 testenv.SkipIfShortAndSlow(t)
229 testenv.MustHaveExternalNetwork(t)
230 testenv.MustHaveGoRun(t)
231 testenv.MustHaveExec(t)
232
233 if testing.Short() {
234 t.Skip("skipping in short mode")
235 }
236
237 if testenv.Builder() != "" && runtime.GOOS == "windows" {
238 t.Skip("#66913: windows network connections are flakey on builders")
239 }
240
241 const boringsslModVer = "v0.0.0-20240412155355-1c6e10495e4f"
242 output, err := exec.Command("go", "mod", "download", "-json", "github.com/google/boringssl@"+boringsslModVer).CombinedOutput()
243 if err != nil {
244 t.Fatalf("failed to download boringssl: %s", err)
245 }
246 var j struct {
247 Dir string
248 }
249 if err := json.Unmarshal(output, &j); err != nil {
250 t.Fatalf("failed to parse 'go mod download' output: %s", err)
251 }
252
253 cwd, err := os.Getwd()
254 if err != nil {
255 t.Fatal(err)
256 }
257
258 args := []string{
259 "test",
260 ".",
261 fmt.Sprintf("-shim-config=%s", filepath.Join(cwd, "bogo_config.json")),
262 fmt.Sprintf("-shim-path=%s", os.Args[0]),
263 "-shim-extra-flags=-bogo-mode",
264 "-allow-unimplemented",
265 "-loose-errors",
266 }
267 if *bogoFilter != "" {
268 args = append(args, fmt.Sprintf("-test=%s", *bogoFilter))
269 }
270
271 goCmd, err := testenv.GoTool()
272 if err != nil {
273 t.Fatal(err)
274 }
275 cmd := exec.Command(goCmd, args...)
276 cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
277 cmd.Dir = filepath.Join(j.Dir, "ssl/test/runner")
278 err = cmd.Run()
279 if err != nil {
280 t.Fatalf("bogo failed: %s", err)
281 }
282 }
283
View as plain text