1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 var tests = []interface{}{
19 &certificateRequestMsg{},
20 &certificateVerifyMsg{},
21 &certificateStatusMsg{},
22 &clientKeyExchangeMsg{},
27 type testMessage interface {
29 unmarshal([]byte) bool
32 func TestMarshalUnmarshal(t *testing.T) {
33 rand := rand.New(rand.NewSource(0))
34 for i, iface := range tests {
35 ty := reflect.ValueOf(iface).Type()
41 for j := 0; j < n; j++ {
42 v, ok := quick.Value(ty, rand)
44 t.Errorf("#%d: failed to create value", i)
48 m1 := v.Interface().(testMessage)
49 marshaled := m1.marshal()
50 m2 := iface.(testMessage)
51 if !m2.unmarshal(marshaled) {
52 t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled)
55 m2.marshal() // to fill any marshal cache in the message
57 if !reflect.DeepEqual(m1, m2) {
58 t.Errorf("#%d got:%#v want:%#v %x", i, m2, m1, marshaled)
63 // The first two message types (ClientHello and
64 // ServerHello) are allowed to have parsable
65 // prefixes because the extension data is
67 for j := 0; j < len(marshaled); j++ {
68 if m2.unmarshal(marshaled[0:j]) {
69 t.Errorf("#%d unmarshaled a prefix of length %d of %#v", i, j, m1)
78 func TestFuzz(t *testing.T) {
79 rand := rand.New(rand.NewSource(0))
80 for _, iface := range tests {
81 m := iface.(testMessage)
83 for j := 0; j < 1000; j++ {
85 bytes := randomBytes(len, rand)
86 // This just looks for crashes due to bounds errors etc.
92 func randomBytes(n int, rand *rand.Rand) []byte {
94 for i := 0; i < n; i++ {
95 r[i] = byte(rand.Int31())
100 func randomString(n int, rand *rand.Rand) string {
101 b := randomBytes(n, rand)
105 func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
106 m := &clientHelloMsg{}
107 m.vers = uint16(rand.Intn(65536))
108 m.random = randomBytes(32, rand)
109 m.sessionId = randomBytes(rand.Intn(32), rand)
110 m.cipherSuites = make([]uint16, rand.Intn(63)+1)
111 for i := 0; i < len(m.cipherSuites); i++ {
112 m.cipherSuites[i] = uint16(rand.Int31())
114 m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
115 if rand.Intn(10) > 5 {
116 m.nextProtoNeg = true
118 if rand.Intn(10) > 5 {
119 m.serverName = randomString(rand.Intn(255), rand)
121 m.ocspStapling = rand.Intn(10) > 5
122 m.supportedPoints = randomBytes(rand.Intn(5)+1, rand)
123 m.supportedCurves = make([]uint16, rand.Intn(5)+1)
124 for i := range m.supportedCurves {
125 m.supportedCurves[i] = uint16(rand.Intn(30000))
128 return reflect.ValueOf(m)
131 func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
132 m := &serverHelloMsg{}
133 m.vers = uint16(rand.Intn(65536))
134 m.random = randomBytes(32, rand)
135 m.sessionId = randomBytes(rand.Intn(32), rand)
136 m.cipherSuite = uint16(rand.Int31())
137 m.compressionMethod = uint8(rand.Intn(256))
139 if rand.Intn(10) > 5 {
140 m.nextProtoNeg = true
143 m.nextProtos = make([]string, n)
144 for i := 0; i < n; i++ {
145 m.nextProtos[i] = randomString(20, rand)
149 return reflect.ValueOf(m)
152 func (*certificateMsg) Generate(rand *rand.Rand, size int) reflect.Value {
153 m := &certificateMsg{}
154 numCerts := rand.Intn(20)
155 m.certificates = make([][]byte, numCerts)
156 for i := 0; i < numCerts; i++ {
157 m.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
159 return reflect.ValueOf(m)
162 func (*certificateRequestMsg) Generate(rand *rand.Rand, size int) reflect.Value {
163 m := &certificateRequestMsg{}
164 m.certificateTypes = randomBytes(rand.Intn(5)+1, rand)
165 numCAs := rand.Intn(100)
166 m.certificateAuthorities = make([][]byte, numCAs)
167 for i := 0; i < numCAs; i++ {
168 m.certificateAuthorities[i] = randomBytes(rand.Intn(15)+1, rand)
170 return reflect.ValueOf(m)
173 func (*certificateVerifyMsg) Generate(rand *rand.Rand, size int) reflect.Value {
174 m := &certificateVerifyMsg{}
175 m.signature = randomBytes(rand.Intn(15)+1, rand)
176 return reflect.ValueOf(m)
179 func (*certificateStatusMsg) Generate(rand *rand.Rand, size int) reflect.Value {
180 m := &certificateStatusMsg{}
181 if rand.Intn(10) > 5 {
182 m.statusType = statusTypeOCSP
183 m.response = randomBytes(rand.Intn(10)+1, rand)
187 return reflect.ValueOf(m)
190 func (*clientKeyExchangeMsg) Generate(rand *rand.Rand, size int) reflect.Value {
191 m := &clientKeyExchangeMsg{}
192 m.ciphertext = randomBytes(rand.Intn(1000)+1, rand)
193 return reflect.ValueOf(m)
196 func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value {
198 m.verifyData = randomBytes(12, rand)
199 return reflect.ValueOf(m)
202 func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value {
204 m.proto = randomString(rand.Intn(255), rand)
205 return reflect.ValueOf(m)