23f729dd94bdfd866f8689e98caf930e1effe3ed
[platform/upstream/gcc.git] / libgo / go / crypto / tls / handshake_messages_test.go
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.
4
5 package tls
6
7 import (
8         "rand"
9         "reflect"
10         "testing"
11         "testing/quick"
12 )
13
14 var tests = []interface{}{
15         &clientHelloMsg{},
16         &serverHelloMsg{},
17
18         &certificateMsg{},
19         &certificateRequestMsg{},
20         &certificateVerifyMsg{},
21         &certificateStatusMsg{},
22         &clientKeyExchangeMsg{},
23         &finishedMsg{},
24         &nextProtoMsg{},
25 }
26
27 type testMessage interface {
28         marshal() []byte
29         unmarshal([]byte) bool
30 }
31
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()
36
37                 n := 100
38                 if testing.Short() {
39                         n = 5
40                 }
41                 for j := 0; j < n; j++ {
42                         v, ok := quick.Value(ty, rand)
43                         if !ok {
44                                 t.Errorf("#%d: failed to create value", i)
45                                 break
46                         }
47
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)
53                                 break
54                         }
55                         m2.marshal() // to fill any marshal cache in the message
56
57                         if !reflect.DeepEqual(m1, m2) {
58                                 t.Errorf("#%d got:%#v want:%#v %x", i, m2, m1, marshaled)
59                                 break
60                         }
61
62                         if i >= 2 {
63                                 // The first two message types (ClientHello and
64                                 // ServerHello) are allowed to have parsable
65                                 // prefixes because the extension data is
66                                 // optional.
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)
70                                                 break
71                                         }
72                                 }
73                         }
74                 }
75         }
76 }
77
78 func TestFuzz(t *testing.T) {
79         rand := rand.New(rand.NewSource(0))
80         for _, iface := range tests {
81                 m := iface.(testMessage)
82
83                 for j := 0; j < 1000; j++ {
84                         len := rand.Intn(100)
85                         bytes := randomBytes(len, rand)
86                         // This just looks for crashes due to bounds errors etc.
87                         m.unmarshal(bytes)
88                 }
89         }
90 }
91
92 func randomBytes(n int, rand *rand.Rand) []byte {
93         r := make([]byte, n)
94         for i := 0; i < n; i++ {
95                 r[i] = byte(rand.Int31())
96         }
97         return r
98 }
99
100 func randomString(n int, rand *rand.Rand) string {
101         b := randomBytes(n, rand)
102         return string(b)
103 }
104
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())
113         }
114         m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
115         if rand.Intn(10) > 5 {
116                 m.nextProtoNeg = true
117         }
118         if rand.Intn(10) > 5 {
119                 m.serverName = randomString(rand.Intn(255), rand)
120         }
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))
126         }
127
128         return reflect.ValueOf(m)
129 }
130
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))
138
139         if rand.Intn(10) > 5 {
140                 m.nextProtoNeg = true
141
142                 n := rand.Intn(10)
143                 m.nextProtos = make([]string, n)
144                 for i := 0; i < n; i++ {
145                         m.nextProtos[i] = randomString(20, rand)
146                 }
147         }
148
149         return reflect.ValueOf(m)
150 }
151
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)
158         }
159         return reflect.ValueOf(m)
160 }
161
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)
169         }
170         return reflect.ValueOf(m)
171 }
172
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)
177 }
178
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)
184         } else {
185                 m.statusType = 42
186         }
187         return reflect.ValueOf(m)
188 }
189
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)
194 }
195
196 func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value {
197         m := &finishedMsg{}
198         m.verifyData = randomBytes(12, rand)
199         return reflect.ValueOf(m)
200 }
201
202 func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value {
203         m := &nextProtoMsg{}
204         m.proto = randomString(rand.Intn(255), rand)
205         return reflect.ValueOf(m)
206 }