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{}{
20 &certificateRequestMsg
{},
21 &certificateVerifyMsg
{},
22 &certificateStatusMsg
{},
23 &clientKeyExchangeMsg
{},
25 &newSessionTicketMsg
{},
29 type testMessage
interface {
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()
45 for j
:= 0; j
< n
; j
++ {
46 v
, ok
:= quick
.Value(ty
, rand
)
48 t
.Errorf("#%d: failed to create value", i
)
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
)
59 m2
.marshal() // to fill any marshal cache in the message
62 t
.Errorf("#%d got:%#v want:%#v %x", i
, m2
, m1
, marshaled
)
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
)
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
++ {
90 bytes
:= randomBytes(len, rand
)
91 // This just looks for crashes due to bounds errors etc.
97 func randomBytes(n
int, rand
*rand
.Rand
) []byte {
99 for i
:= 0; i
< n
; i
++ {
100 r
[i
] = byte(rand
.Int31())
105 func randomString(n
int, rand
*rand
.Rand
) string {
106 b
:= randomBytes(n
, rand
)
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([]uint16, rand
.Intn(5)+1)
129 for i
:= range m
.supportedCurves
{
130 m
.supportedCurves
[i
] = uint16(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
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
)
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
{
219 m
.verifyData
= randomBytes(12, rand
)
220 return reflect
.ValueOf(m
)
223 func (*nextProtoMsg
) Generate(rand
*rand
.Rand
, size
int) reflect
.Value
{
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
{
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
)