Skip to content

crypto/tls: ECH decodeInnerClientHello incorrectly rejects ClientHello with GREASE values in supportedVersions #71642

Description

@gdy666

Problem Description

In Golang's crypto/tls implementation, the function decodeInnerClientHello contains the following code:

if len(inner.supportedVersions) != 1 || (len(inner.supportedVersions) >= 1 && inner.supportedVersions[0] != VersionTLS13) {
    return nil, errors.New("tls: client sent encrypted_client_hello extension and offered incompatible versions")
}

This logic requires supportedVersions to contain exactly one version, which must be TLS 1.3, otherwise, the connection is rejected.

However, Chrome and Edge use the GREASE mechanism, which means supportedVersions may contain multiple values, such as:

supported_versions: [GREASE, TLS 1.3]

Since len(inner.supportedVersions) != 1, Golang incorrectly rejects these connections, causing Chrome and Edge to fail when accessing a Golang Web server with ECH enabled, while Firefox works fine.

Steps to Reproduce

Start a Golang crypto/tls server with ECH enabled.
Try accessing the server using Chrome or Edge.
The connection fails with a TLS error in Chrome.
Try accessing the server using Firefox.
The connection works fine.

Expected Behavior

The server should accept connections as long as supportedVersions contains TLS 1.3, rather than rejecting them due to the GREASE mechanism.

Suggested Fix

Modify decodeInnerClientHello logic to:

Ignore GREASE values (i.e., values with the format 0xXAXA).
Allow multiple versions in supportedVersions, as long as TLS 1.3 is included.
Proposed Code Change

hasTLS13 := false
  for _, v := range inner.supportedVersions {
      if v == VersionTLS13 {
          hasTLS13 = true
          break
      }
  }

  if !hasTLS13 {
      return nil, errors.New("tls: client sent encrypted_client_hello extension but did not offer TLS 1.3")
  }

This ensures compatibility with Chrome and Edge while maintaining ECH security.

Related Fix Proposal
🔗 Gerrit CL: https://go-review.googlesource.com/c/go/+/648015

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixPendingIssues that have a fix which has not yet been reviewed or submitted.FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions