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.
12 type clientHelloMsg
struct {
18 compressionMethods
[]uint8
23 supportedCurves
[]CurveID
24 supportedPoints
[]uint8
27 supportedSignatureAlgorithms
[]SignatureScheme
28 secureRenegotiation
[]byte
29 secureRenegotiationSupported
bool
30 alpnProtocols
[]string
33 func (m
*clientHelloMsg
) equal(i
interface{}) bool {
34 m1
, ok
:= i
.(*clientHelloMsg
)
39 return bytes
.Equal(m
.raw
, m1
.raw
) &&
41 bytes
.Equal(m
.random
, m1
.random
) &&
42 bytes
.Equal(m
.sessionId
, m1
.sessionId
) &&
43 eqUint16s(m
.cipherSuites
, m1
.cipherSuites
) &&
44 bytes
.Equal(m
.compressionMethods
, m1
.compressionMethods
) &&
45 m
.nextProtoNeg
== m1
.nextProtoNeg
&&
46 m
.serverName
== m1
.serverName
&&
47 m
.ocspStapling
== m1
.ocspStapling
&&
49 eqCurveIDs(m
.supportedCurves
, m1
.supportedCurves
) &&
50 bytes
.Equal(m
.supportedPoints
, m1
.supportedPoints
) &&
51 m
.ticketSupported
== m1
.ticketSupported
&&
52 bytes
.Equal(m
.sessionTicket
, m1
.sessionTicket
) &&
53 eqSignatureAlgorithms(m
.supportedSignatureAlgorithms
, m1
.supportedSignatureAlgorithms
) &&
54 m
.secureRenegotiationSupported
== m1
.secureRenegotiationSupported
&&
55 bytes
.Equal(m
.secureRenegotiation
, m1
.secureRenegotiation
) &&
56 eqStrings(m
.alpnProtocols
, m1
.alpnProtocols
)
59 func (m
*clientHelloMsg
) marshal() []byte {
64 length
:= 2 + 32 + 1 + len(m
.sessionId
) + 2 + len(m
.cipherSuites
)*2 + 1 + len(m
.compressionMethods
)
71 extensionsLength
+= 1 + 2 + 2
74 if len(m
.serverName
) > 0 {
75 extensionsLength
+= 5 + len(m
.serverName
)
78 if len(m
.supportedCurves
) > 0 {
79 extensionsLength
+= 2 + 2*len(m
.supportedCurves
)
82 if len(m
.supportedPoints
) > 0 {
83 extensionsLength
+= 1 + len(m
.supportedPoints
)
86 if m
.ticketSupported
{
87 extensionsLength
+= len(m
.sessionTicket
)
90 if len(m
.supportedSignatureAlgorithms
) > 0 {
91 extensionsLength
+= 2 + 2*len(m
.supportedSignatureAlgorithms
)
94 if m
.secureRenegotiationSupported
{
95 extensionsLength
+= 1 + len(m
.secureRenegotiation
)
98 if len(m
.alpnProtocols
) > 0 {
100 for _
, s
:= range m
.alpnProtocols
{
101 if l
:= len(s
); l
== 0 || l
> 255 {
102 panic("invalid ALPN protocol")
105 extensionsLength
+= len(s
)
112 if numExtensions
> 0 {
113 extensionsLength
+= 4 * numExtensions
114 length
+= 2 + extensionsLength
117 x
:= make([]byte, 4+length
)
118 x
[0] = typeClientHello
119 x
[1] = uint8(length
>> 16)
120 x
[2] = uint8(length
>> 8)
122 x
[4] = uint8(m
.vers
>> 8)
124 copy(x
[6:38], m
.random
)
125 x
[38] = uint8(len(m
.sessionId
))
126 copy(x
[39:39+len(m
.sessionId
)], m
.sessionId
)
127 y
:= x
[39+len(m
.sessionId
):]
128 y
[0] = uint8(len(m
.cipherSuites
) >> 7)
129 y
[1] = uint8(len(m
.cipherSuites
) << 1)
130 for i
, suite
:= range m
.cipherSuites
{
131 y
[2+i
*2] = uint8(suite
>> 8)
132 y
[3+i
*2] = uint8(suite
)
134 z
:= y
[2+len(m
.cipherSuites
)*2:]
135 z
[0] = uint8(len(m
.compressionMethods
))
136 copy(z
[1:], m
.compressionMethods
)
138 z
= z
[1+len(m
.compressionMethods
):]
139 if numExtensions
> 0 {
140 z
[0] = byte(extensionsLength
>> 8)
141 z
[1] = byte(extensionsLength
)
145 z
[0] = byte(extensionNextProtoNeg
>> 8)
146 z
[1] = byte(extensionNextProtoNeg
& 0xff)
147 // The length is always 0
150 if len(m
.serverName
) > 0 {
151 z
[0] = byte(extensionServerName
>> 8)
152 z
[1] = byte(extensionServerName
& 0xff)
153 l
:= len(m
.serverName
) + 5
158 // RFC 3546, section 3.1
161 // NameType name_type;
162 // select (name_type) {
163 // case host_name: HostName;
168 // host_name(0), (255)
171 // opaque HostName<1..2^16-1>;
174 // ServerName server_name_list<1..2^16-1>
177 z
[0] = byte((len(m
.serverName
) + 3) >> 8)
178 z
[1] = byte(len(m
.serverName
) + 3)
179 z
[3] = byte(len(m
.serverName
) >> 8)
180 z
[4] = byte(len(m
.serverName
))
181 copy(z
[5:], []byte(m
.serverName
))
185 // RFC 4366, section 3.6
186 z
[0] = byte(extensionStatusRequest
>> 8)
187 z
[1] = byte(extensionStatusRequest
)
190 z
[4] = 1 // OCSP type
191 // Two zero valued uint16s for the two lengths.
194 if len(m
.supportedCurves
) > 0 {
195 // https://tools.ietf.org/html/rfc4492#section-5.5.1
196 z
[0] = byte(extensionSupportedCurves
>> 8)
197 z
[1] = byte(extensionSupportedCurves
)
198 l
:= 2 + 2*len(m
.supportedCurves
)
205 for _
, curve
:= range m
.supportedCurves
{
206 z
[0] = byte(curve
>> 8)
211 if len(m
.supportedPoints
) > 0 {
212 // https://tools.ietf.org/html/rfc4492#section-5.5.2
213 z
[0] = byte(extensionSupportedPoints
>> 8)
214 z
[1] = byte(extensionSupportedPoints
)
215 l
:= 1 + len(m
.supportedPoints
)
221 for _
, pointFormat
:= range m
.supportedPoints
{
226 if m
.ticketSupported
{
227 // https://tools.ietf.org/html/rfc5077#section-3.2
228 z
[0] = byte(extensionSessionTicket
>> 8)
229 z
[1] = byte(extensionSessionTicket
)
230 l
:= len(m
.sessionTicket
)
234 copy(z
, m
.sessionTicket
)
235 z
= z
[len(m
.sessionTicket
):]
237 if len(m
.supportedSignatureAlgorithms
) > 0 {
238 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
239 z
[0] = byte(extensionSignatureAlgorithms
>> 8)
240 z
[1] = byte(extensionSignatureAlgorithms
)
241 l
:= 2 + 2*len(m
.supportedSignatureAlgorithms
)
250 for _
, sigAlgo
:= range m
.supportedSignatureAlgorithms
{
251 z
[0] = byte(sigAlgo
>> 8)
256 if m
.secureRenegotiationSupported
{
257 z
[0] = byte(extensionRenegotiationInfo
>> 8)
258 z
[1] = byte(extensionRenegotiationInfo
& 0xff)
260 z
[3] = byte(len(m
.secureRenegotiation
) + 1)
261 z
[4] = byte(len(m
.secureRenegotiation
))
263 copy(z
, m
.secureRenegotiation
)
264 z
= z
[len(m
.secureRenegotiation
):]
266 if len(m
.alpnProtocols
) > 0 {
267 z
[0] = byte(extensionALPN
>> 8)
268 z
[1] = byte(extensionALPN
& 0xff)
273 for _
, s
:= range m
.alpnProtocols
{
278 stringsLength
+= 1 + l
281 lengths
[2] = byte(stringsLength
>> 8)
282 lengths
[3] = byte(stringsLength
)
284 lengths
[0] = byte(stringsLength
>> 8)
285 lengths
[1] = byte(stringsLength
)
288 // https://tools.ietf.org/html/rfc6962#section-3.3.1
289 z
[0] = byte(extensionSCT
>> 8)
290 z
[1] = byte(extensionSCT
)
291 // zero uint16 for the zero-length extension_data
300 func (m
*clientHelloMsg
) unmarshal(data
[]byte) bool {
305 m
.vers
= uint16(data
[4])<<8 |
uint16(data
[5])
306 m
.random
= data
[6:38]
307 sessionIdLen
:= int(data
[38])
308 if sessionIdLen
> 32 ||
len(data
) < 39+sessionIdLen
{
311 m
.sessionId
= data
[39 : 39+sessionIdLen
]
312 data
= data
[39+sessionIdLen
:]
316 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
317 // they are uint16s, the number must be even.
318 cipherSuiteLen
:= int(data
[0])<<8 |
int(data
[1])
319 if cipherSuiteLen%2
== 1 ||
len(data
) < 2+cipherSuiteLen
{
322 numCipherSuites
:= cipherSuiteLen
/ 2
323 m
.cipherSuites
= make([]uint16, numCipherSuites
)
324 for i
:= 0; i
< numCipherSuites
; i
++ {
325 m
.cipherSuites
[i
] = uint16(data
[2+2*i
])<<8 |
uint16(data
[3+2*i
])
326 if m
.cipherSuites
[i
] == scsvRenegotiation
{
327 m
.secureRenegotiationSupported
= true
330 data
= data
[2+cipherSuiteLen
:]
334 compressionMethodsLen
:= int(data
[0])
335 if len(data
) < 1+compressionMethodsLen
{
338 m
.compressionMethods
= data
[1 : 1+compressionMethodsLen
]
340 data
= data
[1+compressionMethodsLen
:]
342 m
.nextProtoNeg
= false
344 m
.ocspStapling
= false
345 m
.ticketSupported
= false
346 m
.sessionTicket
= nil
347 m
.supportedSignatureAlgorithms
= nil
348 m
.alpnProtocols
= nil
352 // ClientHello is optionally followed by extension data
359 extensionsLength
:= int(data
[0])<<8 |
int(data
[1])
361 if extensionsLength
!= len(data
) {
369 extension
:= uint16(data
[0])<<8 |
uint16(data
[1])
370 length
:= int(data
[2])<<8 |
int(data
[3])
372 if len(data
) < length
{
377 case extensionServerName
:
382 namesLen
:= int(d
[0])<<8 |
int(d
[1])
384 if len(d
) != namesLen
{
392 nameLen
:= int(d
[1])<<8 |
int(d
[2])
394 if len(d
) < nameLen
{
398 m
.serverName
= string(d
[:nameLen
])
399 // An SNI value may not include a
401 // https://tools.ietf.org/html/rfc6066#section-3.
402 if strings
.HasSuffix(m
.serverName
, ".") {
409 case extensionNextProtoNeg
:
413 m
.nextProtoNeg
= true
414 case extensionStatusRequest
:
415 m
.ocspStapling
= length
> 0 && data
[0] == statusTypeOCSP
416 case extensionSupportedCurves
:
417 // https://tools.ietf.org/html/rfc4492#section-5.5.1
421 l
:= int(data
[0])<<8 |
int(data
[1])
422 if l%2
== 1 || length
!= l
+2 {
426 m
.supportedCurves
= make([]CurveID
, numCurves
)
428 for i
:= 0; i
< numCurves
; i
++ {
429 m
.supportedCurves
[i
] = CurveID(d
[0])<<8 |
CurveID(d
[1])
432 case extensionSupportedPoints
:
433 // https://tools.ietf.org/html/rfc4492#section-5.5.2
441 m
.supportedPoints
= make([]uint8, l
)
442 copy(m
.supportedPoints
, data
[1:])
443 case extensionSessionTicket
:
444 // https://tools.ietf.org/html/rfc5077#section-3.2
445 m
.ticketSupported
= true
446 m
.sessionTicket
= data
[:length
]
447 case extensionSignatureAlgorithms
:
448 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
449 if length
< 2 || length
&1 != 0 {
452 l
:= int(data
[0])<<8 |
int(data
[1])
458 m
.supportedSignatureAlgorithms
= make([]SignatureScheme
, n
)
459 for i
:= range m
.supportedSignatureAlgorithms
{
460 m
.supportedSignatureAlgorithms
[i
] = SignatureScheme(d
[0])<<8 |
SignatureScheme(d
[1])
463 case extensionRenegotiationInfo
:
474 m
.secureRenegotiation
= d
475 m
.secureRenegotiationSupported
= true
480 l
:= int(data
[0])<<8 |
int(data
[1])
486 stringLen
:= int(d
[0])
488 if stringLen
== 0 || stringLen
> len(d
) {
491 m
.alpnProtocols
= append(m
.alpnProtocols
, string(d
[:stringLen
]))
506 type serverHelloMsg
struct {
512 compressionMethod
uint8
518 secureRenegotiation
[]byte
519 secureRenegotiationSupported
bool
523 func (m
*serverHelloMsg
) equal(i
interface{}) bool {
524 m1
, ok
:= i
.(*serverHelloMsg
)
529 if len(m
.scts
) != len(m1
.scts
) {
532 for i
, sct
:= range m
.scts
{
533 if !bytes
.Equal(sct
, m1
.scts
[i
]) {
538 return bytes
.Equal(m
.raw
, m1
.raw
) &&
540 bytes
.Equal(m
.random
, m1
.random
) &&
541 bytes
.Equal(m
.sessionId
, m1
.sessionId
) &&
542 m
.cipherSuite
== m1
.cipherSuite
&&
543 m
.compressionMethod
== m1
.compressionMethod
&&
544 m
.nextProtoNeg
== m1
.nextProtoNeg
&&
545 eqStrings(m
.nextProtos
, m1
.nextProtos
) &&
546 m
.ocspStapling
== m1
.ocspStapling
&&
547 m
.ticketSupported
== m1
.ticketSupported
&&
548 m
.secureRenegotiationSupported
== m1
.secureRenegotiationSupported
&&
549 bytes
.Equal(m
.secureRenegotiation
, m1
.secureRenegotiation
) &&
550 m
.alpnProtocol
== m1
.alpnProtocol
553 func (m
*serverHelloMsg
) marshal() []byte {
558 length
:= 38 + len(m
.sessionId
)
560 extensionsLength
:= 0
565 for _
, v
:= range m
.nextProtos
{
566 nextProtoLen
+= len(v
)
568 nextProtoLen
+= len(m
.nextProtos
)
569 extensionsLength
+= nextProtoLen
574 if m
.ticketSupported
{
577 if m
.secureRenegotiationSupported
{
578 extensionsLength
+= 1 + len(m
.secureRenegotiation
)
581 if alpnLen
:= len(m
.alpnProtocol
); alpnLen
> 0 {
583 panic("invalid ALPN protocol")
585 extensionsLength
+= 2 + 1 + alpnLen
590 for _
, sct
:= range m
.scts
{
591 sctLen
+= len(sct
) + 2
593 extensionsLength
+= 2 + sctLen
597 if numExtensions
> 0 {
598 extensionsLength
+= 4 * numExtensions
599 length
+= 2 + extensionsLength
602 x
:= make([]byte, 4+length
)
603 x
[0] = typeServerHello
604 x
[1] = uint8(length
>> 16)
605 x
[2] = uint8(length
>> 8)
607 x
[4] = uint8(m
.vers
>> 8)
609 copy(x
[6:38], m
.random
)
610 x
[38] = uint8(len(m
.sessionId
))
611 copy(x
[39:39+len(m
.sessionId
)], m
.sessionId
)
612 z
:= x
[39+len(m
.sessionId
):]
613 z
[0] = uint8(m
.cipherSuite
>> 8)
614 z
[1] = uint8(m
.cipherSuite
)
615 z
[2] = m
.compressionMethod
618 if numExtensions
> 0 {
619 z
[0] = byte(extensionsLength
>> 8)
620 z
[1] = byte(extensionsLength
)
624 z
[0] = byte(extensionNextProtoNeg
>> 8)
625 z
[1] = byte(extensionNextProtoNeg
& 0xff)
626 z
[2] = byte(nextProtoLen
>> 8)
627 z
[3] = byte(nextProtoLen
)
630 for _
, v
:= range m
.nextProtos
{
636 copy(z
[1:], []byte(v
[0:l
]))
641 z
[0] = byte(extensionStatusRequest
>> 8)
642 z
[1] = byte(extensionStatusRequest
)
645 if m
.ticketSupported
{
646 z
[0] = byte(extensionSessionTicket
>> 8)
647 z
[1] = byte(extensionSessionTicket
)
650 if m
.secureRenegotiationSupported
{
651 z
[0] = byte(extensionRenegotiationInfo
>> 8)
652 z
[1] = byte(extensionRenegotiationInfo
& 0xff)
654 z
[3] = byte(len(m
.secureRenegotiation
) + 1)
655 z
[4] = byte(len(m
.secureRenegotiation
))
657 copy(z
, m
.secureRenegotiation
)
658 z
= z
[len(m
.secureRenegotiation
):]
660 if alpnLen
:= len(m
.alpnProtocol
); alpnLen
> 0 {
661 z
[0] = byte(extensionALPN
>> 8)
662 z
[1] = byte(extensionALPN
& 0xff)
671 copy(z
[7:], []byte(m
.alpnProtocol
))
675 z
[0] = byte(extensionSCT
>> 8)
676 z
[1] = byte(extensionSCT
)
680 z
[4] = byte(sctLen
>> 8)
684 for _
, sct
:= range m
.scts
{
685 z
[0] = byte(len(sct
) >> 8)
686 z
[1] = byte(len(sct
))
697 func (m
*serverHelloMsg
) unmarshal(data
[]byte) bool {
702 m
.vers
= uint16(data
[4])<<8 |
uint16(data
[5])
703 m
.random
= data
[6:38]
704 sessionIdLen
:= int(data
[38])
705 if sessionIdLen
> 32 ||
len(data
) < 39+sessionIdLen
{
708 m
.sessionId
= data
[39 : 39+sessionIdLen
]
709 data
= data
[39+sessionIdLen
:]
713 m
.cipherSuite
= uint16(data
[0])<<8 |
uint16(data
[1])
714 m
.compressionMethod
= data
[2]
717 m
.nextProtoNeg
= false
719 m
.ocspStapling
= false
721 m
.ticketSupported
= false
725 // ServerHello is optionally followed by extension data
732 extensionsLength
:= int(data
[0])<<8 |
int(data
[1])
734 if len(data
) != extensionsLength
{
742 extension
:= uint16(data
[0])<<8 |
uint16(data
[1])
743 length
:= int(data
[2])<<8 |
int(data
[3])
745 if len(data
) < length
{
750 case extensionNextProtoNeg
:
751 m
.nextProtoNeg
= true
756 if l
== 0 || l
> len(d
) {
759 m
.nextProtos
= append(m
.nextProtos
, string(d
[:l
]))
762 case extensionStatusRequest
:
766 m
.ocspStapling
= true
767 case extensionSessionTicket
:
771 m
.ticketSupported
= true
772 case extensionRenegotiationInfo
:
783 m
.secureRenegotiation
= d
784 m
.secureRenegotiationSupported
= true
790 l
:= int(d
[0])<<8 |
int(d
[1])
801 // ALPN protocols must not be empty.
804 m
.alpnProtocol
= string(d
)
811 l
:= int(d
[0])<<8 |
int(d
[1])
813 if len(d
) != l || l
== 0 {
817 m
.scts
= make([][]byte, 0, 3)
822 sctLen
:= int(d
[0])<<8 |
int(d
[1])
824 if sctLen
== 0 ||
len(d
) < sctLen
{
827 m
.scts
= append(m
.scts
, d
[:sctLen
])
837 type certificateMsg
struct {
839 certificates
[][]byte
842 func (m
*certificateMsg
) equal(i
interface{}) bool {
843 m1
, ok
:= i
.(*certificateMsg
)
848 return bytes
.Equal(m
.raw
, m1
.raw
) &&
849 eqByteSlices(m
.certificates
, m1
.certificates
)
852 func (m
*certificateMsg
) marshal() (x
[]byte) {
858 for _
, slice
:= range m
.certificates
{
862 length
:= 3 + 3*len(m
.certificates
) + i
863 x
= make([]byte, 4+length
)
864 x
[0] = typeCertificate
865 x
[1] = uint8(length
>> 16)
866 x
[2] = uint8(length
>> 8)
869 certificateOctets
:= length
- 3
870 x
[4] = uint8(certificateOctets
>> 16)
871 x
[5] = uint8(certificateOctets
>> 8)
872 x
[6] = uint8(certificateOctets
)
875 for _
, slice
:= range m
.certificates
{
876 y
[0] = uint8(len(slice
) >> 16)
877 y
[1] = uint8(len(slice
) >> 8)
878 y
[2] = uint8(len(slice
))
887 func (m
*certificateMsg
) unmarshal(data
[]byte) bool {
893 certsLen
:= uint32(data
[4])<<16 |
uint32(data
[5])<<8 |
uint32(data
[6])
894 if uint32(len(data
)) != certsLen
+7 {
904 certLen
:= uint32(d
[0])<<16 |
uint32(d
[1])<<8 |
uint32(d
[2])
905 if uint32(len(d
)) < 3+certLen
{
909 certsLen
-= 3 + certLen
913 m
.certificates
= make([][]byte, numCerts
)
915 for i
:= 0; i
< numCerts
; i
++ {
916 certLen
:= uint32(d
[0])<<16 |
uint32(d
[1])<<8 |
uint32(d
[2])
917 m
.certificates
[i
] = d
[3 : 3+certLen
]
924 type serverKeyExchangeMsg
struct {
929 func (m
*serverKeyExchangeMsg
) equal(i
interface{}) bool {
930 m1
, ok
:= i
.(*serverKeyExchangeMsg
)
935 return bytes
.Equal(m
.raw
, m1
.raw
) &&
936 bytes
.Equal(m
.key
, m1
.key
)
939 func (m
*serverKeyExchangeMsg
) marshal() []byte {
944 x
:= make([]byte, length
+4)
945 x
[0] = typeServerKeyExchange
946 x
[1] = uint8(length
>> 16)
947 x
[2] = uint8(length
>> 8)
955 func (m
*serverKeyExchangeMsg
) unmarshal(data
[]byte) bool {
964 type certificateStatusMsg
struct {
970 func (m
*certificateStatusMsg
) equal(i
interface{}) bool {
971 m1
, ok
:= i
.(*certificateStatusMsg
)
976 return bytes
.Equal(m
.raw
, m1
.raw
) &&
977 m
.statusType
== m1
.statusType
&&
978 bytes
.Equal(m
.response
, m1
.response
)
981 func (m
*certificateStatusMsg
) marshal() []byte {
987 if m
.statusType
== statusTypeOCSP
{
988 x
= make([]byte, 4+4+len(m
.response
))
989 x
[0] = typeCertificateStatus
990 l
:= len(m
.response
) + 4
994 x
[4] = statusTypeOCSP
1000 copy(x
[8:], m
.response
)
1002 x
= []byte{typeCertificateStatus
, 0, 0, 1, m
.statusType
}
1009 func (m
*certificateStatusMsg
) unmarshal(data
[]byte) bool {
1014 m
.statusType
= data
[4]
1017 if m
.statusType
== statusTypeOCSP
{
1021 respLen
:= uint32(data
[5])<<16 |
uint32(data
[6])<<8 |
uint32(data
[7])
1022 if uint32(len(data
)) != 4+4+respLen
{
1025 m
.response
= data
[8:]
1030 type serverHelloDoneMsg
struct{}
1032 func (m
*serverHelloDoneMsg
) equal(i
interface{}) bool {
1033 _
, ok
:= i
.(*serverHelloDoneMsg
)
1037 func (m
*serverHelloDoneMsg
) marshal() []byte {
1038 x
:= make([]byte, 4)
1039 x
[0] = typeServerHelloDone
1043 func (m
*serverHelloDoneMsg
) unmarshal(data
[]byte) bool {
1044 return len(data
) == 4
1047 type clientKeyExchangeMsg
struct {
1052 func (m
*clientKeyExchangeMsg
) equal(i
interface{}) bool {
1053 m1
, ok
:= i
.(*clientKeyExchangeMsg
)
1058 return bytes
.Equal(m
.raw
, m1
.raw
) &&
1059 bytes
.Equal(m
.ciphertext
, m1
.ciphertext
)
1062 func (m
*clientKeyExchangeMsg
) marshal() []byte {
1066 length
:= len(m
.ciphertext
)
1067 x
:= make([]byte, length
+4)
1068 x
[0] = typeClientKeyExchange
1069 x
[1] = uint8(length
>> 16)
1070 x
[2] = uint8(length
>> 8)
1071 x
[3] = uint8(length
)
1072 copy(x
[4:], m
.ciphertext
)
1078 func (m
*clientKeyExchangeMsg
) unmarshal(data
[]byte) bool {
1083 l
:= int(data
[1])<<16 |
int(data
[2])<<8 |
int(data
[3])
1084 if l
!= len(data
)-4 {
1087 m
.ciphertext
= data
[4:]
1091 type finishedMsg
struct {
1096 func (m
*finishedMsg
) equal(i
interface{}) bool {
1097 m1
, ok
:= i
.(*finishedMsg
)
1102 return bytes
.Equal(m
.raw
, m1
.raw
) &&
1103 bytes
.Equal(m
.verifyData
, m1
.verifyData
)
1106 func (m
*finishedMsg
) marshal() (x
[]byte) {
1111 x
= make([]byte, 4+len(m
.verifyData
))
1113 x
[3] = byte(len(m
.verifyData
))
1114 copy(x
[4:], m
.verifyData
)
1119 func (m
*finishedMsg
) unmarshal(data
[]byte) bool {
1124 m
.verifyData
= data
[4:]
1128 type nextProtoMsg
struct {
1133 func (m
*nextProtoMsg
) equal(i
interface{}) bool {
1134 m1
, ok
:= i
.(*nextProtoMsg
)
1139 return bytes
.Equal(m
.raw
, m1
.raw
) &&
1143 func (m
*nextProtoMsg
) marshal() []byte {
1152 padding
:= 32 - (l
+2)%32
1153 length
:= l
+ padding
+ 2
1154 x
:= make([]byte, length
+4)
1155 x
[0] = typeNextProtocol
1156 x
[1] = uint8(length
>> 16)
1157 x
[2] = uint8(length
>> 8)
1158 x
[3] = uint8(length
)
1162 copy(y
[1:], []byte(m
.proto
[0:l
]))
1164 y
[0] = byte(padding
)
1171 func (m
*nextProtoMsg
) unmarshal(data
[]byte) bool {
1178 protoLen
:= int(data
[0])
1180 if len(data
) < protoLen
{
1183 m
.proto
= string(data
[0:protoLen
])
1184 data
= data
[protoLen
:]
1189 paddingLen
:= int(data
[0])
1191 if len(data
) != paddingLen
{
1198 type certificateRequestMsg
struct {
1200 // hasSignatureAndHash indicates whether this message includes a list
1201 // of signature and hash functions. This change was introduced with TLS
1203 hasSignatureAndHash
bool
1205 certificateTypes
[]byte
1206 supportedSignatureAlgorithms
[]SignatureScheme
1207 certificateAuthorities
[][]byte
1210 func (m
*certificateRequestMsg
) equal(i
interface{}) bool {
1211 m1
, ok
:= i
.(*certificateRequestMsg
)
1216 return bytes
.Equal(m
.raw
, m1
.raw
) &&
1217 bytes
.Equal(m
.certificateTypes
, m1
.certificateTypes
) &&
1218 eqByteSlices(m
.certificateAuthorities
, m1
.certificateAuthorities
) &&
1219 eqSignatureAlgorithms(m
.supportedSignatureAlgorithms
, m1
.supportedSignatureAlgorithms
)
1222 func (m
*certificateRequestMsg
) marshal() (x
[]byte) {
1227 // See https://tools.ietf.org/html/rfc4346#section-7.4.4
1228 length
:= 1 + len(m
.certificateTypes
) + 2
1230 for _
, ca
:= range m
.certificateAuthorities
{
1231 casLength
+= 2 + len(ca
)
1235 if m
.hasSignatureAndHash
{
1236 length
+= 2 + 2*len(m
.supportedSignatureAlgorithms
)
1239 x
= make([]byte, 4+length
)
1240 x
[0] = typeCertificateRequest
1241 x
[1] = uint8(length
>> 16)
1242 x
[2] = uint8(length
>> 8)
1243 x
[3] = uint8(length
)
1245 x
[4] = uint8(len(m
.certificateTypes
))
1247 copy(x
[5:], m
.certificateTypes
)
1248 y
:= x
[5+len(m
.certificateTypes
):]
1250 if m
.hasSignatureAndHash
{
1251 n
:= len(m
.supportedSignatureAlgorithms
) * 2
1252 y
[0] = uint8(n
>> 8)
1255 for _
, sigAlgo
:= range m
.supportedSignatureAlgorithms
{
1256 y
[0] = uint8(sigAlgo
>> 8)
1257 y
[1] = uint8(sigAlgo
)
1262 y
[0] = uint8(casLength
>> 8)
1263 y
[1] = uint8(casLength
)
1265 for _
, ca
:= range m
.certificateAuthorities
{
1266 y
[0] = uint8(len(ca
) >> 8)
1267 y
[1] = uint8(len(ca
))
1277 func (m
*certificateRequestMsg
) unmarshal(data
[]byte) bool {
1284 length
:= uint32(data
[1])<<16 |
uint32(data
[2])<<8 |
uint32(data
[3])
1285 if uint32(len(data
))-4 != length
{
1289 numCertTypes
:= int(data
[4])
1291 if numCertTypes
== 0 ||
len(data
) <= numCertTypes
{
1295 m
.certificateTypes
= make([]byte, numCertTypes
)
1296 if copy(m
.certificateTypes
, data
) != numCertTypes
{
1300 data
= data
[numCertTypes
:]
1302 if m
.hasSignatureAndHash
{
1306 sigAndHashLen
:= uint16(data
[0])<<8 |
uint16(data
[1])
1308 if sigAndHashLen
&1 != 0 {
1311 if len(data
) < int(sigAndHashLen
) {
1314 numSigAlgos
:= sigAndHashLen
/ 2
1315 m
.supportedSignatureAlgorithms
= make([]SignatureScheme
, numSigAlgos
)
1316 for i
:= range m
.supportedSignatureAlgorithms
{
1317 m
.supportedSignatureAlgorithms
[i
] = SignatureScheme(data
[0])<<8 |
SignatureScheme(data
[1])
1325 casLength
:= uint16(data
[0])<<8 |
uint16(data
[1])
1327 if len(data
) < int(casLength
) {
1330 cas
:= make([]byte, casLength
)
1332 data
= data
[casLength
:]
1334 m
.certificateAuthorities
= nil
1339 caLen
:= uint16(cas
[0])<<8 |
uint16(cas
[1])
1342 if len(cas
) < int(caLen
) {
1346 m
.certificateAuthorities
= append(m
.certificateAuthorities
, cas
[:caLen
])
1350 return len(data
) == 0
1353 type certificateVerifyMsg
struct {
1355 hasSignatureAndHash
bool
1356 signatureAlgorithm SignatureScheme
1360 func (m
*certificateVerifyMsg
) equal(i
interface{}) bool {
1361 m1
, ok
:= i
.(*certificateVerifyMsg
)
1366 return bytes
.Equal(m
.raw
, m1
.raw
) &&
1367 m
.hasSignatureAndHash
== m1
.hasSignatureAndHash
&&
1368 m
.signatureAlgorithm
== m1
.signatureAlgorithm
&&
1369 bytes
.Equal(m
.signature
, m1
.signature
)
1372 func (m
*certificateVerifyMsg
) marshal() (x
[]byte) {
1377 // See https://tools.ietf.org/html/rfc4346#section-7.4.8
1378 siglength
:= len(m
.signature
)
1379 length
:= 2 + siglength
1380 if m
.hasSignatureAndHash
{
1383 x
= make([]byte, 4+length
)
1384 x
[0] = typeCertificateVerify
1385 x
[1] = uint8(length
>> 16)
1386 x
[2] = uint8(length
>> 8)
1387 x
[3] = uint8(length
)
1389 if m
.hasSignatureAndHash
{
1390 y
[0] = uint8(m
.signatureAlgorithm
>> 8)
1391 y
[1] = uint8(m
.signatureAlgorithm
)
1394 y
[0] = uint8(siglength
>> 8)
1395 y
[1] = uint8(siglength
)
1396 copy(y
[2:], m
.signature
)
1403 func (m
*certificateVerifyMsg
) unmarshal(data
[]byte) bool {
1410 length
:= uint32(data
[1])<<16 |
uint32(data
[2])<<8 |
uint32(data
[3])
1411 if uint32(len(data
))-4 != length
{
1416 if m
.hasSignatureAndHash
{
1417 m
.signatureAlgorithm
= SignatureScheme(data
[0])<<8 |
SignatureScheme(data
[1])
1424 siglength
:= int(data
[0])<<8 + int(data
[1])
1426 if len(data
) != siglength
{
1435 type newSessionTicketMsg
struct {
1440 func (m
*newSessionTicketMsg
) equal(i
interface{}) bool {
1441 m1
, ok
:= i
.(*newSessionTicketMsg
)
1446 return bytes
.Equal(m
.raw
, m1
.raw
) &&
1447 bytes
.Equal(m
.ticket
, m1
.ticket
)
1450 func (m
*newSessionTicketMsg
) marshal() (x
[]byte) {
1455 // See https://tools.ietf.org/html/rfc5077#section-3.3
1456 ticketLen
:= len(m
.ticket
)
1457 length
:= 2 + 4 + ticketLen
1458 x
= make([]byte, 4+length
)
1459 x
[0] = typeNewSessionTicket
1460 x
[1] = uint8(length
>> 16)
1461 x
[2] = uint8(length
>> 8)
1462 x
[3] = uint8(length
)
1463 x
[8] = uint8(ticketLen
>> 8)
1464 x
[9] = uint8(ticketLen
)
1465 copy(x
[10:], m
.ticket
)
1472 func (m
*newSessionTicketMsg
) unmarshal(data
[]byte) bool {
1479 length
:= uint32(data
[1])<<16 |
uint32(data
[2])<<8 |
uint32(data
[3])
1480 if uint32(len(data
))-4 != length
{
1484 ticketLen
:= int(data
[8])<<8 + int(data
[9])
1485 if len(data
)-10 != ticketLen
{
1489 m
.ticket
= data
[10:]
1494 type helloRequestMsg
struct {
1497 func (*helloRequestMsg
) marshal() []byte {
1498 return []byte{typeHelloRequest
, 0, 0, 0}
1501 func (*helloRequestMsg
) unmarshal(data
[]byte) bool {
1502 return len(data
) == 4
1505 func eqUint16s(x
, y
[]uint16) bool {
1506 if len(x
) != len(y
) {
1509 for i
, v
:= range x
{
1517 func eqCurveIDs(x
, y
[]CurveID
) bool {
1518 if len(x
) != len(y
) {
1521 for i
, v
:= range x
{
1529 func eqStrings(x
, y
[]string) bool {
1530 if len(x
) != len(y
) {
1533 for i
, v
:= range x
{
1541 func eqByteSlices(x
, y
[][]byte) bool {
1542 if len(x
) != len(y
) {
1545 for i
, v
:= range x
{
1546 if !bytes
.Equal(v
, y
[i
]) {
1553 func eqSignatureAlgorithms(x
, y
[]SignatureScheme
) bool {
1554 if len(x
) != len(y
) {
1557 for i
, v
:= range x
{