Browse Source

tests/e2e: test client-side cipher suites with curl

Signed-off-by: Gyuho Lee <gyuhox@gmail.com>
Gyuho Lee 7 years ago
parent
commit
d82f726da8
3 changed files with 55 additions and 0 deletions
  1. 6 0
      tests/e2e/cluster_test.go
  2. 6 0
      tests/e2e/v2_curl_test.go
  3. 43 0
      tests/e2e/v3_curl_test.go

+ 6 - 0
tests/e2e/cluster_test.go

@@ -117,6 +117,8 @@ type etcdProcessClusterConfig struct {
 	isClientAutoTLS       bool
 	isClientCRL           bool
 
+	cipherSuites []string
+
 	forceNewCluster     bool
 	initialToken        string
 	quotaBackendBytes   int64
@@ -307,6 +309,10 @@ func (cfg *etcdProcessClusterConfig) tlsArgs() (args []string) {
 		args = append(args, "--client-crl-file", crlPath, "--client-cert-auth")
 	}
 
+	if len(cfg.cipherSuites) > 0 {
+		args = append(args, "--cipher-suites", strings.Join(cfg.cipherSuites, ","))
+	}
+
 	return args
 }
 

+ 6 - 0
tests/e2e/v2_curl_test.go

@@ -130,6 +130,8 @@ type cURLReq struct {
 	header   string
 
 	metricsURLScheme string
+
+	ciphers string
 }
 
 // cURLPrefixArgs builds the beginning of a curl command for a given key
@@ -168,6 +170,10 @@ func cURLPrefixArgs(clus *etcdProcessCluster, method string, req cURLReq) []stri
 		cmdArgs = append(cmdArgs, "-H", req.header)
 	}
 
+	if req.ciphers != "" {
+		cmdArgs = append(cmdArgs, "--ciphers", req.ciphers)
+	}
+
 	switch method {
 	case "POST", "PUT":
 		dt := req.value

+ 43 - 0
tests/e2e/v3_curl_test.go

@@ -26,6 +26,7 @@ import (
 	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
 	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 	"github.com/coreos/etcd/pkg/testutil"
+	"github.com/coreos/etcd/version"
 
 	"github.com/grpc-ecosystem/grpc-gateway/runtime"
 )
@@ -349,6 +350,48 @@ func testV3CurlResignMissiongLeaderKey(cx ctlCtx) {
 	}
 }
 
+func TestV3CurlCipherSuitesValid(t *testing.T)    { testV3CurlCipherSuites(t, true) }
+func TestV3CurlCipherSuitesMismatch(t *testing.T) { testV3CurlCipherSuites(t, false) }
+func testV3CurlCipherSuites(t *testing.T, valid bool) {
+	cc := configClientTLS
+	cc.clusterSize = 1
+	cc.cipherSuites = []string{
+		"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+		"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+		"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+		"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+		"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
+		"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
+	}
+	testFunc := cipherSuiteTestValid
+	if !valid {
+		testFunc = cipherSuiteTestMismatch
+	}
+	testCtl(t, testFunc, withCfg(cc))
+}
+
+func cipherSuiteTestValid(cx ctlCtx) {
+	if err := cURLGet(cx.epc, cURLReq{
+		endpoint:         "/metrics",
+		expected:         fmt.Sprintf(`etcd_server_version{server_version="%s"} 1`, version.Version),
+		metricsURLScheme: cx.cfg.metricsURLScheme,
+		ciphers:          "ECDHE-RSA-AES128-GCM-SHA256", // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+	}); err != nil {
+		cx.t.Fatalf("failed get with curl (%v)", err)
+	}
+}
+
+func cipherSuiteTestMismatch(cx ctlCtx) {
+	if err := cURLGet(cx.epc, cURLReq{
+		endpoint:         "/metrics",
+		expected:         "alert handshake failure",
+		metricsURLScheme: cx.cfg.metricsURLScheme,
+		ciphers:          "ECDHE-RSA-DES-CBC3-SHA", // TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+	}); err != nil {
+		cx.t.Fatalf("failed get with curl (%v)", err)
+	}
+}
+
 // to manually decode; JSON marshals integer fields with
 // string types, so can't unmarshal with epb.CampaignResponse
 type campaignResponse struct {