Description
A TLS 1.3 peer can send syntactically valid post-handshake messages, such as one NewSessionTicket per encrypted handshake record, without producing application data. The record retry counter can be reset for each non-empty handshake record before post-handshake handling determines whether useful progress occurred.
This is an availability issue with limited impact. A malicious peer can already stall by withholding data, and read deadlines mitigate the behavior.
Specification
RFC 8446 Section 4.6 defines TLS 1.3 post-handshake messages such as NewSessionTicket. This issue is mainly an implementation progress-accounting bug, not a direct violation of a TLS wire-format rule.
Code references
.bughunt/master-findings.md:232 through .bughunt/master-findings.md:251 records the local analysis and affected functions.
go/src/crypto/tls/conn.go:698 through go/src/crypto/tls/conn.go:701 resets retryCount for non-empty non-alert records before post-handshake semantics are processed.
go/src/crypto/tls/conn.go:1308 through go/src/crypto/tls/conn.go:1320 increments retryCount while handling TLS 1.3 post-handshake messages.
go/src/crypto/tls/conn.go:1390 through go/src/crypto/tls/conn.go:1398 loops in Conn.Read until application data is available.
go/src/crypto/tls/handshake_server_tls13.go:1006 through go/src/crypto/tls/handshake_server_tls13.go:1020 shows the server-side NewSessionTicket generation path useful for reproducing repeated tickets.
Test case
This can be a Go TLS integration test using net.Pipe: complete a TLS 1.3 handshake, repeatedly send post-handshake tickets without application data, then assert that the client eventually returns a non-advancing-record error rather than spinning until a deadline.
A bogo test may also be possible by scripting a peer that sends repeated post-handshake NewSessionTicket records and expects Go to reject them after the non-advancing record limit.
Description
A TLS 1.3 peer can send syntactically valid post-handshake messages, such as one
NewSessionTicketper encrypted handshake record, without producing application data. The record retry counter can be reset for each non-empty handshake record before post-handshake handling determines whether useful progress occurred.This is an availability issue with limited impact. A malicious peer can already stall by withholding data, and read deadlines mitigate the behavior.
Specification
RFC 8446 Section 4.6 defines TLS 1.3 post-handshake messages such as NewSessionTicket. This issue is mainly an implementation progress-accounting bug, not a direct violation of a TLS wire-format rule.
Code references
.bughunt/master-findings.md:232through.bughunt/master-findings.md:251records the local analysis and affected functions.go/src/crypto/tls/conn.go:698throughgo/src/crypto/tls/conn.go:701resetsretryCountfor non-empty non-alert records before post-handshake semantics are processed.go/src/crypto/tls/conn.go:1308throughgo/src/crypto/tls/conn.go:1320incrementsretryCountwhile handling TLS 1.3 post-handshake messages.go/src/crypto/tls/conn.go:1390throughgo/src/crypto/tls/conn.go:1398loops inConn.Readuntil application data is available.go/src/crypto/tls/handshake_server_tls13.go:1006throughgo/src/crypto/tls/handshake_server_tls13.go:1020shows the server-side NewSessionTicket generation path useful for reproducing repeated tickets.Test case
This can be a Go TLS integration test using
net.Pipe: complete a TLS 1.3 handshake, repeatedly send post-handshake tickets without application data, then assert that the client eventually returns a non-advancing-record error rather than spinning until a deadline.A bogo test may also be possible by scripting a peer that sends repeated post-handshake
NewSessionTicketrecords and expects Go to reject them after the non-advancing record limit.