1*cc02d7e2SAndroid Build Coastguard Worker// Copyright 2019 The gRPC Authors 2*cc02d7e2SAndroid Build Coastguard Worker// 3*cc02d7e2SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*cc02d7e2SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*cc02d7e2SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*cc02d7e2SAndroid Build Coastguard Worker// 7*cc02d7e2SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*cc02d7e2SAndroid Build Coastguard Worker// 9*cc02d7e2SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*cc02d7e2SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*cc02d7e2SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*cc02d7e2SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*cc02d7e2SAndroid Build Coastguard Worker// limitations under the License. 14*cc02d7e2SAndroid Build Coastguard Worker 15*cc02d7e2SAndroid Build Coastguard Workerpackage http2interop 16*cc02d7e2SAndroid Build Coastguard Worker 17*cc02d7e2SAndroid Build Coastguard Workerimport ( 18*cc02d7e2SAndroid Build Coastguard Worker "crypto/tls" 19*cc02d7e2SAndroid Build Coastguard Worker "crypto/x509" 20*cc02d7e2SAndroid Build Coastguard Worker "encoding/json" 21*cc02d7e2SAndroid Build Coastguard Worker "flag" 22*cc02d7e2SAndroid Build Coastguard Worker "fmt" 23*cc02d7e2SAndroid Build Coastguard Worker "io/ioutil" 24*cc02d7e2SAndroid Build Coastguard Worker "os" 25*cc02d7e2SAndroid Build Coastguard Worker "strconv" 26*cc02d7e2SAndroid Build Coastguard Worker "strings" 27*cc02d7e2SAndroid Build Coastguard Worker "testing" 28*cc02d7e2SAndroid Build Coastguard Worker) 29*cc02d7e2SAndroid Build Coastguard Worker 30*cc02d7e2SAndroid Build Coastguard Workervar ( 31*cc02d7e2SAndroid Build Coastguard Worker serverHost = flag.String("server_host", "", "The host to test") 32*cc02d7e2SAndroid Build Coastguard Worker serverPort = flag.Int("server_port", 443, "The port to test") 33*cc02d7e2SAndroid Build Coastguard Worker useTls = flag.Bool("use_tls", true, "Should TLS tests be run") 34*cc02d7e2SAndroid Build Coastguard Worker testCase = flag.String("test_case", "", "What test cases to run (tls, framing)") 35*cc02d7e2SAndroid Build Coastguard Worker 36*cc02d7e2SAndroid Build Coastguard Worker // The rest of these are unused, but present to fulfill the client interface 37*cc02d7e2SAndroid Build Coastguard Worker serverHostOverride = flag.String("server_host_override", "", "Unused") 38*cc02d7e2SAndroid Build Coastguard Worker useTestCa = flag.Bool("use_test_ca", false, "Unused") 39*cc02d7e2SAndroid Build Coastguard Worker defaultServiceAccount = flag.String("default_service_account", "", "Unused") 40*cc02d7e2SAndroid Build Coastguard Worker oauthScope = flag.String("oauth_scope", "", "Unused") 41*cc02d7e2SAndroid Build Coastguard Worker serviceAccountKeyFile = flag.String("service_account_key_file", "", "Unused") 42*cc02d7e2SAndroid Build Coastguard Worker) 43*cc02d7e2SAndroid Build Coastguard Worker 44*cc02d7e2SAndroid Build Coastguard Workerfunc InteropCtx(t *testing.T) *HTTP2InteropCtx { 45*cc02d7e2SAndroid Build Coastguard Worker ctx := &HTTP2InteropCtx{ 46*cc02d7e2SAndroid Build Coastguard Worker ServerHost: *serverHost, 47*cc02d7e2SAndroid Build Coastguard Worker ServerPort: *serverPort, 48*cc02d7e2SAndroid Build Coastguard Worker ServerHostnameOverride: *serverHostOverride, 49*cc02d7e2SAndroid Build Coastguard Worker UseTLS: *useTls, 50*cc02d7e2SAndroid Build Coastguard Worker UseTestCa: *useTestCa, 51*cc02d7e2SAndroid Build Coastguard Worker T: t, 52*cc02d7e2SAndroid Build Coastguard Worker } 53*cc02d7e2SAndroid Build Coastguard Worker 54*cc02d7e2SAndroid Build Coastguard Worker ctx.serverSpec = ctx.ServerHost 55*cc02d7e2SAndroid Build Coastguard Worker if ctx.ServerPort != -1 { 56*cc02d7e2SAndroid Build Coastguard Worker ctx.serverSpec += ":" + strconv.Itoa(ctx.ServerPort) 57*cc02d7e2SAndroid Build Coastguard Worker } 58*cc02d7e2SAndroid Build Coastguard Worker if ctx.ServerHostnameOverride == "" { 59*cc02d7e2SAndroid Build Coastguard Worker ctx.authority = ctx.ServerHost 60*cc02d7e2SAndroid Build Coastguard Worker } else { 61*cc02d7e2SAndroid Build Coastguard Worker ctx.authority = ctx.ServerHostnameOverride 62*cc02d7e2SAndroid Build Coastguard Worker } 63*cc02d7e2SAndroid Build Coastguard Worker 64*cc02d7e2SAndroid Build Coastguard Worker if ctx.UseTestCa { 65*cc02d7e2SAndroid Build Coastguard Worker // It would be odd if useTestCa was true, but not useTls. meh 66*cc02d7e2SAndroid Build Coastguard Worker certData, err := ioutil.ReadFile("src/core/tsi/test_creds/ca.pem") 67*cc02d7e2SAndroid Build Coastguard Worker if err != nil { 68*cc02d7e2SAndroid Build Coastguard Worker t.Fatal(err) 69*cc02d7e2SAndroid Build Coastguard Worker } 70*cc02d7e2SAndroid Build Coastguard Worker 71*cc02d7e2SAndroid Build Coastguard Worker ctx.rootCAs = x509.NewCertPool() 72*cc02d7e2SAndroid Build Coastguard Worker if !ctx.rootCAs.AppendCertsFromPEM(certData) { 73*cc02d7e2SAndroid Build Coastguard Worker t.Fatal(fmt.Errorf("Unable to parse pem data")) 74*cc02d7e2SAndroid Build Coastguard Worker } 75*cc02d7e2SAndroid Build Coastguard Worker } 76*cc02d7e2SAndroid Build Coastguard Worker 77*cc02d7e2SAndroid Build Coastguard Worker return ctx 78*cc02d7e2SAndroid Build Coastguard Worker} 79*cc02d7e2SAndroid Build Coastguard Worker 80*cc02d7e2SAndroid Build Coastguard Workerfunc (ctx *HTTP2InteropCtx) Close() error { 81*cc02d7e2SAndroid Build Coastguard Worker // currently a noop 82*cc02d7e2SAndroid Build Coastguard Worker return nil 83*cc02d7e2SAndroid Build Coastguard Worker} 84*cc02d7e2SAndroid Build Coastguard Worker 85*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonClientShortSettings(t *testing.T) { 86*cc02d7e2SAndroid Build Coastguard Worker defer Report(t) 87*cc02d7e2SAndroid Build Coastguard Worker if *testCase != "framing" { 88*cc02d7e2SAndroid Build Coastguard Worker t.SkipNow() 89*cc02d7e2SAndroid Build Coastguard Worker } 90*cc02d7e2SAndroid Build Coastguard Worker ctx := InteropCtx(t) 91*cc02d7e2SAndroid Build Coastguard Worker for i := 1; i <= 5; i++ { 92*cc02d7e2SAndroid Build Coastguard Worker err := testClientShortSettings(ctx, i) 93*cc02d7e2SAndroid Build Coastguard Worker matchError(t, err, "EOF") 94*cc02d7e2SAndroid Build Coastguard Worker } 95*cc02d7e2SAndroid Build Coastguard Worker} 96*cc02d7e2SAndroid Build Coastguard Worker 97*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonShortPreface(t *testing.T) { 98*cc02d7e2SAndroid Build Coastguard Worker defer Report(t) 99*cc02d7e2SAndroid Build Coastguard Worker if *testCase != "framing" { 100*cc02d7e2SAndroid Build Coastguard Worker t.SkipNow() 101*cc02d7e2SAndroid Build Coastguard Worker } 102*cc02d7e2SAndroid Build Coastguard Worker ctx := InteropCtx(t) 103*cc02d7e2SAndroid Build Coastguard Worker for i := 0; i < len(Preface)-1; i++ { 104*cc02d7e2SAndroid Build Coastguard Worker err := testShortPreface(ctx, Preface[:i]+"X") 105*cc02d7e2SAndroid Build Coastguard Worker matchError(t, err, "EOF") 106*cc02d7e2SAndroid Build Coastguard Worker } 107*cc02d7e2SAndroid Build Coastguard Worker} 108*cc02d7e2SAndroid Build Coastguard Worker 109*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonUnknownFrameType(t *testing.T) { 110*cc02d7e2SAndroid Build Coastguard Worker defer Report(t) 111*cc02d7e2SAndroid Build Coastguard Worker if *testCase != "framing" { 112*cc02d7e2SAndroid Build Coastguard Worker t.SkipNow() 113*cc02d7e2SAndroid Build Coastguard Worker } 114*cc02d7e2SAndroid Build Coastguard Worker ctx := InteropCtx(t) 115*cc02d7e2SAndroid Build Coastguard Worker if err := testUnknownFrameType(ctx); err != nil { 116*cc02d7e2SAndroid Build Coastguard Worker t.Fatal(err) 117*cc02d7e2SAndroid Build Coastguard Worker } 118*cc02d7e2SAndroid Build Coastguard Worker} 119*cc02d7e2SAndroid Build Coastguard Worker 120*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonClientPrefaceWithStreamId(t *testing.T) { 121*cc02d7e2SAndroid Build Coastguard Worker defer Report(t) 122*cc02d7e2SAndroid Build Coastguard Worker if *testCase != "framing" { 123*cc02d7e2SAndroid Build Coastguard Worker t.SkipNow() 124*cc02d7e2SAndroid Build Coastguard Worker } 125*cc02d7e2SAndroid Build Coastguard Worker ctx := InteropCtx(t) 126*cc02d7e2SAndroid Build Coastguard Worker err := testClientPrefaceWithStreamId(ctx) 127*cc02d7e2SAndroid Build Coastguard Worker matchError(t, err, "EOF") 128*cc02d7e2SAndroid Build Coastguard Worker} 129*cc02d7e2SAndroid Build Coastguard Worker 130*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonTLSApplicationProtocol(t *testing.T) { 131*cc02d7e2SAndroid Build Coastguard Worker defer Report(t) 132*cc02d7e2SAndroid Build Coastguard Worker if *testCase != "tls" { 133*cc02d7e2SAndroid Build Coastguard Worker t.SkipNow() 134*cc02d7e2SAndroid Build Coastguard Worker } 135*cc02d7e2SAndroid Build Coastguard Worker ctx := InteropCtx(t) 136*cc02d7e2SAndroid Build Coastguard Worker err := testTLSApplicationProtocol(ctx) 137*cc02d7e2SAndroid Build Coastguard Worker matchError(t, err, "EOF", "broken pipe") 138*cc02d7e2SAndroid Build Coastguard Worker} 139*cc02d7e2SAndroid Build Coastguard Worker 140*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonTLSMaxVersion(t *testing.T) { 141*cc02d7e2SAndroid Build Coastguard Worker defer Report(t) 142*cc02d7e2SAndroid Build Coastguard Worker if *testCase != "tls" { 143*cc02d7e2SAndroid Build Coastguard Worker t.SkipNow() 144*cc02d7e2SAndroid Build Coastguard Worker } 145*cc02d7e2SAndroid Build Coastguard Worker ctx := InteropCtx(t) 146*cc02d7e2SAndroid Build Coastguard Worker err := testTLSMaxVersion(ctx, tls.VersionTLS11) 147*cc02d7e2SAndroid Build Coastguard Worker // TODO(carl-mastrangelo): maybe this should be some other error. If the server picks 148*cc02d7e2SAndroid Build Coastguard Worker // the wrong protocol version, that's bad too. 149*cc02d7e2SAndroid Build Coastguard Worker matchError(t, err, "EOF", "server selected unsupported protocol") 150*cc02d7e2SAndroid Build Coastguard Worker} 151*cc02d7e2SAndroid Build Coastguard Worker 152*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonTLSBadCipherSuites(t *testing.T) { 153*cc02d7e2SAndroid Build Coastguard Worker defer Report(t) 154*cc02d7e2SAndroid Build Coastguard Worker if *testCase != "tls" { 155*cc02d7e2SAndroid Build Coastguard Worker t.SkipNow() 156*cc02d7e2SAndroid Build Coastguard Worker } 157*cc02d7e2SAndroid Build Coastguard Worker ctx := InteropCtx(t) 158*cc02d7e2SAndroid Build Coastguard Worker err := testTLSBadCipherSuites(ctx) 159*cc02d7e2SAndroid Build Coastguard Worker matchError(t, err, "EOF", "Got goaway frame") 160*cc02d7e2SAndroid Build Coastguard Worker} 161*cc02d7e2SAndroid Build Coastguard Worker 162*cc02d7e2SAndroid Build Coastguard Workerfunc matchError(t *testing.T, err error, matches ...string) { 163*cc02d7e2SAndroid Build Coastguard Worker if err == nil { 164*cc02d7e2SAndroid Build Coastguard Worker t.Fatal("Expected an error") 165*cc02d7e2SAndroid Build Coastguard Worker } 166*cc02d7e2SAndroid Build Coastguard Worker for _, s := range matches { 167*cc02d7e2SAndroid Build Coastguard Worker if strings.Contains(err.Error(), s) { 168*cc02d7e2SAndroid Build Coastguard Worker return 169*cc02d7e2SAndroid Build Coastguard Worker } 170*cc02d7e2SAndroid Build Coastguard Worker } 171*cc02d7e2SAndroid Build Coastguard Worker t.Fatalf("Error %v not in %+v", err, matches) 172*cc02d7e2SAndroid Build Coastguard Worker} 173*cc02d7e2SAndroid Build Coastguard Worker 174*cc02d7e2SAndroid Build Coastguard Workerfunc TestMain(m *testing.M) { 175*cc02d7e2SAndroid Build Coastguard Worker flag.Parse() 176*cc02d7e2SAndroid Build Coastguard Worker m.Run() 177*cc02d7e2SAndroid Build Coastguard Worker var fatal bool 178*cc02d7e2SAndroid Build Coastguard Worker var any bool 179*cc02d7e2SAndroid Build Coastguard Worker for _, ci := range allCaseInfos.Cases { 180*cc02d7e2SAndroid Build Coastguard Worker if ci.Skipped { 181*cc02d7e2SAndroid Build Coastguard Worker continue 182*cc02d7e2SAndroid Build Coastguard Worker } 183*cc02d7e2SAndroid Build Coastguard Worker any = true 184*cc02d7e2SAndroid Build Coastguard Worker if !ci.Passed && ci.Fatal { 185*cc02d7e2SAndroid Build Coastguard Worker fatal = true 186*cc02d7e2SAndroid Build Coastguard Worker } 187*cc02d7e2SAndroid Build Coastguard Worker } 188*cc02d7e2SAndroid Build Coastguard Worker 189*cc02d7e2SAndroid Build Coastguard Worker if err := json.NewEncoder(os.Stderr).Encode(&allCaseInfos); err != nil { 190*cc02d7e2SAndroid Build Coastguard Worker fmt.Println("Failed to encode", err) 191*cc02d7e2SAndroid Build Coastguard Worker } 192*cc02d7e2SAndroid Build Coastguard Worker var code int 193*cc02d7e2SAndroid Build Coastguard Worker if !any || fatal { 194*cc02d7e2SAndroid Build Coastguard Worker code = 1 195*cc02d7e2SAndroid Build Coastguard Worker } 196*cc02d7e2SAndroid Build Coastguard Worker os.Exit(code) 197*cc02d7e2SAndroid Build Coastguard Worker} 198