Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
afrancoc2000 opened this issue Aug 13, 2024 · 9 comments
Closed

Comments

@afrancoc2000
Copy link

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.

@seankhliao
Copy link
Member

The fact that TLS 1.3 cipher suites are non configurable is intended.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Aug 13, 2024
@afrancoc2000
Copy link
Author

why? it can be done using curl, how can you then choose to use one specific cipher suite? shouldn't that be documented somewhere? why allowing to set cipher suites at all if you're going to ignore them?

@seankhliao
Copy link
Member

It is documented on the Cipher suites field.
Config was allowed for < 1.3 because some of them were less secure.
Testing / educational uses are considered out of scope for crypto/tls, the goal is for secure by default usages.

@afrancoc2000
Copy link
Author

got it thanks

@MajedMuhammad
Copy link

The fact that TLS 1.3 cipher suites are non configurable is intended.

@seankhliao @FiloSottile
I appreciate your work.
#29349 I tried to comment there, but sadly it is locked.
So I am avoiding to create separate issue and writing here.

I appreciate your work, but I must express my frustration with the non-configurable nature of the TLS 1.3 cipher suites in the standard library.

As maintainers, you should respect developers' rights to configure libraries according to their application requirements rather than impose your design choices. It is baffling that there is no option for selecting specific cipher suites when they are supported by the library.

Most Golang standard libraries allow for configurations, and this restriction undermines the flexibility developers expect. This needs to change.

@MajedMuhammad
Copy link

@seankhliao @FiloSottile
Heads-up!

@MajedMuhammad
Copy link

@seankhliao @FiloSottile
It needs to change, Gophers!
Could you take 25 seconds to respond, please?

@golang golang locked as resolved and limited conversation to collaborators Mar 6, 2025
@ianlancetaylor
Copy link
Contributor

See, for example, the explanation at https://go.dev/issue/45430.

The Go project aims for the best choices for the overall ecosystem. People who need different choices are free to copy the package and modify it as they see fit.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants