]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls: reject duplicate TLS 1.3 EncryptedExtensions
authorDaniel McCarney <daniel@binaryparadox.net>
Sat, 17 May 2025 15:33:07 +0000 (11:33 -0400)
committerGopher Robot <gobot@golang.org>
Wed, 21 May 2025 22:09:41 +0000 (15:09 -0700)
When a TLS 1.3 client processes the server's encryptedExtensionsMsg it
should reject instances that contain duplicate extension types.

RFC 8446 ยง4.2 says:
  There MUST NOT be more than one extension of the same type in a given
  extension block.

This update matches enforcement done in the client hello unmarshalling,
but applied to the TLS 1.3 encrypted extensions message unmarshalling.

Making this change also allows enabling the
DuplicateExtensionClient-TLS-TLS13 BoGo test.

Updates #72006

Change-Id: I27a2cd231e4b8762b0d9e2dbd3d8ddd5b87fd5d2
Reviewed-on: https://go-review.googlesource.com/c/go/+/673757
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
src/crypto/tls/bogo_config.json
src/crypto/tls/handshake_messages.go

index 8276d08d35142c03f8398cf9a7e8dc703565fcbb..1bc647ce6059685b9de01a1d44e5655f439fc423 100644 (file)
@@ -72,7 +72,6 @@
         "TicketSessionIDLength-33-TLS-TLS11": "TODO: first pass, this should be fixed",
         "UnsolicitedServerNameAck-TLS-TLS12": "TODO: first pass, this should be fixed",
         "TicketSessionIDLength-33-TLS-TLS12": "TODO: first pass, this should be fixed",
-        "DuplicateExtensionClient-TLS-TLS13": "TODO: first pass, this should be fixed",
         "UnsolicitedServerNameAck-TLS-TLS13": "TODO: first pass, this should be fixed",
         "RenegotiationInfo-Forbidden-TLS13": "TODO: first pass, this should be fixed",
         "EMS-Forbidden-TLS13": "TODO: first pass, this should be fixed",
index 6c6141c421ea34d26945d155df9a2b1c776f144a..ad3e5fa352f33d2cc76eb3bf6776b2ae1d7120fe 100644 (file)
@@ -1056,6 +1056,7 @@ func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
                return false
        }
 
+       seenExts := make(map[uint16]bool)
        for !extensions.Empty() {
                var extension uint16
                var extData cryptobyte.String
@@ -1064,6 +1065,11 @@ func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
                        return false
                }
 
+               if seenExts[extension] {
+                       return false
+               }
+               seenExts[extension] = true
+
                switch extension {
                case extensionALPN:
                        var protoList cryptobyte.String