google.golang.org/grpc@v1.62.1/credentials/tls_ext_test.go (about) 1 /* 2 * 3 * Copyright 2023 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package credentials_test 20 21 import ( 22 "context" 23 "crypto/tls" 24 "crypto/x509" 25 "fmt" 26 "os" 27 "strings" 28 "testing" 29 "time" 30 31 "google.golang.org/grpc" 32 "google.golang.org/grpc/codes" 33 "google.golang.org/grpc/credentials" 34 "google.golang.org/grpc/internal/grpctest" 35 "google.golang.org/grpc/internal/stubserver" 36 "google.golang.org/grpc/status" 37 "google.golang.org/grpc/testdata" 38 39 testgrpc "google.golang.org/grpc/interop/grpc_testing" 40 testpb "google.golang.org/grpc/interop/grpc_testing" 41 ) 42 43 const defaultTestTimeout = 10 * time.Second 44 45 type s struct { 46 grpctest.Tester 47 } 48 49 func Test(t *testing.T) { 50 grpctest.RunSubTests(t, s{}) 51 } 52 53 var serverCert tls.Certificate 54 var certPool *x509.CertPool 55 var serverName = "x.test.example.com" 56 57 func init() { 58 var err error 59 serverCert, err = tls.LoadX509KeyPair(testdata.Path("x509/server1_cert.pem"), testdata.Path("x509/server1_key.pem")) 60 if err != nil { 61 panic(fmt.Sprintf("tls.LoadX509KeyPair(server1.pem, server1.key) failed: %v", err)) 62 } 63 64 b, err := os.ReadFile(testdata.Path("x509/server_ca_cert.pem")) 65 if err != nil { 66 panic(fmt.Sprintf("Error reading CA cert file: %v", err)) 67 } 68 certPool = x509.NewCertPool() 69 if !certPool.AppendCertsFromPEM(b) { 70 panic("Error appending cert from PEM") 71 } 72 } 73 74 // Tests that the MinVersion of tls.Config is set to 1.2 if it is not already 75 // set by the user. 76 func (s) TestTLS_MinVersion12(t *testing.T) { 77 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 78 defer cancel() 79 80 // Create server creds without a minimum version. 81 serverCreds := credentials.NewTLS(&tls.Config{ 82 // MinVersion should be set to 1.2 by gRPC by default. 83 Certificates: []tls.Certificate{serverCert}, 84 }) 85 ss := stubserver.StubServer{ 86 EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { 87 return &testpb.Empty{}, nil 88 }, 89 } 90 91 // Create client creds that supports V1.0-V1.1. 92 clientCreds := credentials.NewTLS(&tls.Config{ 93 ServerName: serverName, 94 RootCAs: certPool, 95 MinVersion: tls.VersionTLS10, 96 MaxVersion: tls.VersionTLS11, 97 }) 98 99 // Start server and client separately, because Start() blocks on a 100 // successful connection, which we will not get. 101 if err := ss.StartServer(grpc.Creds(serverCreds)); err != nil { 102 t.Fatalf("Error starting server: %v", err) 103 } 104 defer ss.Stop() 105 106 cc, err := grpc.Dial(ss.Address, grpc.WithTransportCredentials(clientCreds)) 107 if err != nil { 108 t.Fatalf("grpc.Dial error: %v", err) 109 } 110 defer cc.Close() 111 112 client := testgrpc.NewTestServiceClient(cc) 113 114 const wantStr = "authentication handshake failed" 115 if _, err = client.EmptyCall(ctx, &testpb.Empty{}); status.Code(err) != codes.Unavailable || !strings.Contains(status.Convert(err).Message(), wantStr) { 116 t.Fatalf("EmptyCall err = %v; want code=%v, message contains %q", err, codes.Unavailable, wantStr) 117 } 118 } 119 120 // Tests that the MinVersion of tls.Config is not changed if it is set by the 121 // user. 122 func (s) TestTLS_MinVersionOverridable(t *testing.T) { 123 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 124 defer cancel() 125 126 var allCipherSuites []uint16 127 for _, cs := range tls.CipherSuites() { 128 allCipherSuites = append(allCipherSuites, cs.ID) 129 } 130 131 // Create server creds that allow v1.0. 132 serverCreds := credentials.NewTLS(&tls.Config{ 133 MinVersion: tls.VersionTLS10, 134 Certificates: []tls.Certificate{serverCert}, 135 CipherSuites: allCipherSuites, 136 }) 137 ss := stubserver.StubServer{ 138 EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { 139 return &testpb.Empty{}, nil 140 }, 141 } 142 143 // Create client creds that supports V1.0-V1.1. 144 clientCreds := credentials.NewTLS(&tls.Config{ 145 ServerName: serverName, 146 RootCAs: certPool, 147 CipherSuites: allCipherSuites, 148 MinVersion: tls.VersionTLS10, 149 MaxVersion: tls.VersionTLS11, 150 }) 151 152 if err := ss.Start([]grpc.ServerOption{grpc.Creds(serverCreds)}, grpc.WithTransportCredentials(clientCreds)); err != nil { 153 t.Fatalf("Error starting stub server: %v", err) 154 } 155 defer ss.Stop() 156 157 if _, err := ss.Client.EmptyCall(ctx, &testpb.Empty{}); err != nil { 158 t.Fatalf("EmptyCall err = %v; want <nil>", err) 159 } 160 } 161 162 // Tests that CipherSuites is set to exclude HTTP/2 forbidden suites by default. 163 func (s) TestTLS_CipherSuites(t *testing.T) { 164 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 165 defer cancel() 166 167 // Create server creds without cipher suites. 168 serverCreds := credentials.NewTLS(&tls.Config{ 169 Certificates: []tls.Certificate{serverCert}, 170 }) 171 ss := stubserver.StubServer{ 172 EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { 173 return &testpb.Empty{}, nil 174 }, 175 } 176 177 // Create client creds that use a forbidden suite only. 178 clientCreds := credentials.NewTLS(&tls.Config{ 179 ServerName: serverName, 180 RootCAs: certPool, 181 CipherSuites: []uint16{tls.TLS_RSA_WITH_AES_128_CBC_SHA}, 182 MaxVersion: tls.VersionTLS12, // TLS1.3 cipher suites are not configurable, so limit to 1.2. 183 }) 184 185 // Start server and client separately, because Start() blocks on a 186 // successful connection, which we will not get. 187 if err := ss.StartServer(grpc.Creds(serverCreds)); err != nil { 188 t.Fatalf("Error starting server: %v", err) 189 } 190 defer ss.Stop() 191 192 cc, err := grpc.Dial("dns:"+ss.Address, grpc.WithTransportCredentials(clientCreds)) 193 if err != nil { 194 t.Fatalf("grpc.Dial error: %v", err) 195 } 196 defer cc.Close() 197 198 client := testgrpc.NewTestServiceClient(cc) 199 200 const wantStr = "authentication handshake failed" 201 if _, err = client.EmptyCall(ctx, &testpb.Empty{}); status.Code(err) != codes.Unavailable || !strings.Contains(status.Convert(err).Message(), wantStr) { 202 t.Fatalf("EmptyCall err = %v; want code=%v, message contains %q", err, codes.Unavailable, wantStr) 203 } 204 } 205 206 // Tests that CipherSuites is not overridden when it is set. 207 func (s) TestTLS_CipherSuitesOverridable(t *testing.T) { 208 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 209 defer cancel() 210 211 // Create server that allows only a forbidden cipher suite. 212 serverCreds := credentials.NewTLS(&tls.Config{ 213 Certificates: []tls.Certificate{serverCert}, 214 CipherSuites: []uint16{tls.TLS_RSA_WITH_AES_128_CBC_SHA}, 215 }) 216 ss := stubserver.StubServer{ 217 EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { 218 return &testpb.Empty{}, nil 219 }, 220 } 221 222 // Create server that allows only a forbidden cipher suite. 223 clientCreds := credentials.NewTLS(&tls.Config{ 224 ServerName: serverName, 225 RootCAs: certPool, 226 CipherSuites: []uint16{tls.TLS_RSA_WITH_AES_128_CBC_SHA}, 227 MaxVersion: tls.VersionTLS12, // TLS1.3 cipher suites are not configurable, so limit to 1.2. 228 }) 229 230 if err := ss.Start([]grpc.ServerOption{grpc.Creds(serverCreds)}, grpc.WithTransportCredentials(clientCreds)); err != nil { 231 t.Fatalf("Error starting stub server: %v", err) 232 } 233 defer ss.Stop() 234 235 if _, err := ss.Client.EmptyCall(ctx, &testpb.Empty{}); err != nil { 236 t.Fatalf("EmptyCall err = %v; want <nil>", err) 237 } 238 }