Rebase.
[official-gcc.git] / libgo / go / crypto / tls / handshake_messages_test.go
blobf46aabdfd5f2445bb1b4e54e58da09903e3ed1a6
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.
5 package tls
7 import (
8 "math/rand"
9 "reflect"
10 "testing"
11 "testing/quick"
14 var tests = []interface{}{
15 &clientHelloMsg{},
16 &serverHelloMsg{},
17 &finishedMsg{},
19 &certificateMsg{},
20 &certificateRequestMsg{},
21 &certificateVerifyMsg{},
22 &certificateStatusMsg{},
23 &clientKeyExchangeMsg{},
24 &nextProtoMsg{},
25 &newSessionTicketMsg{},
26 &sessionState{},
29 type testMessage interface {
30 marshal() []byte
31 unmarshal([]byte) bool
32 equal(interface{}) bool
35 func TestMarshalUnmarshal(t *testing.T) {
36 rand := rand.New(rand.NewSource(0))
38 for i, iface := range tests {
39 ty := reflect.ValueOf(iface).Type()
41 n := 100
42 if testing.Short() {
43 n = 5
45 for j := 0; j < n; j++ {
46 v, ok := quick.Value(ty, rand)
47 if !ok {
48 t.Errorf("#%d: failed to create value", i)
49 break
52 m1 := v.Interface().(testMessage)
53 marshaled := m1.marshal()
54 m2 := iface.(testMessage)
55 if !m2.unmarshal(marshaled) {
56 t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled)
57 break
59 m2.marshal() // to fill any marshal cache in the message
61 if !m1.equal(m2) {
62 t.Errorf("#%d got:%#v want:%#v %x", i, m2, m1, marshaled)
63 break
66 if i >= 3 {
67 // The first three message types (ClientHello,
68 // ServerHello and Finished) are allowed to
69 // have parsable prefixes because the extension
70 // data is optional and the length of the
71 // Finished varies across versions.
72 for j := 0; j < len(marshaled); j++ {
73 if m2.unmarshal(marshaled[0:j]) {
74 t.Errorf("#%d unmarshaled a prefix of length %d of %#v", i, j, m1)
75 break
83 func TestFuzz(t *testing.T) {
84 rand := rand.New(rand.NewSource(0))
85 for _, iface := range tests {
86 m := iface.(testMessage)
88 for j := 0; j < 1000; j++ {
89 len := rand.Intn(100)
90 bytes := randomBytes(len, rand)
91 // This just looks for crashes due to bounds errors etc.
92 m.unmarshal(bytes)
97 func randomBytes(n int, rand *rand.Rand) []byte {
98 r := make([]byte, n)
99 for i := 0; i < n; i++ {
100 r[i] = byte(rand.Int31())
102 return r
105 func randomString(n int, rand *rand.Rand) string {
106 b := randomBytes(n, rand)
107 return string(b)
110 func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
111 m := &clientHelloMsg{}
112 m.vers = uint16(rand.Intn(65536))
113 m.random = randomBytes(32, rand)
114 m.sessionId = randomBytes(rand.Intn(32), rand)
115 m.cipherSuites = make([]uint16, rand.Intn(63)+1)
116 for i := 0; i < len(m.cipherSuites); i++ {
117 m.cipherSuites[i] = uint16(rand.Int31())
119 m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
120 if rand.Intn(10) > 5 {
121 m.nextProtoNeg = true
123 if rand.Intn(10) > 5 {
124 m.serverName = randomString(rand.Intn(255), rand)
126 m.ocspStapling = rand.Intn(10) > 5
127 m.supportedPoints = randomBytes(rand.Intn(5)+1, rand)
128 m.supportedCurves = make([]CurveID, rand.Intn(5)+1)
129 for i := range m.supportedCurves {
130 m.supportedCurves[i] = CurveID(rand.Intn(30000))
132 if rand.Intn(10) > 5 {
133 m.ticketSupported = true
134 if rand.Intn(10) > 5 {
135 m.sessionTicket = randomBytes(rand.Intn(300), rand)
138 if rand.Intn(10) > 5 {
139 m.signatureAndHashes = supportedSKXSignatureAlgorithms
142 return reflect.ValueOf(m)
145 func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
146 m := &serverHelloMsg{}
147 m.vers = uint16(rand.Intn(65536))
148 m.random = randomBytes(32, rand)
149 m.sessionId = randomBytes(rand.Intn(32), rand)
150 m.cipherSuite = uint16(rand.Int31())
151 m.compressionMethod = uint8(rand.Intn(256))
153 if rand.Intn(10) > 5 {
154 m.nextProtoNeg = true
156 n := rand.Intn(10)
157 m.nextProtos = make([]string, n)
158 for i := 0; i < n; i++ {
159 m.nextProtos[i] = randomString(20, rand)
163 if rand.Intn(10) > 5 {
164 m.ocspStapling = true
166 if rand.Intn(10) > 5 {
167 m.ticketSupported = true
170 return reflect.ValueOf(m)
173 func (*certificateMsg) Generate(rand *rand.Rand, size int) reflect.Value {
174 m := &certificateMsg{}
175 numCerts := rand.Intn(20)
176 m.certificates = make([][]byte, numCerts)
177 for i := 0; i < numCerts; i++ {
178 m.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
180 return reflect.ValueOf(m)
183 func (*certificateRequestMsg) Generate(rand *rand.Rand, size int) reflect.Value {
184 m := &certificateRequestMsg{}
185 m.certificateTypes = randomBytes(rand.Intn(5)+1, rand)
186 numCAs := rand.Intn(100)
187 m.certificateAuthorities = make([][]byte, numCAs)
188 for i := 0; i < numCAs; i++ {
189 m.certificateAuthorities[i] = randomBytes(rand.Intn(15)+1, rand)
191 return reflect.ValueOf(m)
194 func (*certificateVerifyMsg) Generate(rand *rand.Rand, size int) reflect.Value {
195 m := &certificateVerifyMsg{}
196 m.signature = randomBytes(rand.Intn(15)+1, rand)
197 return reflect.ValueOf(m)
200 func (*certificateStatusMsg) Generate(rand *rand.Rand, size int) reflect.Value {
201 m := &certificateStatusMsg{}
202 if rand.Intn(10) > 5 {
203 m.statusType = statusTypeOCSP
204 m.response = randomBytes(rand.Intn(10)+1, rand)
205 } else {
206 m.statusType = 42
208 return reflect.ValueOf(m)
211 func (*clientKeyExchangeMsg) Generate(rand *rand.Rand, size int) reflect.Value {
212 m := &clientKeyExchangeMsg{}
213 m.ciphertext = randomBytes(rand.Intn(1000)+1, rand)
214 return reflect.ValueOf(m)
217 func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value {
218 m := &finishedMsg{}
219 m.verifyData = randomBytes(12, rand)
220 return reflect.ValueOf(m)
223 func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value {
224 m := &nextProtoMsg{}
225 m.proto = randomString(rand.Intn(255), rand)
226 return reflect.ValueOf(m)
229 func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value {
230 m := &newSessionTicketMsg{}
231 m.ticket = randomBytes(rand.Intn(4), rand)
232 return reflect.ValueOf(m)
235 func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value {
236 s := &sessionState{}
237 s.vers = uint16(rand.Intn(10000))
238 s.cipherSuite = uint16(rand.Intn(10000))
239 s.masterSecret = randomBytes(rand.Intn(100), rand)
240 numCerts := rand.Intn(20)
241 s.certificates = make([][]byte, numCerts)
242 for i := 0; i < numCerts; i++ {
243 s.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
245 return reflect.ValueOf(s)