Skip to content

crypto/tls: Can't create a request using just one cipher suite with TLS v1.3  #68854

Description

@afrancoc2000

Go version

go version go1.22.4 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.4'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/workspaces/MyProject/go.mod'
GOWORK='/workspaces/MyProject/go.work'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2224093303=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I'm doing some tests in my project to demonstrate the support for different cipher suites but when I use TLS V1.3, 3 default cipher suites are added, making it impossible to test just one cipher suite in my client request.

package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"

	"github.com/gorilla/websocket"
)

const (
	reqURL        = "wss://localhost:8080/test"
	reqHost       = "example.com"
	reqBody       = "Hello, world!"
	useCerts      = false
	CipherSuite   = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
	minTLSVersion = tls.VersionTLS12
	maxTLSVersion = tls.VersionTLS13
)

func main() {
	secure := strings.HasPrefix(reqURL, "wss")

	headers := http.Header{}
	headers.Add("Host", reqHost)

	fmt.Printf("Making ws request to %s\n", reqURL)

	dialer := websocket.DefaultDialer
	if secure {
		tlsConfig := &tls.Config{
			MinVersion: minTLSVersion,
			MaxVersion: maxTLSVersion,
		}
		if useCerts {
			caCert, err := os.ReadFile("../../certs/server-cert.pem")
			if err != nil {
				log.Fatalf("failed to read CA certificate: %v", err)
			}
			caCertPool := x509.NewCertPool()
			caCertPool.AppendCertsFromPEM(caCert)
			tlsConfig.RootCAs = caCertPool
		} else {
			tlsConfig.InsecureSkipVerify = true
		}

		if CipherSuite != 0 {
			tlsConfig.CipherSuites = []uint16{CipherSuite}
		}

		dialer = &websocket.Dialer{
			TLSClientConfig: tlsConfig,
		}
	}
	conn, _, err := dialer.Dial(reqURL, headers)
	if err != nil {
		panic(fmt.Errorf("error setting a websocket connection, url: %s, error: %v", reqURL, err))
	}
	defer conn.Close()

	err = conn.WriteMessage(websocket.TextMessage, []byte(reqBody))
	if err != nil {
		panic(fmt.Errorf("error sending a message to websockets: %w", err))
	}
	fmt.Printf("Sent message: %s\n", reqBody)

	_, message, err := conn.ReadMessage()
	if err != nil {
		panic(fmt.Errorf("error reading a message from websockets: %w", err))
	}
	fmt.Printf("Received message: %s\n", message)
}

My client is for websockets but you can see the issue also happening in http requests.

What did you see happen?

Doing this I can see in wire shark my client offering a request including my chosen cipher suite plus: TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256

image

and if I select to use only TLS v1.3 not even my cipher suite shows up just the v1.3 defaults.

What did you expect to see?

Only my cipher suite being used from the client request, so I can test different cipher suites scenarios. I'm setting my cipher suite so I expect the request to use it, is not the default behavior when no cipher suite is defined.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions