From 7c47afd7d252663e15d79d2c11d7a63ad867e4e5 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 5 Jun 2018 18:48:17 -0700 Subject: [PATCH] e2e: test client-side cipher suites with curl Signed-off-by: Gyuho Lee --- e2e/etcd_test.go | 7 +++++++ e2e/v2_curl_test.go | 6 ++++++ e2e/v3_curl_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/e2e/etcd_test.go b/e2e/etcd_test.go index c15f95d6f..411b41603 100644 --- a/e2e/etcd_test.go +++ b/e2e/etcd_test.go @@ -179,6 +179,8 @@ type etcdProcessClusterConfig struct { initialToken string quotaBackendBytes int64 noStrictReconfig bool + + cipherSuites []string } // newEtcdProcessCluster launches a new cluster from etcd processes, returning @@ -384,6 +386,11 @@ func (cfg *etcdProcessClusterConfig) tlsArgs() (args []string) { args = append(args, tlsPeerArgs...) } } + + if len(cfg.cipherSuites) > 0 { + args = append(args, "--cipher-suites", strings.Join(cfg.cipherSuites, ",")) + } + return args } diff --git a/e2e/v2_curl_test.go b/e2e/v2_curl_test.go index 289d64c0d..93370abc0 100644 --- a/e2e/v2_curl_test.go +++ b/e2e/v2_curl_test.go @@ -127,6 +127,8 @@ type cURLReq struct { value string expected string + + ciphers string } // cURLPrefixArgs builds the beginning of a curl command for a given key @@ -156,6 +158,10 @@ func cURLPrefixArgs(clus *etcdProcessCluster, method string, req cURLReq) []stri cmdArgs = append(cmdArgs, "-m", fmt.Sprintf("%d", req.timeout)) } + if req.ciphers != "" { + cmdArgs = append(cmdArgs, "--ciphers", req.ciphers) + } + switch method { case "POST", "PUT": dt := req.value diff --git a/e2e/v3_curl_test.go b/e2e/v3_curl_test.go index cb140f2b6..56652b82e 100644 --- a/e2e/v3_curl_test.go +++ b/e2e/v3_curl_test.go @@ -16,12 +16,14 @@ package e2e import ( "encoding/json" + "fmt" "path" "testing" epb "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb" 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" ) @@ -281,3 +283,45 @@ type campaignResponse struct { Lease string `json:"lease,omitempty"` } `json:"leader,omitempty"` } + +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) + } +}