Backport tls 1.3 support.

Signed-off-by: James Blair <mail@jamesblair.net>
This commit is contained in:
James Blair
2023-03-15 14:10:14 +13:00
parent 6ddb23ce7a
commit 358bcf3fb6
10 changed files with 357 additions and 11 deletions

View File

@@ -21,6 +21,7 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"go.etcd.io/etcd/pkg/v3/expect"
)
@@ -374,3 +375,32 @@ func TestBootstrapDefragFlag(t *testing.T) {
t.Fatal(err)
}
}
func TestEtcdTLSVersion(t *testing.T) {
skipInShortMode(t)
d := t.TempDir()
proc, err := spawnCmd(
[]string{
binDir + "/etcd",
"--data-dir", d,
"--name", "e1",
"--listen-client-urls", "https://0.0.0.0:0",
"--advertise-client-urls", "https://0.0.0.0:0",
"--listen-peer-urls", fmt.Sprintf("https://127.0.0.1:%d", etcdProcessBasePort),
"--initial-advertise-peer-urls", fmt.Sprintf("https://127.0.0.1:%d", etcdProcessBasePort),
"--initial-cluster", fmt.Sprintf("e1=https://127.0.0.1:%d", etcdProcessBasePort),
"--peer-cert-file", certPath,
"--peer-key-file", privateKeyPath,
"--cert-file", certPath2,
"--key-file", privateKeyPath2,
"--tls-min-version", "TLS1.2",
"--tls-max-version", "TLS1.3",
}, nil,
)
assert.NoError(t, err)
assert.NoError(t, waitReadyExpectProc(proc, etcdServerReadyLines), "did not receive expected output from etcd process")
assert.NoError(t, proc.Stop())
}

View File

@@ -20,6 +20,7 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"go.etcd.io/etcd/client/v3"
"google.golang.org/grpc"
)
@@ -47,6 +48,12 @@ func testTLSCipherSuites(t *testing.T, valid bool) {
srvTLS.CipherSuites, cliTLS.CipherSuites = cipherSuites[:2], cipherSuites[2:]
}
// go1.13 enables TLS 1.3 by default
// and in TLS 1.3, cipher suites are not configurable,
// so setting Max TLS version to TLS 1.2 to test cipher config.
srvTLS.MaxVersion = tls.VersionTLS12
cliTLS.MaxVersion = tls.VersionTLS12
clus := NewClusterV3(t, &ClusterConfig{Size: 1, ClientTLS: &srvTLS})
defer clus.Terminate(t)
@@ -70,3 +77,67 @@ func testTLSCipherSuites(t *testing.T, valid bool) {
t.Fatalf("expected TLS handshake success, got %v", cerr)
}
}
func TestTLSMinMaxVersion(t *testing.T) {
BeforeTest(t)
tests := []struct {
name string
minVersion uint16
maxVersion uint16
expectError bool
}{
{
name: "Connect with default TLS version should succeed",
minVersion: 0,
maxVersion: 0,
},
{
name: "Connect with TLS 1.2 only should fail",
minVersion: tls.VersionTLS12,
maxVersion: tls.VersionTLS12,
expectError: true,
},
{
name: "Connect with TLS 1.2 and 1.3 should succeed",
minVersion: tls.VersionTLS12,
maxVersion: tls.VersionTLS13,
},
{
name: "Connect with TLS 1.3 only should succeed",
minVersion: tls.VersionTLS13,
maxVersion: tls.VersionTLS13,
},
}
// Configure server to support TLS 1.3 only.
srvTLS := testTLSInfo
srvTLS.MinVersion = tls.VersionTLS13
srvTLS.MaxVersion = tls.VersionTLS13
clus := NewClusterV3(t, &ClusterConfig{Size: 1, ClientTLS: &srvTLS})
defer clus.Terminate(t)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cc, err := testTLSInfo.ClientConfig()
assert.NoError(t, err)
cc.MinVersion = tt.minVersion
cc.MaxVersion = tt.maxVersion
cli, cerr := NewClient(t, clientv3.Config{
Endpoints: []string{clus.Members[0].GRPCURL()},
DialTimeout: time.Second,
DialOptions: []grpc.DialOption{grpc.WithBlock()},
TLS: cc,
})
if cerr != nil {
assert.True(t, tt.expectError, "got TLS handshake error while expecting success: %v", cerr)
assert.Equal(t, context.DeadlineExceeded, cerr, "expected %v with TLS handshake failure, got %v", context.DeadlineExceeded, cerr)
return
}
cli.Close()
})
}
}