2009-11-04 01:25:13 +00:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package tls
|
|
|
|
|
|
|
|
import (
|
2016-11-17 12:14:32 +00:00
|
|
|
"bytes"
|
2011-11-08 23:40:58 +00:00
|
|
|
"math/rand"
|
2009-12-15 23:33:31 +00:00
|
|
|
"reflect"
|
2016-12-05 18:24:30 +00:00
|
|
|
"strings"
|
2009-12-15 23:33:31 +00:00
|
|
|
"testing"
|
|
|
|
"testing/quick"
|
2009-11-04 01:25:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var tests = []interface{}{
|
|
|
|
&clientHelloMsg{},
|
2009-11-21 23:53:03 +00:00
|
|
|
&serverHelloMsg{},
|
2011-09-14 20:32:19 +01:00
|
|
|
&finishedMsg{},
|
2009-12-23 19:13:09 +00:00
|
|
|
|
2009-11-21 23:53:03 +00:00
|
|
|
&certificateMsg{},
|
2010-08-16 16:22:22 +01:00
|
|
|
&certificateRequestMsg{},
|
|
|
|
&certificateVerifyMsg{},
|
2010-07-14 15:40:15 +01:00
|
|
|
&certificateStatusMsg{},
|
2009-11-04 01:25:13 +00:00
|
|
|
&clientKeyExchangeMsg{},
|
2009-12-23 19:13:09 +00:00
|
|
|
&nextProtoMsg{},
|
2012-09-24 21:52:43 +01:00
|
|
|
&newSessionTicketMsg{},
|
|
|
|
&sessionState{},
|
2016-11-19 22:10:00 +00:00
|
|
|
&encryptedExtensionsMsg{},
|
|
|
|
&certificateMsg13{},
|
2016-11-21 22:24:45 +00:00
|
|
|
&newSessionTicketMsg13{},
|
|
|
|
&sessionState13{},
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type testMessage interface {
|
2009-12-15 23:33:31 +00:00
|
|
|
marshal() []byte
|
2017-01-16 12:23:17 +00:00
|
|
|
unmarshal([]byte) alert
|
2011-11-14 20:21:08 +00:00
|
|
|
equal(interface{}) bool
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestMarshalUnmarshal(t *testing.T) {
|
2009-12-15 23:33:31 +00:00
|
|
|
rand := rand.New(rand.NewSource(0))
|
2011-11-14 20:21:08 +00:00
|
|
|
|
2009-11-04 01:25:13 +00:00
|
|
|
for i, iface := range tests {
|
2011-04-25 18:39:36 +01:00
|
|
|
ty := reflect.ValueOf(iface).Type()
|
2009-11-04 01:25:13 +00:00
|
|
|
|
2011-03-26 18:25:22 +00:00
|
|
|
n := 100
|
|
|
|
if testing.Short() {
|
|
|
|
n = 5
|
|
|
|
}
|
|
|
|
for j := 0; j < n; j++ {
|
2009-12-15 23:33:31 +00:00
|
|
|
v, ok := quick.Value(ty, rand)
|
2009-11-04 01:25:13 +00:00
|
|
|
if !ok {
|
2009-12-15 23:33:31 +00:00
|
|
|
t.Errorf("#%d: failed to create value", i)
|
|
|
|
break
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
|
|
|
|
2009-12-15 23:33:31 +00:00
|
|
|
m1 := v.Interface().(testMessage)
|
|
|
|
marshaled := m1.marshal()
|
|
|
|
m2 := iface.(testMessage)
|
2017-01-16 12:23:17 +00:00
|
|
|
if m2.unmarshal(marshaled) != alertSuccess {
|
2016-11-19 22:10:00 +00:00
|
|
|
t.Errorf("#%d.%d failed to unmarshal %#v %x", i, j, m1, marshaled)
|
2009-12-15 23:33:31 +00:00
|
|
|
break
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
2009-12-15 23:33:31 +00:00
|
|
|
m2.marshal() // to fill any marshal cache in the message
|
2009-11-04 01:25:13 +00:00
|
|
|
|
2011-11-14 20:21:08 +00:00
|
|
|
if !m1.equal(m2) {
|
2016-11-19 22:10:00 +00:00
|
|
|
t.Errorf("#%d.%d got:%#v want:%#v %x", i, j, m2, m1, marshaled)
|
2009-12-15 23:33:31 +00:00
|
|
|
break
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
|
|
|
|
2011-09-14 20:32:19 +01:00
|
|
|
if i >= 3 {
|
|
|
|
// The first three message types (ClientHello,
|
|
|
|
// ServerHello and Finished) are allowed to
|
|
|
|
// have parsable prefixes because the extension
|
|
|
|
// data is optional and the length of the
|
|
|
|
// Finished varies across versions.
|
2009-12-23 19:13:09 +00:00
|
|
|
for j := 0; j < len(marshaled); j++ {
|
2017-01-16 12:23:17 +00:00
|
|
|
if m2.unmarshal(marshaled[0:j]) == alertSuccess {
|
2009-12-23 19:13:09 +00:00
|
|
|
t.Errorf("#%d unmarshaled a prefix of length %d of %#v", i, j, m1)
|
|
|
|
break
|
|
|
|
}
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-21 23:53:03 +00:00
|
|
|
func TestFuzz(t *testing.T) {
|
2009-12-15 23:33:31 +00:00
|
|
|
rand := rand.New(rand.NewSource(0))
|
2009-11-21 23:53:03 +00:00
|
|
|
for _, iface := range tests {
|
2009-12-15 23:33:31 +00:00
|
|
|
m := iface.(testMessage)
|
2009-11-21 23:53:03 +00:00
|
|
|
|
|
|
|
for j := 0; j < 1000; j++ {
|
2009-12-15 23:33:31 +00:00
|
|
|
len := rand.Intn(100)
|
|
|
|
bytes := randomBytes(len, rand)
|
2009-11-21 23:53:03 +00:00
|
|
|
// This just looks for crashes due to bounds errors etc.
|
2009-12-15 23:33:31 +00:00
|
|
|
m.unmarshal(bytes)
|
2009-11-21 23:53:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 01:25:13 +00:00
|
|
|
func randomBytes(n int, rand *rand.Rand) []byte {
|
2009-12-15 23:33:31 +00:00
|
|
|
r := make([]byte, n)
|
2017-07-03 23:38:55 +01:00
|
|
|
if _, err := rand.Read(r); err != nil {
|
|
|
|
panic("rand.Read failed: " + err.Error())
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
2009-12-15 23:33:31 +00:00
|
|
|
return r
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
|
|
|
|
2009-12-23 19:13:09 +00:00
|
|
|
func randomString(n int, rand *rand.Rand) string {
|
|
|
|
b := randomBytes(n, rand)
|
|
|
|
return string(b)
|
|
|
|
}
|
|
|
|
|
2009-11-04 01:25:13 +00:00
|
|
|
func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
2009-12-15 23:33:31 +00:00
|
|
|
m := &clientHelloMsg{}
|
2010-04-27 06:19:04 +01:00
|
|
|
m.vers = uint16(rand.Intn(65536))
|
2009-12-15 23:33:31 +00:00
|
|
|
m.random = randomBytes(32, rand)
|
|
|
|
m.sessionId = randomBytes(rand.Intn(32), rand)
|
|
|
|
m.cipherSuites = make([]uint16, rand.Intn(63)+1)
|
2009-11-04 01:25:13 +00:00
|
|
|
for i := 0; i < len(m.cipherSuites); i++ {
|
2017-01-11 21:46:27 +00:00
|
|
|
cs := uint16(rand.Int31())
|
|
|
|
if cs == scsvRenegotiation {
|
|
|
|
cs += 1
|
|
|
|
}
|
|
|
|
m.cipherSuites[i] = cs
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
2009-12-15 23:33:31 +00:00
|
|
|
m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
|
2009-12-23 19:13:09 +00:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.nextProtoNeg = true
|
|
|
|
}
|
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.serverName = randomString(rand.Intn(255), rand)
|
2016-12-05 18:24:30 +00:00
|
|
|
for strings.HasSuffix(m.serverName, ".") {
|
|
|
|
m.serverName = m.serverName[:len(m.serverName)-1]
|
|
|
|
}
|
2009-12-23 19:13:09 +00:00
|
|
|
}
|
2010-07-14 15:40:15 +01:00
|
|
|
m.ocspStapling = rand.Intn(10) > 5
|
2010-12-16 22:10:50 +00:00
|
|
|
m.supportedPoints = randomBytes(rand.Intn(5)+1, rand)
|
2014-02-24 22:57:51 +00:00
|
|
|
m.supportedCurves = make([]CurveID, rand.Intn(5)+1)
|
2011-04-13 23:13:59 +01:00
|
|
|
for i := range m.supportedCurves {
|
2014-02-24 22:57:51 +00:00
|
|
|
m.supportedCurves[i] = CurveID(rand.Intn(30000))
|
2010-12-16 22:10:50 +00:00
|
|
|
}
|
2012-10-09 18:25:47 +01:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.ticketSupported = true
|
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.sessionTicket = randomBytes(rand.Intn(300), rand)
|
|
|
|
}
|
|
|
|
}
|
2013-07-03 00:58:56 +01:00
|
|
|
if rand.Intn(10) > 5 {
|
2017-09-07 17:50:10 +01:00
|
|
|
m.supportedSignatureAlgorithms = supportedSignatureAlgorithms
|
2013-07-03 00:58:56 +01:00
|
|
|
}
|
2014-08-05 19:36:20 +01:00
|
|
|
m.alpnProtocols = make([]string, rand.Intn(5))
|
|
|
|
for i := range m.alpnProtocols {
|
|
|
|
m.alpnProtocols[i] = randomString(rand.Intn(20)+1, rand)
|
|
|
|
}
|
2015-04-16 19:59:22 +01:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.scts = true
|
|
|
|
}
|
2016-11-19 22:10:00 +00:00
|
|
|
m.keyShares = make([]keyShare, rand.Intn(4))
|
|
|
|
for i := range m.keyShares {
|
|
|
|
m.keyShares[i].group = CurveID(rand.Intn(30000))
|
|
|
|
m.keyShares[i].data = randomBytes(rand.Intn(300), rand)
|
|
|
|
}
|
|
|
|
m.supportedVersions = make([]uint16, rand.Intn(5))
|
|
|
|
for i := range m.supportedVersions {
|
|
|
|
m.supportedVersions[i] = uint16(rand.Intn(30000))
|
|
|
|
}
|
2016-11-25 21:46:50 +00:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.earlyData = true
|
|
|
|
}
|
2009-11-04 01:25:13 +00:00
|
|
|
|
2011-04-25 18:39:36 +01:00
|
|
|
return reflect.ValueOf(m)
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
|
|
|
|
2009-11-21 23:53:03 +00:00
|
|
|
func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
2009-12-15 23:33:31 +00:00
|
|
|
m := &serverHelloMsg{}
|
2010-04-27 06:19:04 +01:00
|
|
|
m.vers = uint16(rand.Intn(65536))
|
2009-12-15 23:33:31 +00:00
|
|
|
m.random = randomBytes(32, rand)
|
|
|
|
m.sessionId = randomBytes(rand.Intn(32), rand)
|
|
|
|
m.cipherSuite = uint16(rand.Int31())
|
|
|
|
m.compressionMethod = uint8(rand.Intn(256))
|
2009-12-23 19:13:09 +00:00
|
|
|
|
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.nextProtoNeg = true
|
|
|
|
|
|
|
|
n := rand.Intn(10)
|
|
|
|
m.nextProtos = make([]string, n)
|
|
|
|
for i := 0; i < n; i++ {
|
|
|
|
m.nextProtos[i] = randomString(20, rand)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-09 18:25:47 +01:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.ocspStapling = true
|
|
|
|
}
|
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.ticketSupported = true
|
|
|
|
}
|
2014-08-05 19:36:20 +01:00
|
|
|
m.alpnProtocol = randomString(rand.Intn(32)+1, rand)
|
2012-10-09 18:25:47 +01:00
|
|
|
|
2015-04-16 19:59:22 +01:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
numSCTs := rand.Intn(4)
|
|
|
|
m.scts = make([][]byte, numSCTs)
|
|
|
|
for i := range m.scts {
|
|
|
|
m.scts[i] = randomBytes(rand.Intn(500), rand)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-24 18:10:50 +00:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.keyShare.group = CurveID(rand.Intn(30000))
|
|
|
|
m.keyShare.data = randomBytes(rand.Intn(300), rand)
|
|
|
|
}
|
2016-11-21 22:24:45 +00:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.psk = true
|
|
|
|
m.pskIdentity = uint16(rand.Int31())
|
|
|
|
}
|
2016-11-19 22:10:00 +00:00
|
|
|
|
|
|
|
return reflect.ValueOf(m)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (*encryptedExtensionsMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
m := &encryptedExtensionsMsg{}
|
2016-11-25 21:46:50 +00:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.alpnProtocol = randomString(rand.Intn(32)+1, rand)
|
|
|
|
}
|
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.earlyData = true
|
|
|
|
}
|
2016-11-19 22:10:00 +00:00
|
|
|
|
|
|
|
return reflect.ValueOf(m)
|
|
|
|
}
|
|
|
|
|
2009-11-21 23:53:03 +00:00
|
|
|
func (*certificateMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
2009-12-15 23:33:31 +00:00
|
|
|
m := &certificateMsg{}
|
|
|
|
numCerts := rand.Intn(20)
|
|
|
|
m.certificates = make([][]byte, numCerts)
|
2009-11-21 23:53:03 +00:00
|
|
|
for i := 0; i < numCerts; i++ {
|
|
|
|
m.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
|
|
|
|
}
|
2011-04-25 18:39:36 +01:00
|
|
|
return reflect.ValueOf(m)
|
2009-11-21 23:53:03 +00:00
|
|
|
}
|
|
|
|
|
2016-11-19 22:10:00 +00:00
|
|
|
func (*certificateMsg13) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
m := &certificateMsg13{}
|
|
|
|
numCerts := rand.Intn(20)
|
2017-02-03 19:36:10 +00:00
|
|
|
m.certificates = make([]certificateEntry, numCerts)
|
2016-11-19 22:10:00 +00:00
|
|
|
for i := 0; i < numCerts; i++ {
|
2017-02-03 19:36:10 +00:00
|
|
|
m.certificates[i].data = randomBytes(rand.Intn(10)+1, rand)
|
|
|
|
if rand.Intn(2) == 1 {
|
|
|
|
m.certificates[i].ocspStaple = randomBytes(rand.Intn(10)+1, rand)
|
|
|
|
}
|
|
|
|
|
|
|
|
numScts := rand.Intn(3)
|
|
|
|
for j := 0; j < numScts; j++ {
|
|
|
|
m.certificates[i].sctList = append(m.certificates[i].sctList, randomBytes(rand.Intn(10)+1, rand))
|
|
|
|
}
|
2016-11-19 22:10:00 +00:00
|
|
|
}
|
|
|
|
m.requestContext = randomBytes(rand.Intn(5), rand)
|
|
|
|
return reflect.ValueOf(m)
|
|
|
|
}
|
|
|
|
|
2010-08-16 16:22:22 +01:00
|
|
|
func (*certificateRequestMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
m := &certificateRequestMsg{}
|
|
|
|
m.certificateTypes = randomBytes(rand.Intn(5)+1, rand)
|
|
|
|
numCAs := rand.Intn(100)
|
|
|
|
m.certificateAuthorities = make([][]byte, numCAs)
|
|
|
|
for i := 0; i < numCAs; i++ {
|
|
|
|
m.certificateAuthorities[i] = randomBytes(rand.Intn(15)+1, rand)
|
|
|
|
}
|
2011-04-25 18:39:36 +01:00
|
|
|
return reflect.ValueOf(m)
|
2010-08-16 16:22:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (*certificateVerifyMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
m := &certificateVerifyMsg{}
|
|
|
|
m.signature = randomBytes(rand.Intn(15)+1, rand)
|
2011-04-25 18:39:36 +01:00
|
|
|
return reflect.ValueOf(m)
|
2010-08-16 16:22:22 +01:00
|
|
|
}
|
|
|
|
|
2010-07-14 15:40:15 +01:00
|
|
|
func (*certificateStatusMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
m := &certificateStatusMsg{}
|
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.statusType = statusTypeOCSP
|
|
|
|
m.response = randomBytes(rand.Intn(10)+1, rand)
|
|
|
|
} else {
|
|
|
|
m.statusType = 42
|
|
|
|
}
|
2011-04-25 18:39:36 +01:00
|
|
|
return reflect.ValueOf(m)
|
2010-07-14 15:40:15 +01:00
|
|
|
}
|
|
|
|
|
2009-11-04 01:25:13 +00:00
|
|
|
func (*clientKeyExchangeMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
2009-12-15 23:33:31 +00:00
|
|
|
m := &clientKeyExchangeMsg{}
|
|
|
|
m.ciphertext = randomBytes(rand.Intn(1000)+1, rand)
|
2011-04-25 18:39:36 +01:00
|
|
|
return reflect.ValueOf(m)
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
2009-12-15 23:33:31 +00:00
|
|
|
m := &finishedMsg{}
|
|
|
|
m.verifyData = randomBytes(12, rand)
|
2011-04-25 18:39:36 +01:00
|
|
|
return reflect.ValueOf(m)
|
2009-11-04 01:25:13 +00:00
|
|
|
}
|
2009-12-23 19:13:09 +00:00
|
|
|
|
|
|
|
func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
m := &nextProtoMsg{}
|
|
|
|
m.proto = randomString(rand.Intn(255), rand)
|
2011-04-25 18:39:36 +01:00
|
|
|
return reflect.ValueOf(m)
|
2009-12-23 19:13:09 +00:00
|
|
|
}
|
2012-09-24 21:52:43 +01:00
|
|
|
|
|
|
|
func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
m := &newSessionTicketMsg{}
|
|
|
|
m.ticket = randomBytes(rand.Intn(4), rand)
|
|
|
|
return reflect.ValueOf(m)
|
|
|
|
}
|
|
|
|
|
2016-11-21 22:24:45 +00:00
|
|
|
func (*newSessionTicketMsg13) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
m := &newSessionTicketMsg13{}
|
|
|
|
m.ageAdd = uint32(rand.Intn(0xffffffff))
|
|
|
|
m.lifetime = uint32(rand.Intn(0xffffffff))
|
2017-11-12 02:11:32 +00:00
|
|
|
m.nonce = randomBytes(1+rand.Intn(255), rand)
|
|
|
|
m.ticket = randomBytes(1+rand.Intn(40), rand)
|
2016-11-21 22:24:45 +00:00
|
|
|
if rand.Intn(10) > 5 {
|
|
|
|
m.withEarlyDataInfo = true
|
|
|
|
m.maxEarlyDataLength = uint32(rand.Intn(0xffffffff))
|
|
|
|
}
|
|
|
|
return reflect.ValueOf(m)
|
|
|
|
}
|
|
|
|
|
2012-09-24 21:52:43 +01:00
|
|
|
func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
s := &sessionState{}
|
|
|
|
s.vers = uint16(rand.Intn(10000))
|
|
|
|
s.cipherSuite = uint16(rand.Intn(10000))
|
|
|
|
s.masterSecret = randomBytes(rand.Intn(100), rand)
|
|
|
|
numCerts := rand.Intn(20)
|
|
|
|
s.certificates = make([][]byte, numCerts)
|
|
|
|
for i := 0; i < numCerts; i++ {
|
|
|
|
s.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
|
|
|
|
}
|
|
|
|
return reflect.ValueOf(s)
|
|
|
|
}
|
2016-11-17 12:14:32 +00:00
|
|
|
|
2016-11-21 22:24:45 +00:00
|
|
|
func (*sessionState13) Generate(rand *rand.Rand, size int) reflect.Value {
|
|
|
|
s := &sessionState13{}
|
|
|
|
s.vers = uint16(rand.Intn(10000))
|
2016-11-25 21:46:50 +00:00
|
|
|
s.suite = uint16(rand.Intn(10000))
|
2016-11-21 22:24:45 +00:00
|
|
|
s.ageAdd = uint32(rand.Intn(0xffffffff))
|
2016-11-30 00:11:10 +00:00
|
|
|
s.maxEarlyDataLen = uint32(rand.Intn(0xffffffff))
|
2016-11-21 22:24:45 +00:00
|
|
|
s.createdAt = uint64(rand.Int63n(0xfffffffffffffff))
|
2017-11-12 02:11:32 +00:00
|
|
|
s.pskSecret = randomBytes(rand.Intn(100), rand)
|
2016-11-25 21:46:50 +00:00
|
|
|
s.alpnProtocol = randomString(rand.Intn(100), rand)
|
2016-11-30 00:11:10 +00:00
|
|
|
s.SNI = randomString(rand.Intn(100), rand)
|
2016-11-21 22:24:45 +00:00
|
|
|
return reflect.ValueOf(s)
|
|
|
|
}
|
|
|
|
|
2016-11-17 12:14:32 +00:00
|
|
|
func TestRejectEmptySCTList(t *testing.T) {
|
|
|
|
// https://tools.ietf.org/html/rfc6962#section-3.3.1 specifies that
|
|
|
|
// empty SCT lists are invalid.
|
|
|
|
|
|
|
|
var random [32]byte
|
|
|
|
sct := []byte{0x42, 0x42, 0x42, 0x42}
|
|
|
|
serverHello := serverHelloMsg{
|
|
|
|
vers: VersionTLS12,
|
|
|
|
random: random[:],
|
|
|
|
scts: [][]byte{sct},
|
|
|
|
}
|
|
|
|
serverHelloBytes := serverHello.marshal()
|
|
|
|
|
|
|
|
var serverHelloCopy serverHelloMsg
|
2017-01-16 12:23:17 +00:00
|
|
|
if serverHelloCopy.unmarshal(serverHelloBytes) != alertSuccess {
|
2016-11-17 12:14:32 +00:00
|
|
|
t.Fatal("Failed to unmarshal initial message")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change serverHelloBytes so that the SCT list is empty
|
|
|
|
i := bytes.Index(serverHelloBytes, sct)
|
|
|
|
if i < 0 {
|
|
|
|
t.Fatal("Cannot find SCT in ServerHello")
|
|
|
|
}
|
|
|
|
|
|
|
|
var serverHelloEmptySCT []byte
|
|
|
|
serverHelloEmptySCT = append(serverHelloEmptySCT, serverHelloBytes[:i-6]...)
|
|
|
|
// Append the extension length and SCT list length for an empty list.
|
|
|
|
serverHelloEmptySCT = append(serverHelloEmptySCT, []byte{0, 2, 0, 0}...)
|
|
|
|
serverHelloEmptySCT = append(serverHelloEmptySCT, serverHelloBytes[i+4:]...)
|
|
|
|
|
|
|
|
// Update the handshake message length.
|
|
|
|
serverHelloEmptySCT[1] = byte((len(serverHelloEmptySCT) - 4) >> 16)
|
|
|
|
serverHelloEmptySCT[2] = byte((len(serverHelloEmptySCT) - 4) >> 8)
|
|
|
|
serverHelloEmptySCT[3] = byte(len(serverHelloEmptySCT) - 4)
|
|
|
|
|
|
|
|
// Update the extensions length
|
|
|
|
serverHelloEmptySCT[42] = byte((len(serverHelloEmptySCT) - 44) >> 8)
|
|
|
|
serverHelloEmptySCT[43] = byte((len(serverHelloEmptySCT) - 44))
|
|
|
|
|
2017-01-16 12:23:17 +00:00
|
|
|
if serverHelloCopy.unmarshal(serverHelloEmptySCT) == alertSuccess {
|
2016-11-17 12:14:32 +00:00
|
|
|
t.Fatal("Unmarshaled ServerHello with empty SCT list")
|
|
|
|
}
|
|
|
|
}
|
2016-11-17 20:15:19 +00:00
|
|
|
|
|
|
|
func TestRejectEmptySCT(t *testing.T) {
|
|
|
|
// Not only must the SCT list be non-empty, but the SCT elements must
|
|
|
|
// not be zero length.
|
|
|
|
|
|
|
|
var random [32]byte
|
|
|
|
serverHello := serverHelloMsg{
|
|
|
|
vers: VersionTLS12,
|
|
|
|
random: random[:],
|
|
|
|
scts: [][]byte{nil},
|
|
|
|
}
|
|
|
|
serverHelloBytes := serverHello.marshal()
|
|
|
|
|
|
|
|
var serverHelloCopy serverHelloMsg
|
2017-01-16 12:23:17 +00:00
|
|
|
if serverHelloCopy.unmarshal(serverHelloBytes) == alertSuccess {
|
2016-11-17 20:15:19 +00:00
|
|
|
t.Fatal("Unmarshaled ServerHello with zero-length SCT")
|
|
|
|
}
|
|
|
|
}
|