Skip to content

Commit c099459

Browse files
woodsajbradfitz
woodsaj
authored andcommitted
crypto/tls: reject CT extension with no SCTs included
When the CT extension is enabled but no SCTs are present, the existing code calls "continue" which causes resizing the data byte slice to be skipped. In fact, such extensions should be rejected. Fixes #17958 Change-Id: Iad12da10d1ea72d04ae2e1012c28bb2636f06bcd Reviewed-on: https://go-review.googlesource.com/33265 Reviewed-by: Brad Fitzpatrick <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 5cd6ab5 commit c099459

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

src/crypto/tls/handshake_messages.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -802,12 +802,9 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
802802
}
803803
l := int(d[0])<<8 | int(d[1])
804804
d = d[2:]
805-
if len(d) != l {
805+
if len(d) != l || l == 0 {
806806
return false
807807
}
808-
if l == 0 {
809-
continue
810-
}
811808

812809
m.scts = make([][]byte, 0, 3)
813810
for len(d) != 0 {

src/crypto/tls/handshake_messages_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package tls
66

77
import (
8+
"bytes"
89
"math/rand"
910
"reflect"
1011
"testing"
@@ -260,3 +261,47 @@ func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value {
260261
}
261262
return reflect.ValueOf(s)
262263
}
264+
265+
func TestRejectEmptySCTList(t *testing.T) {
266+
// https://tools.ietf.org/html/rfc6962#section-3.3.1 specifies that
267+
// empty SCT lists are invalid.
268+
269+
var random [32]byte
270+
sct := []byte{0x42, 0x42, 0x42, 0x42}
271+
serverHello := serverHelloMsg{
272+
vers: VersionTLS12,
273+
random: random[:],
274+
scts: [][]byte{sct},
275+
}
276+
serverHelloBytes := serverHello.marshal()
277+
278+
var serverHelloCopy serverHelloMsg
279+
if !serverHelloCopy.unmarshal(serverHelloBytes) {
280+
t.Fatal("Failed to unmarshal initial message")
281+
}
282+
283+
// Change serverHelloBytes so that the SCT list is empty
284+
i := bytes.Index(serverHelloBytes, sct)
285+
if i < 0 {
286+
t.Fatal("Cannot find SCT in ServerHello")
287+
}
288+
289+
var serverHelloEmptySCT []byte
290+
serverHelloEmptySCT = append(serverHelloEmptySCT, serverHelloBytes[:i-6]...)
291+
// Append the extension length and SCT list length for an empty list.
292+
serverHelloEmptySCT = append(serverHelloEmptySCT, []byte{0, 2, 0, 0}...)
293+
serverHelloEmptySCT = append(serverHelloEmptySCT, serverHelloBytes[i+4:]...)
294+
295+
// Update the handshake message length.
296+
serverHelloEmptySCT[1] = byte((len(serverHelloEmptySCT) - 4) >> 16)
297+
serverHelloEmptySCT[2] = byte((len(serverHelloEmptySCT) - 4) >> 8)
298+
serverHelloEmptySCT[3] = byte(len(serverHelloEmptySCT) - 4)
299+
300+
// Update the extensions length
301+
serverHelloEmptySCT[42] = byte((len(serverHelloEmptySCT) - 44) >> 8)
302+
serverHelloEmptySCT[43] = byte((len(serverHelloEmptySCT) - 44))
303+
304+
if serverHelloCopy.unmarshal(serverHelloEmptySCT) {
305+
t.Fatal("Unmarshaled ServerHello with empty SCT list")
306+
}
307+
}

0 commit comments

Comments
 (0)