mirror of
https://git.yoctoproject.org/poky
synced 2026-06-01 13:09:50 +00:00
go 1.22.12: Fix CVE-2025-61730
Upstream Repository: https://github.com/golang/go.git Bug details: https://nvd.nist.gov/vuln/detail/CVE-2025-61730 Type: Security Fix CVE: CVE-2025-61730 Score: 4.2 Patch: https://github.com/golang/go/commit/ad2cd043db66 (From OE-Core rev: 71f645d9ebf77d30744780e777955a6c7e28258b) Signed-off-by: Deepak Rathore <deeratho@cisco.com> Signed-off-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Paul Barker <paul@pbarker.dev> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
b16633f3c6
commit
dde29170e3
@@ -31,6 +31,7 @@ SRC_URI += "\
|
|||||||
file://CVE-2025-61724.patch \
|
file://CVE-2025-61724.patch \
|
||||||
file://CVE-2025-61727.patch \
|
file://CVE-2025-61727.patch \
|
||||||
file://CVE-2025-61729.patch \
|
file://CVE-2025-61729.patch \
|
||||||
|
file://CVE-2025-61730.patch \
|
||||||
"
|
"
|
||||||
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
|
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,460 @@
|
|||||||
|
From 2cfa797798cc982973d194eca3be19fb1f092556 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roland Shoemaker <roland@golang.org>
|
||||||
|
Date: Mon, 24 Nov 2025 14:03:10 -0800
|
||||||
|
Subject: [PATCH] [release-branch.go1.24] crypto/tls: reject trailing messages
|
||||||
|
after client/server hello
|
||||||
|
|
||||||
|
For TLS 1.3, after procesesing the server/client hello, if there isn't a
|
||||||
|
CCS message, reject the trailing messages which were appended to the
|
||||||
|
hello messages. This prevents an on-path attacker from injecting
|
||||||
|
plaintext messages into the handshake.
|
||||||
|
|
||||||
|
Additionally, check that we don't have any buffered messages before we
|
||||||
|
switch the read traffic secret regardless, since any buffered messages
|
||||||
|
would have been under an old key which is no longer appropriate.
|
||||||
|
|
||||||
|
We also invert the ordering of setting the read/write secrets so that if
|
||||||
|
we fail when changing the read secret we send the alert using the
|
||||||
|
correct write secret.
|
||||||
|
|
||||||
|
Updates #76443
|
||||||
|
Fixes #76854
|
||||||
|
Fixes CVE-2025-61730
|
||||||
|
|
||||||
|
CVE: CVE-2025-61730
|
||||||
|
Upstream-Status: Backport [https://github.com/golang/go/commit/ad2cd043db66]
|
||||||
|
|
||||||
|
Backport Changes:
|
||||||
|
- In version 1.24, the doHelloRetryRequest function defined in handshake_server_tls13.go
|
||||||
|
returns keyshare and error, but in version 1.22 it only returns error. The backport
|
||||||
|
was adjusted accordingly and These changes were introduced by commit
|
||||||
|
https://github.com/golang/go/commit/d0edd9acc80a in version 1.24.
|
||||||
|
- In file src/crypto/tls/handshake_server_tls13.go, Replaced the function call
|
||||||
|
hs.handshakeSecret.ClientHandshakeTrafficSecret(hs.transcript) with
|
||||||
|
hs.suite.deriveSecret(hs.handshakeSecret, clientHandshakeTrafficLabel, hs.transcript).
|
||||||
|
This change is not present in version v1.22 and it was introduced by commit
|
||||||
|
https://github.com/golang/go/commit/743746a3a52d in version 1.24.
|
||||||
|
|
||||||
|
Change-Id: If6ba8ad16f48d5cd5db5574824062ad4244a5b52
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/724120
|
||||||
|
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
|
||||||
|
Reviewed-by: Michael Knyszek <mknyszek@google.com>
|
||||||
|
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
|
||||||
|
Reviewed-by: Coia Prant <coiaprant@gmail.com>
|
||||||
|
(cherry picked from commit 5046bdf8a612b35a2c1a9e168054c1d5c65e7dd7)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/731961
|
||||||
|
Reviewed-by: Damien Neil <dneil@google.com>
|
||||||
|
(cherry picked from commit ad2cd043db66cd36e1f55359638729d2c8ff3d99)
|
||||||
|
Signed-off-by: Deepak Rathore <deeratho@cisco.com>
|
||||||
|
---
|
||||||
|
src/crypto/tls/conn.go | 39 ++++++-
|
||||||
|
src/crypto/tls/handshake_client_tls13.go | 22 ++--
|
||||||
|
src/crypto/tls/handshake_server_tls13.go | 39 ++++---
|
||||||
|
src/crypto/tls/handshake_test.go | 140 +++++++++++++++++++++++
|
||||||
|
src/crypto/tls/quic.go | 11 +-
|
||||||
|
5 files changed, 219 insertions(+), 32 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
|
||||||
|
index 0e4669866e..08609ce17b 100644
|
||||||
|
--- a/src/crypto/tls/conn.go
|
||||||
|
+++ b/src/crypto/tls/conn.go
|
||||||
|
@@ -225,6 +225,9 @@ func (hc *halfConn) changeCipherSpec() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
+// setTrafficSecret sets the traffic secret for the given encryption level. setTrafficSecret
|
||||||
|
+// should not be called directly, but rather through the Conn setWriteTrafficSecret and
|
||||||
|
+// setReadTrafficSecret wrapper methods.
|
||||||
|
func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, level QUICEncryptionLevel, secret []byte) {
|
||||||
|
hc.trafficSecret = secret
|
||||||
|
hc.level = level
|
||||||
|
@@ -1321,9 +1324,6 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
|
||||||
|
return c.in.setErrorLocked(c.sendAlert(alertInternalError))
|
||||||
|
}
|
||||||
|
|
||||||
|
- newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret)
|
||||||
|
- c.in.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
|
||||||
|
-
|
||||||
|
if keyUpdate.updateRequested {
|
||||||
|
c.out.Lock()
|
||||||
|
defer c.out.Unlock()
|
||||||
|
@@ -1341,7 +1341,12 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
|
||||||
|
}
|
||||||
|
|
||||||
|
newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret)
|
||||||
|
- c.out.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
|
||||||
|
+ c.setWriteTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret)
|
||||||
|
+ if err := c.setReadTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret); err != nil {
|
||||||
|
+ return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
@@ -1572,7 +1577,9 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
|
||||||
|
// Provide the 1-RTT read secret now that the handshake is complete.
|
||||||
|
// The QUIC layer MUST NOT decrypt 1-RTT packets prior to completing
|
||||||
|
// the handshake (RFC 9001, Section 5.7).
|
||||||
|
- c.quicSetReadSecret(QUICEncryptionLevelApplication, c.cipherSuite, c.in.trafficSecret)
|
||||||
|
+ if err := c.quicSetReadSecret(QUICEncryptionLevelApplication, c.cipherSuite, c.in.trafficSecret); err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
var a alert
|
||||||
|
c.out.Lock()
|
||||||
|
@@ -1664,3 +1671,25 @@ func (c *Conn) VerifyHostname(host string) error {
|
||||||
|
}
|
||||||
|
return c.peerCertificates[0].VerifyHostname(host)
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+// setReadTrafficSecret sets the read traffic secret for the given encryption level. If
|
||||||
|
+// being called at the same time as setWriteTrafficSecret, the caller must ensure the call
|
||||||
|
+// to setWriteTrafficSecret happens first so any alerts are sent at the write level.
|
||||||
|
+func (c *Conn) setReadTrafficSecret(suite *cipherSuiteTLS13, level QUICEncryptionLevel, secret []byte) error {
|
||||||
|
+ // Ensure that there are no buffered handshake messages before changing the
|
||||||
|
+ // read keys, since that can cause messages to be parsed that were encrypted
|
||||||
|
+ // using old keys which are no longer appropriate.
|
||||||
|
+ if c.hand.Len() != 0 {
|
||||||
|
+ c.sendAlert(alertUnexpectedMessage)
|
||||||
|
+ return errors.New("tls: handshake buffer not empty before setting read traffic secret")
|
||||||
|
+ }
|
||||||
|
+ c.in.setTrafficSecret(suite, level, secret)
|
||||||
|
+ return nil
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// setWriteTrafficSecret sets the write traffic secret for the given encryption level. If
|
||||||
|
+// being called at the same time as setReadTrafficSecret, the caller must ensure the call
|
||||||
|
+// to setWriteTrafficSecret happens first so any alerts are sent at the write level.
|
||||||
|
+func (c *Conn) setWriteTrafficSecret(suite *cipherSuiteTLS13, level QUICEncryptionLevel, secret []byte) {
|
||||||
|
+ c.out.setTrafficSecret(suite, level, secret)
|
||||||
|
+}
|
||||||
|
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
|
||||||
|
index 2f59f6888c..68ff92beda 100644
|
||||||
|
--- a/src/crypto/tls/handshake_client_tls13.go
|
||||||
|
+++ b/src/crypto/tls/handshake_client_tls13.go
|
||||||
|
@@ -393,17 +393,18 @@ func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
|
||||||
|
|
||||||
|
clientSecret := hs.suite.deriveSecret(handshakeSecret,
|
||||||
|
clientHandshakeTrafficLabel, hs.transcript)
|
||||||
|
- c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
|
||||||
|
+ c.setWriteTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
|
||||||
|
serverSecret := hs.suite.deriveSecret(handshakeSecret,
|
||||||
|
serverHandshakeTrafficLabel, hs.transcript)
|
||||||
|
- c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
|
||||||
|
+ if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret); err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if c.quic != nil {
|
||||||
|
- if c.hand.Len() != 0 {
|
||||||
|
- c.sendAlert(alertUnexpectedMessage)
|
||||||
|
- }
|
||||||
|
c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
|
||||||
|
- c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
|
||||||
|
+ if err := c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret); err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
|
||||||
|
@@ -606,7 +607,9 @@ func (hs *clientHandshakeStateTLS13) readServerFinished() error {
|
||||||
|
clientApplicationTrafficLabel, hs.transcript)
|
||||||
|
serverSecret := hs.suite.deriveSecret(hs.masterSecret,
|
||||||
|
serverApplicationTrafficLabel, hs.transcript)
|
||||||
|
- c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
|
||||||
|
+ if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret); err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
|
||||||
|
err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
|
||||||
|
if err != nil {
|
||||||
|
@@ -702,7 +705,7 @@ func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
- c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
|
||||||
|
+ c.setWriteTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
|
||||||
|
|
||||||
|
if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
|
||||||
|
c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
|
||||||
|
@@ -710,9 +713,6 @@ func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.quic != nil {
|
||||||
|
- if c.hand.Len() != 0 {
|
||||||
|
- c.sendAlert(alertUnexpectedMessage)
|
||||||
|
- }
|
||||||
|
c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, hs.trafficSecret)
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
|
||||||
|
index 21d798de37..5aa69e9640 100644
|
||||||
|
--- a/src/crypto/tls/handshake_server_tls13.go
|
||||||
|
+++ b/src/crypto/tls/handshake_server_tls13.go
|
||||||
|
@@ -380,7 +380,9 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
earlyTrafficSecret := hs.suite.deriveSecret(hs.earlySecret, clientEarlyTrafficLabel, transcript)
|
||||||
|
- c.quicSetReadSecret(QUICEncryptionLevelEarly, hs.suite.id, earlyTrafficSecret)
|
||||||
|
+ if err := c.quicSetReadSecret(QUICEncryptionLevelEarly, hs.suite.id, earlyTrafficSecret); err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
c.didResume = true
|
||||||
|
@@ -477,6 +479,14 @@ func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
|
||||||
|
func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error {
|
||||||
|
c := hs.c
|
||||||
|
|
||||||
|
+ // Make sure the client didn't send extra handshake messages alongside
|
||||||
|
+ // their initial client_hello. If they sent two client_hello messages,
|
||||||
|
+ // we will consume the second before they respond to the server_hello.
|
||||||
|
+ if c.hand.Len() != 0 {
|
||||||
|
+ c.sendAlert(alertUnexpectedMessage)
|
||||||
|
+ return errors.New("tls: handshake buffer not empty before HelloRetryRequest")
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// The first ClientHello gets double-hashed into the transcript upon a
|
||||||
|
// HelloRetryRequest. See RFC 8446, Section 4.4.1.
|
||||||
|
if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
|
||||||
|
@@ -615,19 +625,20 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
|
||||||
|
hs.handshakeSecret = hs.suite.extract(hs.sharedKey,
|
||||||
|
hs.suite.deriveSecret(earlySecret, "derived", nil))
|
||||||
|
|
||||||
|
- clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
|
||||||
|
- clientHandshakeTrafficLabel, hs.transcript)
|
||||||
|
- c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
|
||||||
|
serverSecret := hs.suite.deriveSecret(hs.handshakeSecret,
|
||||||
|
serverHandshakeTrafficLabel, hs.transcript)
|
||||||
|
- c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
|
||||||
|
+ c.setWriteTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
|
||||||
|
+ clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
|
||||||
|
+ clientHandshakeTrafficLabel, hs.transcript)
|
||||||
|
+ if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret); err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if c.quic != nil {
|
||||||
|
- if c.hand.Len() != 0 {
|
||||||
|
- c.sendAlert(alertUnexpectedMessage)
|
||||||
|
- }
|
||||||
|
c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
|
||||||
|
- c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
|
||||||
|
+ if err := c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret); err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret)
|
||||||
|
@@ -751,13 +762,9 @@ func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
|
||||||
|
clientApplicationTrafficLabel, hs.transcript)
|
||||||
|
serverSecret := hs.suite.deriveSecret(hs.masterSecret,
|
||||||
|
serverApplicationTrafficLabel, hs.transcript)
|
||||||
|
- c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
|
||||||
|
+ c.setWriteTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
|
||||||
|
|
||||||
|
if c.quic != nil {
|
||||||
|
- if c.hand.Len() != 0 {
|
||||||
|
- // TODO: Handle this in setTrafficSecret?
|
||||||
|
- c.sendAlert(alertUnexpectedMessage)
|
||||||
|
- }
|
||||||
|
c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, serverSecret)
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -992,7 +999,9 @@ func (hs *serverHandshakeStateTLS13) readClientFinished() error {
|
||||||
|
return errors.New("tls: invalid client finished hash")
|
||||||
|
}
|
||||||
|
|
||||||
|
- c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
|
||||||
|
+ if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret); err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
diff --git a/src/crypto/tls/handshake_test.go b/src/crypto/tls/handshake_test.go
|
||||||
|
index 27ab19ef31..4991a0e69b 100644
|
||||||
|
--- a/src/crypto/tls/handshake_test.go
|
||||||
|
+++ b/src/crypto/tls/handshake_test.go
|
||||||
|
@@ -6,6 +6,7 @@ package tls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
+ "context"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/hex"
|
||||||
|
@@ -533,3 +534,142 @@ var clientEd25519KeyPEM = testingKey(`
|
||||||
|
-----BEGIN TESTING KEY-----
|
||||||
|
MC4CAQAwBQYDK2VwBCIEINifzf07d9qx3d44e0FSbV4mC/xQxT644RRbpgNpin7I
|
||||||
|
-----END TESTING KEY-----`)
|
||||||
|
+
|
||||||
|
+func TestServerHelloTrailingMessage(t *testing.T) {
|
||||||
|
+ // In TLS 1.3 the change cipher spec message is optional. If a CCS message
|
||||||
|
+ // is not sent, after reading the ServerHello, the read traffic secret is
|
||||||
|
+ // set, and all following messages must be encrypted. If the server sends
|
||||||
|
+ // additional unencrypted messages in a record with the ServerHello, the
|
||||||
|
+ // client must either fail or ignore the additional messages.
|
||||||
|
+
|
||||||
|
+ c, s := localPipe(t)
|
||||||
|
+ go func() {
|
||||||
|
+ ctx := context.Background()
|
||||||
|
+ srv := Server(s, testConfig)
|
||||||
|
+ clientHello, _, err := srv.readClientHello(ctx)
|
||||||
|
+ if err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ hs := serverHandshakeStateTLS13{
|
||||||
|
+ c: srv,
|
||||||
|
+ ctx: ctx,
|
||||||
|
+ clientHello: clientHello,
|
||||||
|
+ }
|
||||||
|
+ if err := hs.processClientHello(); err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+ if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ record, err := concatHandshakeMessages(hs.hello, &encryptedExtensionsMsg{alpnProtocol: "h2"})
|
||||||
|
+ if err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if _, err := s.Write(record); err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+ srv.Close()
|
||||||
|
+ }()
|
||||||
|
+
|
||||||
|
+ cli := Client(c, testConfig)
|
||||||
|
+ expectedErr := "tls: handshake buffer not empty before setting read traffic secret"
|
||||||
|
+ if err := cli.Handshake(); err == nil {
|
||||||
|
+ t.Fatal("expected error from incomplete handshake, got nil")
|
||||||
|
+ } else if err.Error() != expectedErr {
|
||||||
|
+ t.Fatalf("expected error %q, got %q", expectedErr, err.Error())
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func TestClientHelloTrailingMessage(t *testing.T) {
|
||||||
|
+ // Same as TestServerHelloTrailingMessage but for the client side.
|
||||||
|
+
|
||||||
|
+ c, s := localPipe(t)
|
||||||
|
+ go func() {
|
||||||
|
+ cli := Client(c, testConfig)
|
||||||
|
+
|
||||||
|
+ hello, _, _, err := cli.makeClientHello()
|
||||||
|
+ if err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ record, err := concatHandshakeMessages(hello, &certificateMsgTLS13{})
|
||||||
|
+ if err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if _, err := c.Write(record); err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+ cli.Close()
|
||||||
|
+ }()
|
||||||
|
+
|
||||||
|
+ srv := Server(s, testConfig)
|
||||||
|
+ expectedErr := "tls: handshake buffer not empty before setting read traffic secret"
|
||||||
|
+ if err := srv.Handshake(); err == nil {
|
||||||
|
+ t.Fatal("expected error from incomplete handshake, got nil")
|
||||||
|
+ } else if err.Error() != expectedErr {
|
||||||
|
+ t.Fatalf("expected error %q, got %q", expectedErr, err.Error())
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func TestDoubleClientHelloHRR(t *testing.T) {
|
||||||
|
+ // If a client sends two ClientHello messages in a single record, and the
|
||||||
|
+ // server sends a HRR after reading the first ClientHello, the server must
|
||||||
|
+ // either fail or ignore the trailing ClientHello.
|
||||||
|
+
|
||||||
|
+ c, s := localPipe(t)
|
||||||
|
+
|
||||||
|
+ go func() {
|
||||||
|
+ cli := Client(c, testConfig)
|
||||||
|
+
|
||||||
|
+ hello, _, _, err := cli.makeClientHello()
|
||||||
|
+ if err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+ hello.keyShares = nil
|
||||||
|
+
|
||||||
|
+ record, err := concatHandshakeMessages(hello, hello)
|
||||||
|
+ if err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if _, err := c.Write(record); err != nil {
|
||||||
|
+ testFatal(t, err)
|
||||||
|
+ }
|
||||||
|
+ cli.Close()
|
||||||
|
+ }()
|
||||||
|
+
|
||||||
|
+ srv := Server(s, testConfig)
|
||||||
|
+ expectedErr := "tls: handshake buffer not empty before HelloRetryRequest"
|
||||||
|
+ if err := srv.Handshake(); err == nil {
|
||||||
|
+ t.Fatal("expected error from incomplete handshake, got nil")
|
||||||
|
+ } else if err.Error() != expectedErr {
|
||||||
|
+ t.Fatalf("expected error %q, got %q", expectedErr, err.Error())
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// concatHandshakeMessages marshals and concatenates the given handshake
|
||||||
|
+// messages into a single record.
|
||||||
|
+func concatHandshakeMessages(msgs ...handshakeMessage) ([]byte, error) {
|
||||||
|
+ var marshalled []byte
|
||||||
|
+ for _, msg := range msgs {
|
||||||
|
+ data, err := msg.marshal()
|
||||||
|
+ if err != nil {
|
||||||
|
+ return nil, err
|
||||||
|
+ }
|
||||||
|
+ marshalled = append(marshalled, data...)
|
||||||
|
+ }
|
||||||
|
+ m := len(marshalled)
|
||||||
|
+ outBuf := make([]byte, recordHeaderLen)
|
||||||
|
+ outBuf[0] = byte(recordTypeHandshake)
|
||||||
|
+ vers := VersionTLS12
|
||||||
|
+ outBuf[1] = byte(vers >> 8)
|
||||||
|
+ outBuf[2] = byte(vers)
|
||||||
|
+ outBuf[3] = byte(m >> 8)
|
||||||
|
+ outBuf[4] = byte(m)
|
||||||
|
+ outBuf = append(outBuf, marshalled...)
|
||||||
|
+ return outBuf, nil
|
||||||
|
+}
|
||||||
|
diff --git a/src/crypto/tls/quic.go b/src/crypto/tls/quic.go
|
||||||
|
index 3518169bf7..aa14f1dadb 100644
|
||||||
|
--- a/src/crypto/tls/quic.go
|
||||||
|
+++ b/src/crypto/tls/quic.go
|
||||||
|
@@ -323,13 +323,22 @@ func (c *Conn) quicReadHandshakeBytes(n int) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
-func (c *Conn) quicSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
|
||||||
|
+func (c *Conn) quicSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) error {
|
||||||
|
+ // Ensure that there are no buffered handshake messages before changing the
|
||||||
|
+ // read keys, since that can cause messages to be parsed that were encrypted
|
||||||
|
+ // using old keys which are no longer appropriate.
|
||||||
|
+ // TODO(roland): we should merge this check with the similar one in setReadTrafficSecret.
|
||||||
|
+ if c.hand.Len() != 0 {
|
||||||
|
+ c.sendAlert(alertUnexpectedMessage)
|
||||||
|
+ return errors.New("tls: handshake buffer not empty before setting read traffic secret")
|
||||||
|
+ }
|
||||||
|
c.quic.events = append(c.quic.events, QUICEvent{
|
||||||
|
Kind: QUICSetReadSecret,
|
||||||
|
Level: level,
|
||||||
|
Suite: suite,
|
||||||
|
Data: secret,
|
||||||
|
})
|
||||||
|
+ return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) quicSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
|
||||||
|
--
|
||||||
|
2.35.6
|
||||||
Reference in New Issue
Block a user