| package tls |
| |
| import ( |
| "crypto/x509" |
| "encoding/binary" |
| "encoding/json" |
| "encoding/pem" |
| "flag" |
| "fmt" |
| "internal/testenv" |
| "io" |
| "log" |
| "net" |
| "os" |
| "os/exec" |
| "path/filepath" |
| "runtime" |
| "testing" |
| ) |
| |
| var ( |
| port = flag.String("port", "", "") |
| server = flag.Bool("server", false, "") |
| |
| isHandshakerSupported = flag.Bool("is-handshaker-supported", false, "") |
| |
| keyfile = flag.String("key-file", "", "") |
| certfile = flag.String("cert-file", "", "") |
| |
| trustCert = flag.String("trust-cert", "", "") |
| |
| minVersion = flag.Int("min-version", VersionSSL30, "") |
| maxVersion = flag.Int("max-version", VersionTLS13, "") |
| |
| noTLS13 = flag.Bool("no-tls13", false, "") |
| |
| requireAnyClientCertificate = flag.Bool("require-any-client-certificate", false, "") |
| |
| shimWritesFirst = flag.Bool("shim-writes-first", false, "") |
| |
| resumeCount = flag.Int("resume-count", 0, "") |
| |
| shimID = flag.Uint64("shim-id", 0, "") |
| _ = flag.Bool("ipv6", false, "") |
| |
| // Unimplemented flags |
| // -advertise-alpn |
| // -advertise-npn |
| // -allow-hint-mismatch |
| // -async |
| // -check-close-notify |
| // -cipher |
| // -curves |
| // -delegated-credential |
| // -dtls |
| // -ech-config-list |
| // -ech-server-config |
| // -enable-channel-id |
| // -enable-early-data |
| // -enable-ech-grease |
| // -enable-grease |
| // -enable-ocsp-stapling |
| // -enable-signed-cert-timestamps |
| // -expect-advertised-alpn |
| // -expect-certificate-types |
| // -expect-channel-id |
| // -expect-cipher-aes |
| // -expect-client-ca-list |
| // -expect-curve-id |
| // -expect-early-data-reason |
| // -expect-extended-master-secret |
| // -expect-hrr |
| // -expect-key-usage-invalid |
| // -expect-msg-callback |
| // -expect-no-session |
| // -expect-peer-cert-file |
| // -expect-peer-signature-algorithm |
| // -expect-peer-verify-pref |
| // -expect-secure-renegotiation |
| // -expect-server-name |
| // -expect-ticket-supports-early-data |
| // -export-keying-material |
| // -export-traffic-secrets |
| // -fail-cert-callback |
| // -fail-early-callback |
| // -fallback-scsv |
| // -false-start |
| // -forbid-renegotiation-after-handshake |
| // -handshake-twice |
| // -host-name |
| // -ignore-rsa-key-usage |
| // -implicit-handshake |
| // -install-cert-compression-algs |
| // -install-ddos-callback |
| // -install-one-cert-compression-alg |
| // -jdk11-workaround |
| // -key-update |
| // -max-cert-list |
| // -max-send-fragment |
| // -no-ticket |
| // -no-tls1 |
| // -no-tls11 |
| // -no-tls12 |
| // -ocsp-response |
| // -on-resume-expect-accept-early-data |
| // -on-resume-expect-reject-early-data |
| // -on-shim-cipher |
| // -on-shim-curves |
| // -peek-then-read |
| // -psk |
| // -read-with-unfinished-write |
| // -reject-alpn |
| // -renegotiate-explicit |
| // -renegotiate-freely |
| // -renegotiate-ignore |
| // -renegotiate-once |
| // -select-alpn |
| // -select-next-proto |
| // -send-alert |
| // -send-channel-id |
| // -server-preference |
| // -shim-shuts-down |
| // -signed-cert-timestamps |
| // -signing-prefs |
| // -srtp-profiles |
| // -tls-unique |
| // -use-client-ca-list |
| // -use-ocsp-callback |
| // -use-old-client-cert-callback |
| // -verify-fail |
| // -verify-peer |
| // -verify-prefs |
| ) |
| |
| func bogoShim() { |
| if *isHandshakerSupported { |
| fmt.Println("No") |
| return |
| } |
| |
| cfg := &Config{ |
| ServerName: "test", |
| |
| MinVersion: uint16(*minVersion), |
| MaxVersion: uint16(*maxVersion), |
| |
| ClientSessionCache: NewLRUClientSessionCache(0), |
| } |
| |
| if *noTLS13 && cfg.MaxVersion == VersionTLS13 { |
| cfg.MaxVersion = VersionTLS12 |
| } |
| |
| if *keyfile != "" || *certfile != "" { |
| pair, err := LoadX509KeyPair(*certfile, *keyfile) |
| if err != nil { |
| log.Fatalf("load key-file err: %s", err) |
| } |
| cfg.Certificates = []Certificate{pair} |
| } |
| if *trustCert != "" { |
| pool := x509.NewCertPool() |
| certFile, err := os.ReadFile(*trustCert) |
| if err != nil { |
| log.Fatalf("load trust-cert err: %s", err) |
| } |
| block, _ := pem.Decode(certFile) |
| cert, err := x509.ParseCertificate(block.Bytes) |
| if err != nil { |
| log.Fatalf("parse trust-cert err: %s", err) |
| } |
| pool.AddCert(cert) |
| cfg.RootCAs = pool |
| } |
| |
| if *requireAnyClientCertificate { |
| cfg.ClientAuth = RequireAnyClientCert |
| } |
| |
| for i := 0; i < *resumeCount+1; i++ { |
| conn, err := net.Dial("tcp", net.JoinHostPort("localhost", *port)) |
| if err != nil { |
| log.Fatalf("dial err: %s", err) |
| } |
| defer conn.Close() |
| |
| // Write the shim ID we were passed as a little endian uint64 |
| shimIDBytes := make([]byte, 8) |
| binary.LittleEndian.PutUint64(shimIDBytes, *shimID) |
| if _, err := conn.Write(shimIDBytes); err != nil { |
| log.Fatalf("failed to write shim id: %s", err) |
| } |
| |
| var tlsConn *Conn |
| if *server { |
| tlsConn = Server(conn, cfg) |
| } else { |
| tlsConn = Client(conn, cfg) |
| } |
| |
| if *shimWritesFirst { |
| if _, err := tlsConn.Write([]byte("hello")); err != nil { |
| log.Fatalf("write err: %s", err) |
| } |
| } |
| |
| for { |
| buf := make([]byte, 500) |
| n, err := tlsConn.Read(buf) |
| if err == io.EOF { |
| break |
| } |
| if err != nil { |
| log.Fatalf("read err: %s", err) |
| } |
| buf = buf[:n] |
| for i := range buf { |
| buf[i] ^= 0xff |
| } |
| if _, err := tlsConn.Write(buf); err != nil { |
| log.Fatalf("write err: %s", err) |
| } |
| } |
| } |
| } |
| |
| func TestBogoSuite(t *testing.T) { |
| testenv.SkipIfShortAndSlow(t) |
| testenv.MustHaveExternalNetwork(t) |
| testenv.MustHaveGoRun(t) |
| testenv.MustHaveExec(t) |
| |
| if testing.Short() { |
| t.Skip("skipping in short mode") |
| } |
| |
| if testenv.Builder() != "" && runtime.GOOS == "windows" { |
| t.Skip("#66913: windows network connections are flakey on builders") |
| } |
| |
| const boringsslModVer = "v0.0.0-20240412155355-1c6e10495e4f" |
| output, err := exec.Command("go", "mod", "download", "-json", "github.com/google/boringssl@"+boringsslModVer).CombinedOutput() |
| if err != nil { |
| t.Fatalf("failed to download boringssl: %s", err) |
| } |
| var j struct { |
| Dir string |
| } |
| if err := json.Unmarshal(output, &j); err != nil { |
| t.Fatalf("failed to parse 'go mod download' output: %s", err) |
| } |
| |
| cwd, err := os.Getwd() |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| args := []string{ |
| "test", |
| ".", |
| fmt.Sprintf("-shim-config=%s", filepath.Join(cwd, "bogo_config.json")), |
| fmt.Sprintf("-shim-path=%s", os.Args[0]), |
| "-shim-extra-flags=-bogo-mode", |
| "-allow-unimplemented", |
| "-loose-errors", // TODO(roland): this should be removed eventually |
| } |
| if *bogoFilter != "" { |
| args = append(args, fmt.Sprintf("-test=%s", *bogoFilter)) |
| } |
| |
| goCmd, err := testenv.GoTool() |
| if err != nil { |
| t.Fatal(err) |
| } |
| cmd := exec.Command(goCmd, args...) |
| cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr |
| cmd.Dir = filepath.Join(j.Dir, "ssl/test/runner") |
| err = cmd.Run() |
| if err != nil { |
| t.Fatalf("bogo failed: %s", err) |
| } |
| } |