...

Source file src/google.golang.org/grpc/credentials/tls_ext_test.go

Documentation: google.golang.org/grpc/credentials

     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.NewClient(ss.Address, grpc.WithTransportCredentials(clientCreds))
   107  	if err != nil {
   108  		t.Fatalf("grpc.NewClient 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.NewClient("dns:"+ss.Address, grpc.WithTransportCredentials(clientCreds))
   193  	if err != nil {
   194  		t.Fatalf("grpc.NewClient 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  }
   239  

View as plain text