Commit a1dbfee1 authored by Adam Langley's avatar Adam Langley

crypto/tls: ignore empty TLS records.

OpenSSL can be configured to send empty records in order to randomise
the CBC IV. This is an early version of 1/n-1 record splitting (that Go
does) and is quite reasonable, but it results in tls.Conn.Read
returning (0, nil).

This change ignores up to 100 consecutive, empty records to avoid
returning (0, nil) to callers.

Fixes 5309.

R=golang-dev, r, minux.ma
CC=golang-dev
https://golang.org/cl/8852044
parent 133cdb67
...@@ -792,21 +792,32 @@ func (c *Conn) Read(b []byte) (n int, err error) { ...@@ -792,21 +792,32 @@ func (c *Conn) Read(b []byte) (n int, err error) {
c.in.Lock() c.in.Lock()
defer c.in.Unlock() defer c.in.Unlock()
for c.input == nil && c.error() == nil { // Some OpenSSL servers send empty records in order to randomize the
if err := c.readRecord(recordTypeApplicationData); err != nil { // CBC IV. So this loop ignores a limited number of empty records.
// Soft error, like EAGAIN const maxConsecutiveEmptyRecords = 100
for emptyRecordCount := 0; emptyRecordCount <= maxConsecutiveEmptyRecords; emptyRecordCount++ {
for c.input == nil && c.error() == nil {
if err := c.readRecord(recordTypeApplicationData); err != nil {
// Soft error, like EAGAIN
return 0, err
}
}
if err := c.error(); err != nil {
return 0, err return 0, err
} }
n, err = c.input.Read(b)
if c.input.off >= len(c.input.data) {
c.in.freeBlock(c.input)
c.input = nil
}
if n != 0 || err != nil {
return n, err
}
} }
if err := c.error(); err != nil {
return 0, err return 0, io.ErrNoProgress
}
n, err = c.input.Read(b)
if c.input.off >= len(c.input.data) {
c.in.freeBlock(c.input)
c.input = nil
}
return n, nil
} }
// Close closes the connection. // Close closes the connection.
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment