go.temporal.io/server@v1.23.0/common/rpc/test/rpc_localstore_tls_test.go (about)

     1  // The MIT License
     2  //
     3  // Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
     4  //
     5  // Copyright (c) 2020 Uber Technologies, Inc.
     6  //
     7  // Permission is hereby granted, free of charge, to any person obtaining a copy
     8  // of this software and associated documentation files (the "Software"), to deal
     9  // in the Software without restriction, including without limitation the rights
    10  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  // copies of the Software, and to permit persons to whom the Software is
    12  // furnished to do so, subject to the following conditions:
    13  //
    14  // The above copyright notice and this permission notice shall be included in
    15  // all copies or substantial portions of the Software.
    16  //
    17  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  // THE SOFTWARE.
    24  
    25  package rpc
    26  
    27  import (
    28  	"crypto/tls"
    29  	"crypto/x509"
    30  	"os"
    31  	"testing"
    32  	"time"
    33  
    34  	"github.com/golang/mock/gomock"
    35  	"github.com/stretchr/testify/require"
    36  	"github.com/stretchr/testify/suite"
    37  	"google.golang.org/grpc"
    38  	"google.golang.org/grpc/credentials"
    39  
    40  	"go.temporal.io/server/common/config"
    41  	"go.temporal.io/server/common/log"
    42  	"go.temporal.io/server/common/metrics"
    43  	"go.temporal.io/server/common/rpc"
    44  	"go.temporal.io/server/common/rpc/encryption"
    45  	"go.temporal.io/server/tests/testutils"
    46  )
    47  
    48  const (
    49  	internodeServerCertSerialNumber = 100
    50  	frontendServerCertSerialNumber  = 150
    51  )
    52  
    53  var (
    54  	frontendURL         = "dummy://" // not needed for test
    55  	noExtraInterceptors = []grpc.UnaryClientInterceptor{}
    56  )
    57  
    58  type localStoreRPCSuite struct {
    59  	*require.Assertions
    60  	*suite.Suite
    61  
    62  	controller *gomock.Controller
    63  
    64  	logger log.Logger
    65  
    66  	insecureRPCFactory                      *TestFactory
    67  	internodeMutualTLSRPCFactory            *TestFactory
    68  	internodeServerTLSRPCFactory            *TestFactory
    69  	internodeAltMutualTLSRPCFactory         *TestFactory
    70  	frontendMutualTLSRPCFactory             *TestFactory
    71  	frontendServerTLSRPCFactory             *TestFactory
    72  	frontendSystemWorkerMutualTLSRPCFactory *TestFactory
    73  	frontendDynamicTLSFactory               *TestFactory
    74  	internodeDynamicTLSFactory              *TestFactory
    75  	internodeMutualTLSRPCRefreshFactory     *TestFactory
    76  	frontendMutualTLSRPCRefreshFactory      *TestFactory
    77  	remoteClusterMutualTLSRPCFactory        *TestFactory
    78  	frontendConfigRootCAForceTLSFactory     *TestFactory
    79  
    80  	internodeCertDir        string
    81  	frontendCertDir         string
    82  	frontendAltCertDir      string
    83  	frontendRollingCertDir  string
    84  	internodeRefreshCertDir string
    85  	frontendRefreshCertDir  string
    86  
    87  	internodeChain        testutils.CertChain
    88  	frontendChain         testutils.CertChain
    89  	frontendAltChain      testutils.CertChain
    90  	frontendRollingCerts  []*tls.Certificate
    91  	internodeRefreshChain testutils.CertChain
    92  	internodeRefreshCA    *tls.Certificate
    93  	frontendRefreshChain  testutils.CertChain
    94  	frontendRefreshCA     *tls.Certificate
    95  
    96  	frontendClientCertDir string
    97  	frontendClientChain   testutils.CertChain
    98  
    99  	membershipConfig               config.Membership
   100  	frontendConfigServerTLS        config.GroupTLS
   101  	frontendConfigMutualTLS        config.GroupTLS
   102  	frontendConfigPerHostOverrides config.GroupTLS
   103  	frontendConfigRootCAOnly       config.GroupTLS
   104  	frontendConfigRootCAForceTLS   config.GroupTLS
   105  	frontendConfigAltRootCAOnly    config.GroupTLS
   106  	systemWorkerOnly               config.WorkerTLS
   107  	frontendConfigSystemWorker     config.WorkerTLS
   108  	frontendConfigMutualTLSRefresh config.GroupTLS
   109  
   110  	internodeConfigMutualTLS        config.GroupTLS
   111  	internodeConfigServerTLS        config.GroupTLS
   112  	internodeConfigAltMutualTLS     config.GroupTLS
   113  	internodeConfigMutualTLSRefresh config.GroupTLS
   114  
   115  	dynamicCACertPool *x509.CertPool
   116  	wrongCACertPool   *x509.CertPool
   117  
   118  	dynamicConfigProvider *encryption.TestDynamicTLSConfigProvider
   119  }
   120  
   121  func TestLocalStoreTLSSuite(t *testing.T) {
   122  	suite.Run(t, &localStoreRPCSuite{
   123  		Suite: &suite.Suite{},
   124  	})
   125  }
   126  
   127  func (s *localStoreRPCSuite) TearDownSuite() {
   128  	_ = os.RemoveAll(s.internodeCertDir)
   129  	_ = os.RemoveAll(s.frontendCertDir)
   130  }
   131  
   132  func (s *localStoreRPCSuite) SetupSuite() {
   133  	s.Assertions = require.New(s.T())
   134  	s.logger = log.NewTestLogger()
   135  
   136  	provider, err := encryption.NewTLSConfigProviderFromConfig(serverCfgInsecure.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   137  	s.NoError(err)
   138  	insecureFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, nil, noExtraInterceptors)
   139  	s.NotNil(insecureFactory)
   140  	s.insecureRPCFactory = i(insecureFactory)
   141  
   142  	s.frontendCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontend")
   143  	s.NoError(err)
   144  	s.frontendChain, err = testutils.GenerateTestChain(s.frontendCertDir, localhostIPv4)
   145  	s.NoError(err)
   146  
   147  	s.internodeCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteInternode")
   148  	s.NoError(err)
   149  	s.internodeChain, err = testutils.GenerateTestChain(s.internodeCertDir, localhostIPv4)
   150  	s.NoError(err)
   151  
   152  	s.frontendAltCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontendAlt")
   153  	s.NoError(err)
   154  	s.frontendAltChain, err = testutils.GenerateTestChain(s.frontendAltCertDir, localhost)
   155  	s.NoError(err)
   156  
   157  	s.frontendClientCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontendClient")
   158  	s.NoError(err)
   159  	s.frontendClientChain, err = testutils.GenerateTestChain(s.frontendClientCertDir, localhostIPv4)
   160  	s.NoError(err)
   161  
   162  	s.frontendRollingCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontendRolling")
   163  	s.NoError(err)
   164  	s.frontendRollingCerts, s.dynamicCACertPool, s.wrongCACertPool, err = testutils.GenerateTestCerts(s.frontendRollingCertDir, localhostIPv4, 2)
   165  	s.NoError(err)
   166  
   167  	s.internodeRefreshCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteInternodeRefresh")
   168  	s.NoError(err)
   169  	s.internodeRefreshChain, s.internodeRefreshCA, err = testutils.GenerateTestChainWithSN(s.internodeRefreshCertDir, localhostIPv4, internodeServerCertSerialNumber)
   170  	s.NoError(err)
   171  
   172  	s.frontendRefreshCertDir, err = os.MkdirTemp("", "localStoreRPCSuiteFrontendRefresh")
   173  	s.NoError(err)
   174  	s.frontendRefreshChain, s.frontendRefreshCA, err = testutils.GenerateTestChainWithSN(s.frontendRefreshCertDir, localhostIPv4, frontendServerCertSerialNumber)
   175  	s.NoError(err)
   176  
   177  	s.membershipConfig = config.Membership{
   178  		MaxJoinDuration:  5,
   179  		BroadcastAddress: localhostIPv4,
   180  	}
   181  
   182  	frontendConfigBase := config.GroupTLS{
   183  		Server: config.ServerTLS{
   184  			CertFile: s.frontendChain.CertPubFile,
   185  			KeyFile:  s.frontendChain.CertKeyFile,
   186  		},
   187  	}
   188  
   189  	s.frontendConfigServerTLS = frontendConfigBase
   190  	s.frontendConfigServerTLS.Client = config.ClientTLS{RootCAFiles: []string{s.frontendChain.CaPubFile}}
   191  
   192  	s.frontendConfigMutualTLS = frontendConfigBase
   193  	s.frontendConfigMutualTLS.Server.ClientCAFiles = []string{s.frontendClientChain.CaPubFile}
   194  	s.frontendConfigMutualTLS.Server.RequireClientAuth = true
   195  
   196  	s.frontendConfigPerHostOverrides = s.frontendConfigServerTLS
   197  	s.frontendConfigPerHostOverrides.PerHostOverrides = map[string]config.ServerTLS{
   198  		localhost: {
   199  			CertFile:          s.frontendAltChain.CertPubFile,
   200  			KeyFile:           s.frontendAltChain.CertKeyFile,
   201  			ClientCAFiles:     []string{s.frontendAltChain.CaPubFile},
   202  			RequireClientAuth: true,
   203  		},
   204  	}
   205  	s.frontendConfigRootCAOnly = config.GroupTLS{
   206  		Client: config.ClientTLS{
   207  			RootCAData: []string{testutils.ConvertFileToBase64(s.frontendChain.CaPubFile)},
   208  		},
   209  	}
   210  	s.frontendConfigRootCAForceTLS = s.frontendConfigRootCAOnly
   211  	s.frontendConfigRootCAForceTLS.Client.ForceTLS = true
   212  
   213  	s.frontendConfigAltRootCAOnly = config.GroupTLS{
   214  		Server: config.ServerTLS{
   215  			RequireClientAuth: true,
   216  		},
   217  		Client: config.ClientTLS{
   218  			RootCAData: []string{testutils.ConvertFileToBase64(s.frontendAltChain.CaPubFile)},
   219  		},
   220  	}
   221  	s.systemWorkerOnly = config.WorkerTLS{
   222  		CertFile: s.frontendClientChain.CertPubFile,
   223  		KeyFile:  s.frontendClientChain.CertKeyFile,
   224  	}
   225  	s.frontendConfigSystemWorker = s.systemWorkerOnly
   226  	s.frontendConfigSystemWorker.Client = config.ClientTLS{
   227  		RootCAFiles: []string{s.frontendChain.CaPubFile},
   228  	}
   229  
   230  	s.internodeConfigMutualTLS = config.GroupTLS{
   231  		Server: config.ServerTLS{
   232  			CertFile:          s.internodeChain.CertPubFile,
   233  			KeyFile:           s.internodeChain.CertKeyFile,
   234  			ClientCAFiles:     []string{s.internodeChain.CaPubFile},
   235  			RequireClientAuth: true,
   236  		},
   237  		Client: config.ClientTLS{
   238  			RootCAFiles: []string{s.internodeChain.CaPubFile},
   239  		},
   240  	}
   241  	s.internodeConfigServerTLS = config.GroupTLS{
   242  		Server: config.ServerTLS{
   243  			CertData: testutils.ConvertFileToBase64(s.internodeChain.CertPubFile),
   244  			KeyData:  testutils.ConvertFileToBase64(s.internodeChain.CertKeyFile),
   245  		},
   246  		Client: config.ClientTLS{
   247  			RootCAData: []string{testutils.ConvertFileToBase64(s.internodeChain.CaPubFile)},
   248  		},
   249  	}
   250  	s.internodeConfigAltMutualTLS = config.GroupTLS{
   251  		Server: config.ServerTLS{
   252  			CertFile:          s.frontendAltChain.CertPubFile,
   253  			KeyFile:           s.frontendAltChain.CertKeyFile,
   254  			ClientCAFiles:     []string{s.frontendAltChain.CaPubFile},
   255  			RequireClientAuth: true,
   256  		},
   257  		Client: config.ClientTLS{
   258  			RootCAFiles: []string{s.frontendAltChain.CaPubFile},
   259  		},
   260  	}
   261  
   262  	s.internodeConfigMutualTLSRefresh = mutualGroupTLSFromChain(s.internodeRefreshChain)
   263  	s.frontendConfigMutualTLSRefresh = mutualGroupTLSFromChain(s.frontendRefreshChain)
   264  }
   265  
   266  func mutualGroupTLSFromChain(chain testutils.CertChain) config.GroupTLS {
   267  	return config.GroupTLS{
   268  		Server: config.ServerTLS{
   269  			CertFile:          chain.CertPubFile,
   270  			KeyFile:           chain.CertKeyFile,
   271  			ClientCAFiles:     []string{chain.CaPubFile},
   272  			RequireClientAuth: true,
   273  		},
   274  		Client: config.ClientTLS{
   275  			RootCAFiles: []string{chain.CaPubFile},
   276  		},
   277  	}
   278  }
   279  
   280  func (s *localStoreRPCSuite) SetupTest() {
   281  	s.controller = gomock.NewController(s.T())
   282  
   283  	s.setupInternode()
   284  	s.setupFrontend()
   285  }
   286  
   287  func (s *localStoreRPCSuite) TearDownTest() {
   288  	s.controller.Finish()
   289  }
   290  
   291  func (s *localStoreRPCSuite) setupFrontend() {
   292  	localStoreServerTLS := &config.Global{
   293  		Membership: s.membershipConfig,
   294  		TLS: config.RootTLS{
   295  			Frontend: s.frontendConfigServerTLS,
   296  		},
   297  	}
   298  
   299  	localStoreMutualTLS := &config.Global{
   300  		Membership: s.membershipConfig,
   301  		TLS: config.RootTLS{
   302  			Frontend: s.frontendConfigPerHostOverrides,
   303  		},
   304  	}
   305  
   306  	localStoreMutualTLSSystemWorker := &config.Global{
   307  		Membership: s.membershipConfig,
   308  		TLS: config.RootTLS{
   309  			Internode:    s.internodeConfigMutualTLS,
   310  			Frontend:     s.frontendConfigMutualTLS,
   311  			SystemWorker: s.frontendConfigSystemWorker,
   312  		},
   313  	}
   314  
   315  	localStoreMutualTLSWithRefresh := &config.Global{
   316  		Membership: s.membershipConfig,
   317  		TLS: config.RootTLS{
   318  			Frontend:        s.frontendConfigMutualTLSRefresh,
   319  			Internode:       s.frontendConfigMutualTLSRefresh,
   320  			RefreshInterval: time.Second,
   321  			ExpirationChecks: config.CertExpirationValidation{
   322  				WarningWindow: time.Hour * 24 * 14,
   323  				ErrorWindow:   time.Hour * 24 * 7,
   324  				CheckInterval: time.Second,
   325  			},
   326  		},
   327  	}
   328  
   329  	localStoreRootCAForceTLS := &config.Global{
   330  		Membership: s.membershipConfig,
   331  		TLS: config.RootTLS{
   332  			Frontend: s.frontendConfigRootCAForceTLS,
   333  		},
   334  	}
   335  
   336  	localStoreMutualTLSRemoteCluster := &config.Global{
   337  		Membership: s.membershipConfig,
   338  		TLS: config.RootTLS{
   339  			Frontend:       s.frontendConfigPerHostOverrides,
   340  			RemoteClusters: map[string]config.GroupTLS{localhostIPv4: s.frontendConfigPerHostOverrides},
   341  		},
   342  	}
   343  
   344  	provider, err := encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   345  	s.NoError(err)
   346  	tlsConfig, err := provider.GetFrontendClientConfig()
   347  	s.NoError(err)
   348  	frontendMutualTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors)
   349  	s.NotNil(frontendMutualTLSFactory)
   350  
   351  	provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreServerTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   352  	s.NoError(err)
   353  	frontendServerTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, nil, noExtraInterceptors)
   354  	s.NotNil(frontendServerTLSFactory)
   355  
   356  	provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLSSystemWorker.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   357  	s.NoError(err)
   358  	tlsConfig, err = provider.GetFrontendClientConfig()
   359  	s.NoError(err)
   360  	frontendSystemWorkerMutualTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors)
   361  	s.NotNil(frontendSystemWorkerMutualTLSFactory)
   362  
   363  	provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLSWithRefresh.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   364  	s.NoError(err)
   365  	tlsConfig, err = provider.GetFrontendClientConfig()
   366  	s.NoError(err)
   367  	frontendMutualTLSRefreshFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors)
   368  	s.NotNil(frontendMutualTLSRefreshFactory)
   369  
   370  	s.frontendMutualTLSRPCFactory = f(frontendMutualTLSFactory)
   371  	s.frontendServerTLSRPCFactory = f(frontendServerTLSFactory)
   372  	s.frontendSystemWorkerMutualTLSRPCFactory = f(frontendSystemWorkerMutualTLSFactory)
   373  
   374  	s.dynamicConfigProvider, err = encryption.NewTestDynamicTLSConfigProvider(
   375  		&localStoreMutualTLS.TLS,
   376  		s.frontendRollingCerts,
   377  		s.dynamicCACertPool,
   378  		s.frontendRollingCerts,
   379  		s.dynamicCACertPool,
   380  		s.wrongCACertPool)
   381  	s.NoError(err)
   382  	tlsConfig, err = s.dynamicConfigProvider.GetFrontendClientConfig()
   383  	s.NoError(err)
   384  	dynamicServerTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, s.dynamicConfigProvider, frontendURL, tlsConfig, noExtraInterceptors)
   385  	s.frontendDynamicTLSFactory = f(dynamicServerTLSFactory)
   386  	s.internodeDynamicTLSFactory = i(dynamicServerTLSFactory)
   387  
   388  	s.frontendMutualTLSRPCRefreshFactory = f(frontendMutualTLSRefreshFactory)
   389  
   390  	provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreRootCAForceTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   391  	s.NoError(err)
   392  	tlsConfig, err = provider.GetFrontendClientConfig()
   393  	s.NoError(err)
   394  	frontendRootCAForceTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors)
   395  	s.NotNil(frontendServerTLSFactory)
   396  	s.frontendConfigRootCAForceTLSFactory = f(frontendRootCAForceTLSFactory)
   397  
   398  	provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLSRemoteCluster.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   399  	s.NoError(err)
   400  	tlsConfig, err = provider.GetFrontendClientConfig()
   401  	s.NoError(err)
   402  	remoteClusterMutualTLSRPCFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors)
   403  	s.NotNil(remoteClusterMutualTLSRPCFactory)
   404  	s.remoteClusterMutualTLSRPCFactory = r(remoteClusterMutualTLSRPCFactory)
   405  }
   406  
   407  func (s *localStoreRPCSuite) setupInternode() {
   408  	localStoreServerTLS := &config.Global{
   409  		Membership: s.membershipConfig,
   410  		TLS: config.RootTLS{
   411  			Internode: s.internodeConfigServerTLS,
   412  			Frontend:  s.frontendConfigRootCAOnly,
   413  		},
   414  	}
   415  
   416  	localStoreMutualTLS := &config.Global{
   417  		Membership: s.membershipConfig,
   418  		TLS: config.RootTLS{
   419  			Internode: s.internodeConfigMutualTLS,
   420  			Frontend:  s.frontendConfigRootCAOnly,
   421  		},
   422  	}
   423  
   424  	localStoreAltMutualTLS := &config.Global{
   425  		Membership: s.membershipConfig,
   426  		TLS: config.RootTLS{
   427  			Internode: s.internodeConfigAltMutualTLS,
   428  			Frontend:  s.frontendConfigAltRootCAOnly,
   429  		},
   430  	}
   431  
   432  	localStoreMutualTLSWithRefresh := *localStoreMutualTLS
   433  	localStoreMutualTLSWithRefresh.TLS.Internode = s.internodeConfigMutualTLSRefresh
   434  	localStoreMutualTLSWithRefresh.TLS.RefreshInterval = time.Second
   435  
   436  	provider, err := encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   437  	s.NoError(err)
   438  	tlsConfig, err := provider.GetFrontendClientConfig()
   439  	s.NoError(err)
   440  	internodeMutualTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors)
   441  	s.NotNil(internodeMutualTLSFactory)
   442  
   443  	provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreServerTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   444  	s.NoError(err)
   445  	tlsConfig, err = provider.GetFrontendClientConfig()
   446  	s.NoError(err)
   447  	internodeServerTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors)
   448  	s.NotNil(internodeServerTLSFactory)
   449  
   450  	provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreAltMutualTLS.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   451  	s.NoError(err)
   452  	tlsConfig, err = provider.GetFrontendClientConfig()
   453  	s.NoError(err)
   454  	internodeMutualAltTLSFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors)
   455  	s.NotNil(internodeMutualAltTLSFactory)
   456  
   457  	provider, err = encryption.NewTLSConfigProviderFromConfig(localStoreMutualTLSWithRefresh.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   458  	s.NoError(err)
   459  	tlsConfig, err = provider.GetFrontendClientConfig()
   460  	s.NoError(err)
   461  	internodeMutualTLSRefreshFactory := rpc.NewFactory(rpcTestCfgDefault, "tester", s.logger, provider, frontendURL, tlsConfig, noExtraInterceptors)
   462  	s.NotNil(internodeMutualTLSRefreshFactory)
   463  
   464  	s.internodeMutualTLSRPCFactory = i(internodeMutualTLSFactory)
   465  	s.internodeServerTLSRPCFactory = i(internodeServerTLSFactory)
   466  	s.internodeAltMutualTLSRPCFactory = i(internodeMutualAltTLSFactory)
   467  	s.internodeMutualTLSRPCRefreshFactory = i(internodeMutualTLSRefreshFactory)
   468  }
   469  
   470  func f(r *rpc.RPCFactory) *TestFactory {
   471  	return &TestFactory{serverUsage: Frontend, RPCFactory: r}
   472  }
   473  
   474  func i(r *rpc.RPCFactory) *TestFactory {
   475  	return &TestFactory{serverUsage: Internode, RPCFactory: r}
   476  }
   477  
   478  func r(r *rpc.RPCFactory) *TestFactory {
   479  	return &TestFactory{serverUsage: RemoteCluster, RPCFactory: r}
   480  }
   481  
   482  func (s *localStoreRPCSuite) TestServerTLS() {
   483  	runHelloWorldTest(s.Suite, localhostIPv4, s.internodeServerTLSRPCFactory, s.internodeServerTLSRPCFactory, true)
   484  }
   485  
   486  func (s *localStoreRPCSuite) TestServerTLSFrontendToFrontend() {
   487  	runHelloWorldTest(s.Suite, localhostIPv4, s.frontendServerTLSRPCFactory, s.frontendServerTLSRPCFactory, true)
   488  }
   489  
   490  func (s *localStoreRPCSuite) TestMutualTLS() {
   491  	runHelloWorldTest(s.Suite, localhostIPv4, s.internodeMutualTLSRPCFactory, s.internodeMutualTLSRPCFactory, true)
   492  }
   493  
   494  func (s *localStoreRPCSuite) TestMutualTLSFrontendToFrontend() {
   495  	runHelloWorldTest(s.Suite, localhostIPv4, s.frontendMutualTLSRPCFactory, s.frontendMutualTLSRPCFactory, true)
   496  }
   497  
   498  func (s *localStoreRPCSuite) TestMutualTLSFrontendToRemoteCluster() {
   499  	runHelloWorldTest(s.Suite, localhostIPv4, s.remoteClusterMutualTLSRPCFactory, s.remoteClusterMutualTLSRPCFactory, true)
   500  }
   501  
   502  func (s *localStoreRPCSuite) TestMutualTLSButClientInsecure() {
   503  	runHelloWorldTest(s.Suite, localhostIPv4, s.internodeMutualTLSRPCFactory, s.insecureRPCFactory, false)
   504  }
   505  
   506  func (s *localStoreRPCSuite) TestServerTLSButClientInsecure() {
   507  	runHelloWorldTest(s.Suite, localhostIPv4, s.internodeServerTLSRPCFactory, s.insecureRPCFactory, false)
   508  }
   509  
   510  func (s *localStoreRPCSuite) TestMutualTLSButClientNoCert() {
   511  	runHelloWorldTest(s.Suite, localhostIPv4, s.internodeMutualTLSRPCFactory, s.internodeServerTLSRPCFactory, false)
   512  }
   513  
   514  func (s *localStoreRPCSuite) TestServerTLSButClientAddsCert() {
   515  	runHelloWorldTest(s.Suite, localhostIPv4, s.internodeServerTLSRPCFactory, s.internodeMutualTLSRPCFactory, true)
   516  }
   517  
   518  func (s *localStoreRPCSuite) TestMutualTLSSystemWorker() {
   519  	runHelloWorldTest(s.Suite, localhostIPv4, s.frontendSystemWorkerMutualTLSRPCFactory, s.frontendSystemWorkerMutualTLSRPCFactory, true)
   520  }
   521  
   522  func (s *localStoreRPCSuite) TestDynamicServerTLSFrontend() {
   523  	s.testDynamicServerTLS(localhostIPv4, true)
   524  }
   525  
   526  func (s *localStoreRPCSuite) TestDynamicServerTLSInternode() {
   527  	s.testDynamicServerTLS(localhostIPv4, false)
   528  }
   529  
   530  func (s *localStoreRPCSuite) TestDynamicServerTLSOverrideFrontend() {
   531  	s.testDynamicServerTLS(localhost, true)
   532  }
   533  
   534  func (s *localStoreRPCSuite) TestDynamicServerTLSOverrideInternode() {
   535  	s.testDynamicServerTLS(localhost, false)
   536  }
   537  
   538  func (s *localStoreRPCSuite) testDynamicServerTLS(host string, frontend bool) {
   539  	server, client := s.getTestFactory(frontend)
   540  	var index int
   541  	s.dynamicConfigProvider.InternodeClientCertProvider.SetServerName(host)
   542  	s.dynamicConfigProvider.FrontendClientCertProvider.SetServerName(host)
   543  	runHelloWorldMultipleDials(s.Suite, host, server, client, 5,
   544  		func(tlsInfo *credentials.TLSInfo, err error) {
   545  			s.validateTLSInfo(tlsInfo, err, int64((index+1)%2+100))
   546  			index++
   547  		})
   548  }
   549  
   550  func (s *localStoreRPCSuite) TestDynamicRootCAFrontend() {
   551  	s.testDynamicRootCA(localhostIPv4, true)
   552  }
   553  
   554  func (s *localStoreRPCSuite) TestDynamicRootCAInternode() {
   555  	s.testDynamicRootCA(localhostIPv4, true)
   556  }
   557  
   558  func (s *localStoreRPCSuite) TestDynamicRootCAOverrideFrontend() {
   559  	s.testDynamicRootCA(localhost, true)
   560  }
   561  
   562  func (s *localStoreRPCSuite) TestDynamicRootCAOverrideInternode() {
   563  	s.testDynamicRootCA(localhost, true)
   564  }
   565  
   566  func (s *localStoreRPCSuite) TestCertExpiration() {
   567  	sixHours := time.Hour * 6
   568  	s.testCertExpiration(s.insecureRPCFactory, sixHours, 0)
   569  	s.testCertExpiration(s.internodeMutualTLSRPCFactory, sixHours, 0)
   570  	s.testCertExpiration(s.internodeServerTLSRPCFactory, sixHours, 0)
   571  	s.testCertExpiration(s.internodeAltMutualTLSRPCFactory, sixHours, 0)
   572  	s.testCertExpiration(s.frontendMutualTLSRPCFactory, sixHours, 0)
   573  	s.testCertExpiration(s.frontendServerTLSRPCFactory, sixHours, 0)
   574  	s.testCertExpiration(s.frontendSystemWorkerMutualTLSRPCFactory, sixHours, 0)
   575  
   576  	twoDays := time.Hour * 48
   577  	s.testCertExpiration(s.insecureRPCFactory, twoDays, 0)
   578  	s.testCertExpiration(s.internodeMutualTLSRPCFactory, twoDays, 3)
   579  	s.testCertExpiration(s.internodeServerTLSRPCFactory, twoDays, 3)
   580  	s.testCertExpiration(s.internodeAltMutualTLSRPCFactory, twoDays, 2)
   581  	s.testCertExpiration(s.frontendMutualTLSRPCFactory, twoDays, 4)
   582  	s.testCertExpiration(s.frontendServerTLSRPCFactory, twoDays, 2)
   583  	s.testCertExpiration(s.frontendSystemWorkerMutualTLSRPCFactory, twoDays, 6)
   584  }
   585  
   586  func (s *localStoreRPCSuite) testCertExpiration(factory *TestFactory, timeWindow time.Duration, nExpiring int) {
   587  	expiring, expired, err := factory.GetTLSConfigProvider().GetExpiringCerts(timeWindow)
   588  	s.NotNil(expiring)
   589  	s.Empty(expired)
   590  	s.NoError(err)
   591  	s.Equal(nExpiring, len(expiring))
   592  }
   593  
   594  func (s *localStoreRPCSuite) testDynamicRootCA(host string, frontend bool) {
   595  	server, client := s.getTestFactory(frontend)
   596  	var index int
   597  	valid := true
   598  	runHelloWorldMultipleDials(s.Suite, host, server, client, 5,
   599  		func(tlsInfo *credentials.TLSInfo, err error) {
   600  			if valid {
   601  				s.NoError(err)
   602  			} else {
   603  				s.Error(err)
   604  			}
   605  			index++
   606  			if index == 2 {
   607  				s.dynamicConfigProvider.InternodeClientCertProvider.SwitchToWrongServerRootCACerts()
   608  				s.dynamicConfigProvider.FrontendClientCertProvider.SwitchToWrongServerRootCACerts()
   609  				valid = false
   610  			}
   611  		})
   612  }
   613  
   614  func (s *localStoreRPCSuite) getTestFactory(frontend bool) (server *TestFactory, client *TestFactory) {
   615  	if frontend {
   616  		server = s.frontendDynamicTLSFactory
   617  		client = s.frontendDynamicTLSFactory
   618  	} else {
   619  		server = s.internodeDynamicTLSFactory
   620  		client = s.internodeDynamicTLSFactory
   621  	}
   622  	return server, client
   623  }
   624  
   625  func (s *localStoreRPCSuite) TestServerTLSRefreshInternode() {
   626  	s.testServerTLSRefresh(s.internodeMutualTLSRPCRefreshFactory, s.internodeRefreshCA, s.internodeRefreshCertDir, internodeServerCertSerialNumber)
   627  }
   628  
   629  func (s *localStoreRPCSuite) TestServerTLSRefreshFrontend() {
   630  	s.testServerTLSRefresh(s.frontendMutualTLSRPCRefreshFactory, s.frontendRefreshCA, s.frontendRefreshCertDir, frontendServerCertSerialNumber)
   631  }
   632  
   633  func (s *localStoreRPCSuite) testServerTLSRefresh(factory *TestFactory, ca *tls.Certificate, certDir string, serialNumber int64) {
   634  	server, port := startHelloWorldServer(s.Suite, factory)
   635  	defer server.Stop()
   636  
   637  	host := localhostIPv4 + ":" + port
   638  	tlsInfo, err := dialHelloAndGetTLSInfo(s.Suite, host, factory, factory.serverUsage)
   639  	s.validateTLSInfo(tlsInfo, err, serialNumber) // serial number of server cert before refresh
   640  
   641  	srvrCert, err := testutils.GenerateServerCert(ca, localhostIPv4, serialNumber+100, testutils.CertFilePath(certDir), testutils.KeyFilePath(certDir))
   642  	s.NoError(err)
   643  	s.NotNil(srvrCert)
   644  
   645  	time.Sleep(time.Second * 2) // let server refresh certs
   646  
   647  	tlsInfo, err = dialHelloAndGetTLSInfo(s.Suite, host, factory, factory.serverUsage)
   648  	s.validateTLSInfo(tlsInfo, err, serialNumber+100) // serial number of server cert after refresh
   649  }
   650  
   651  func (s *localStoreRPCSuite) validateTLSInfo(tlsInfo *credentials.TLSInfo, err error, serialNumber int64) {
   652  	s.NoError(err)
   653  	s.NotNil(tlsInfo)
   654  	s.NotNil(tlsInfo.State.PeerCertificates)
   655  	sn := (*tlsInfo.State.PeerCertificates[0].SerialNumber).Int64()
   656  	s.Equal(serialNumber, sn)
   657  }
   658  
   659  func (s *localStoreRPCSuite) TestClientForceTLS() {
   660  	options, err := s.frontendConfigRootCAForceTLSFactory.RPCFactory.GetFrontendGRPCServerOptions()
   661  	s.NoError(err)
   662  	s.Nil(options)
   663  }
   664  
   665  func (s *localStoreRPCSuite) TestSystemWorkerOnlyConfig() {
   666  	localStoreSystemWorkerOnly := &config.Global{
   667  		Membership: s.membershipConfig,
   668  		TLS: config.RootTLS{
   669  			SystemWorker: s.systemWorkerOnly,
   670  		},
   671  	}
   672  	provider, err := encryption.NewTLSConfigProviderFromConfig(localStoreSystemWorkerOnly.TLS, metrics.NoopMetricsHandler, s.logger, nil)
   673  	s.NoError(err)
   674  	tlsConfig, err := provider.GetFrontendClientConfig()
   675  	s.NoError(err)
   676  	s.NotNil(tlsConfig)
   677  	s.NotNil(tlsConfig.GetClientCertificate)
   678  	cert, err := tlsConfig.GetClientCertificate(nil)
   679  	s.NoError(err)
   680  	s.NotNil(cert)
   681  }