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.
9 type clientHelloMsg
struct {
15 compressionMethods
[]uint8
19 supportedCurves
[]CurveID
20 supportedPoints
[]uint8
23 signatureAndHashes
[]signatureAndHash
24 secureRenegotiation
bool
27 func (m
*clientHelloMsg
) equal(i
interface{}) bool {
28 m1
, ok
:= i
.(*clientHelloMsg
)
33 return bytes
.Equal(m
.raw
, m1
.raw
) &&
35 bytes
.Equal(m
.random
, m1
.random
) &&
36 bytes
.Equal(m
.sessionId
, m1
.sessionId
) &&
37 eqUint16s(m
.cipherSuites
, m1
.cipherSuites
) &&
38 bytes
.Equal(m
.compressionMethods
, m1
.compressionMethods
) &&
39 m
.nextProtoNeg
== m1
.nextProtoNeg
&&
40 m
.serverName
== m1
.serverName
&&
41 m
.ocspStapling
== m1
.ocspStapling
&&
42 eqCurveIDs(m
.supportedCurves
, m1
.supportedCurves
) &&
43 bytes
.Equal(m
.supportedPoints
, m1
.supportedPoints
) &&
44 m
.ticketSupported
== m1
.ticketSupported
&&
45 bytes
.Equal(m
.sessionTicket
, m1
.sessionTicket
) &&
46 eqSignatureAndHashes(m
.signatureAndHashes
, m1
.signatureAndHashes
) &&
47 m
.secureRenegotiation
== m1
.secureRenegotiation
50 func (m
*clientHelloMsg
) marshal() []byte {
55 length
:= 2 + 32 + 1 + len(m
.sessionId
) + 2 + len(m
.cipherSuites
)*2 + 1 + len(m
.compressionMethods
)
62 extensionsLength
+= 1 + 2 + 2
65 if len(m
.serverName
) > 0 {
66 extensionsLength
+= 5 + len(m
.serverName
)
69 if len(m
.supportedCurves
) > 0 {
70 extensionsLength
+= 2 + 2*len(m
.supportedCurves
)
73 if len(m
.supportedPoints
) > 0 {
74 extensionsLength
+= 1 + len(m
.supportedPoints
)
77 if m
.ticketSupported
{
78 extensionsLength
+= len(m
.sessionTicket
)
81 if len(m
.signatureAndHashes
) > 0 {
82 extensionsLength
+= 2 + 2*len(m
.signatureAndHashes
)
85 if m
.secureRenegotiation
{
89 if numExtensions
> 0 {
90 extensionsLength
+= 4 * numExtensions
91 length
+= 2 + extensionsLength
94 x
:= make([]byte, 4+length
)
95 x
[0] = typeClientHello
96 x
[1] = uint8(length
>> 16)
97 x
[2] = uint8(length
>> 8)
99 x
[4] = uint8(m
.vers
>> 8)
101 copy(x
[6:38], m
.random
)
102 x
[38] = uint8(len(m
.sessionId
))
103 copy(x
[39:39+len(m
.sessionId
)], m
.sessionId
)
104 y
:= x
[39+len(m
.sessionId
):]
105 y
[0] = uint8(len(m
.cipherSuites
) >> 7)
106 y
[1] = uint8(len(m
.cipherSuites
) << 1)
107 for i
, suite
:= range m
.cipherSuites
{
108 y
[2+i
*2] = uint8(suite
>> 8)
109 y
[3+i
*2] = uint8(suite
)
111 z
:= y
[2+len(m
.cipherSuites
)*2:]
112 z
[0] = uint8(len(m
.compressionMethods
))
113 copy(z
[1:], m
.compressionMethods
)
115 z
= z
[1+len(m
.compressionMethods
):]
116 if numExtensions
> 0 {
117 z
[0] = byte(extensionsLength
>> 8)
118 z
[1] = byte(extensionsLength
)
122 z
[0] = byte(extensionNextProtoNeg
>> 8)
123 z
[1] = byte(extensionNextProtoNeg
& 0xff)
124 // The length is always 0
127 if len(m
.serverName
) > 0 {
128 z
[0] = byte(extensionServerName
>> 8)
129 z
[1] = byte(extensionServerName
& 0xff)
130 l
:= len(m
.serverName
) + 5
135 // RFC 3546, section 3.1
138 // NameType name_type;
139 // select (name_type) {
140 // case host_name: HostName;
145 // host_name(0), (255)
148 // opaque HostName<1..2^16-1>;
151 // ServerName server_name_list<1..2^16-1>
154 z
[0] = byte((len(m
.serverName
) + 3) >> 8)
155 z
[1] = byte(len(m
.serverName
) + 3)
156 z
[3] = byte(len(m
.serverName
) >> 8)
157 z
[4] = byte(len(m
.serverName
))
158 copy(z
[5:], []byte(m
.serverName
))
162 // RFC 4366, section 3.6
163 z
[0] = byte(extensionStatusRequest
>> 8)
164 z
[1] = byte(extensionStatusRequest
)
167 z
[4] = 1 // OCSP type
168 // Two zero valued uint16s for the two lengths.
171 if len(m
.supportedCurves
) > 0 {
172 // http://tools.ietf.org/html/rfc4492#section-5.5.1
173 z
[0] = byte(extensionSupportedCurves
>> 8)
174 z
[1] = byte(extensionSupportedCurves
)
175 l
:= 2 + 2*len(m
.supportedCurves
)
182 for _
, curve
:= range m
.supportedCurves
{
183 z
[0] = byte(curve
>> 8)
188 if len(m
.supportedPoints
) > 0 {
189 // http://tools.ietf.org/html/rfc4492#section-5.5.2
190 z
[0] = byte(extensionSupportedPoints
>> 8)
191 z
[1] = byte(extensionSupportedPoints
)
192 l
:= 1 + len(m
.supportedPoints
)
198 for _
, pointFormat
:= range m
.supportedPoints
{
199 z
[0] = byte(pointFormat
)
203 if m
.ticketSupported
{
204 // http://tools.ietf.org/html/rfc5077#section-3.2
205 z
[0] = byte(extensionSessionTicket
>> 8)
206 z
[1] = byte(extensionSessionTicket
)
207 l
:= len(m
.sessionTicket
)
211 copy(z
, m
.sessionTicket
)
212 z
= z
[len(m
.sessionTicket
):]
214 if len(m
.signatureAndHashes
) > 0 {
215 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
216 z
[0] = byte(extensionSignatureAlgorithms
>> 8)
217 z
[1] = byte(extensionSignatureAlgorithms
)
218 l
:= 2 + 2*len(m
.signatureAndHashes
)
227 for _
, sigAndHash
:= range m
.signatureAndHashes
{
228 z
[0] = sigAndHash
.hash
229 z
[1] = sigAndHash
.signature
233 if m
.secureRenegotiation
{
234 z
[0] = byte(extensionRenegotiationInfo
>> 8)
235 z
[1] = byte(extensionRenegotiationInfo
& 0xff)
246 func (m
*clientHelloMsg
) unmarshal(data
[]byte) bool {
251 m
.vers
= uint16(data
[4])<<8 |
uint16(data
[5])
252 m
.random
= data
[6:38]
253 sessionIdLen
:= int(data
[38])
254 if sessionIdLen
> 32 ||
len(data
) < 39+sessionIdLen
{
257 m
.sessionId
= data
[39 : 39+sessionIdLen
]
258 data
= data
[39+sessionIdLen
:]
262 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
263 // they are uint16s, the number must be even.
264 cipherSuiteLen
:= int(data
[0])<<8 |
int(data
[1])
265 if cipherSuiteLen%2
== 1 ||
len(data
) < 2+cipherSuiteLen
{
268 numCipherSuites
:= cipherSuiteLen
/ 2
269 m
.cipherSuites
= make([]uint16, numCipherSuites
)
270 for i
:= 0; i
< numCipherSuites
; i
++ {
271 m
.cipherSuites
[i
] = uint16(data
[2+2*i
])<<8 |
uint16(data
[3+2*i
])
272 if m
.cipherSuites
[i
] == scsvRenegotiation
{
273 m
.secureRenegotiation
= true
276 data
= data
[2+cipherSuiteLen
:]
280 compressionMethodsLen
:= int(data
[0])
281 if len(data
) < 1+compressionMethodsLen
{
284 m
.compressionMethods
= data
[1 : 1+compressionMethodsLen
]
286 data
= data
[1+compressionMethodsLen
:]
288 m
.nextProtoNeg
= false
290 m
.ocspStapling
= false
291 m
.ticketSupported
= false
292 m
.sessionTicket
= nil
293 m
.signatureAndHashes
= nil
296 // ClientHello is optionally followed by extension data
303 extensionsLength
:= int(data
[0])<<8 |
int(data
[1])
305 if extensionsLength
!= len(data
) {
313 extension
:= uint16(data
[0])<<8 |
uint16(data
[1])
314 length
:= int(data
[2])<<8 |
int(data
[3])
316 if len(data
) < length
{
321 case extensionServerName
:
325 numNames
:= int(data
[0])<<8 |
int(data
[1])
327 for i
:= 0; i
< numNames
; i
++ {
332 nameLen
:= int(d
[1])<<8 |
int(d
[2])
334 if len(d
) < nameLen
{
338 m
.serverName
= string(d
[0:nameLen
])
343 case extensionNextProtoNeg
:
347 m
.nextProtoNeg
= true
348 case extensionStatusRequest
:
349 m
.ocspStapling
= length
> 0 && data
[0] == statusTypeOCSP
350 case extensionSupportedCurves
:
351 // http://tools.ietf.org/html/rfc4492#section-5.5.1
355 l
:= int(data
[0])<<8 |
int(data
[1])
356 if l%2
== 1 || length
!= l
+2 {
360 m
.supportedCurves
= make([]CurveID
, numCurves
)
362 for i
:= 0; i
< numCurves
; i
++ {
363 m
.supportedCurves
[i
] = CurveID(d
[0])<<8 |
CurveID(d
[1])
366 case extensionSupportedPoints
:
367 // http://tools.ietf.org/html/rfc4492#section-5.5.2
375 m
.supportedPoints
= make([]uint8, l
)
376 copy(m
.supportedPoints
, data
[1:])
377 case extensionSessionTicket
:
378 // http://tools.ietf.org/html/rfc5077#section-3.2
379 m
.ticketSupported
= true
380 m
.sessionTicket
= data
[:length
]
381 case extensionSignatureAlgorithms
:
382 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
383 if length
< 2 || length
&1 != 0 {
386 l
:= int(data
[0])<<8 |
int(data
[1])
392 m
.signatureAndHashes
= make([]signatureAndHash
, n
)
393 for i
:= range m
.signatureAndHashes
{
394 m
.signatureAndHashes
[i
].hash
= d
[0]
395 m
.signatureAndHashes
[i
].signature
= d
[1]
398 case extensionRenegotiationInfo
+ 1:
399 if length
!= 1 || data
[0] != 0 {
402 m
.secureRenegotiation
= true
410 type serverHelloMsg
struct {
416 compressionMethod
uint8
421 secureRenegotiation
bool
424 func (m
*serverHelloMsg
) equal(i
interface{}) bool {
425 m1
, ok
:= i
.(*serverHelloMsg
)
430 return bytes
.Equal(m
.raw
, m1
.raw
) &&
432 bytes
.Equal(m
.random
, m1
.random
) &&
433 bytes
.Equal(m
.sessionId
, m1
.sessionId
) &&
434 m
.cipherSuite
== m1
.cipherSuite
&&
435 m
.compressionMethod
== m1
.compressionMethod
&&
436 m
.nextProtoNeg
== m1
.nextProtoNeg
&&
437 eqStrings(m
.nextProtos
, m1
.nextProtos
) &&
438 m
.ocspStapling
== m1
.ocspStapling
&&
439 m
.ticketSupported
== m1
.ticketSupported
&&
440 m
.secureRenegotiation
== m1
.secureRenegotiation
443 func (m
*serverHelloMsg
) marshal() []byte {
448 length
:= 38 + len(m
.sessionId
)
450 extensionsLength
:= 0
455 for _
, v
:= range m
.nextProtos
{
456 nextProtoLen
+= len(v
)
458 nextProtoLen
+= len(m
.nextProtos
)
459 extensionsLength
+= nextProtoLen
464 if m
.ticketSupported
{
467 if m
.secureRenegotiation
{
468 extensionsLength
+= 1
471 if numExtensions
> 0 {
472 extensionsLength
+= 4 * numExtensions
473 length
+= 2 + extensionsLength
476 x
:= make([]byte, 4+length
)
477 x
[0] = typeServerHello
478 x
[1] = uint8(length
>> 16)
479 x
[2] = uint8(length
>> 8)
481 x
[4] = uint8(m
.vers
>> 8)
483 copy(x
[6:38], m
.random
)
484 x
[38] = uint8(len(m
.sessionId
))
485 copy(x
[39:39+len(m
.sessionId
)], m
.sessionId
)
486 z
:= x
[39+len(m
.sessionId
):]
487 z
[0] = uint8(m
.cipherSuite
>> 8)
488 z
[1] = uint8(m
.cipherSuite
)
489 z
[2] = uint8(m
.compressionMethod
)
492 if numExtensions
> 0 {
493 z
[0] = byte(extensionsLength
>> 8)
494 z
[1] = byte(extensionsLength
)
498 z
[0] = byte(extensionNextProtoNeg
>> 8)
499 z
[1] = byte(extensionNextProtoNeg
& 0xff)
500 z
[2] = byte(nextProtoLen
>> 8)
501 z
[3] = byte(nextProtoLen
)
504 for _
, v
:= range m
.nextProtos
{
510 copy(z
[1:], []byte(v
[0:l
]))
515 z
[0] = byte(extensionStatusRequest
>> 8)
516 z
[1] = byte(extensionStatusRequest
)
519 if m
.ticketSupported
{
520 z
[0] = byte(extensionSessionTicket
>> 8)
521 z
[1] = byte(extensionSessionTicket
)
524 if m
.secureRenegotiation
{
525 z
[0] = byte(extensionRenegotiationInfo
>> 8)
526 z
[1] = byte(extensionRenegotiationInfo
& 0xff)
537 func (m
*serverHelloMsg
) unmarshal(data
[]byte) bool {
542 m
.vers
= uint16(data
[4])<<8 |
uint16(data
[5])
543 m
.random
= data
[6:38]
544 sessionIdLen
:= int(data
[38])
545 if sessionIdLen
> 32 ||
len(data
) < 39+sessionIdLen
{
548 m
.sessionId
= data
[39 : 39+sessionIdLen
]
549 data
= data
[39+sessionIdLen
:]
553 m
.cipherSuite
= uint16(data
[0])<<8 |
uint16(data
[1])
554 m
.compressionMethod
= data
[2]
557 m
.nextProtoNeg
= false
559 m
.ocspStapling
= false
560 m
.ticketSupported
= false
563 // ServerHello is optionally followed by extension data
570 extensionsLength
:= int(data
[0])<<8 |
int(data
[1])
572 if len(data
) != extensionsLength
{
580 extension
:= uint16(data
[0])<<8 |
uint16(data
[1])
581 length
:= int(data
[2])<<8 |
int(data
[3])
583 if len(data
) < length
{
588 case extensionNextProtoNeg
:
589 m
.nextProtoNeg
= true
594 if l
== 0 || l
> len(d
) {
597 m
.nextProtos
= append(m
.nextProtos
, string(d
[:l
]))
600 case extensionStatusRequest
:
604 m
.ocspStapling
= true
605 case extensionSessionTicket
:
609 m
.ticketSupported
= true
610 case extensionRenegotiationInfo
:
611 if length
!= 1 || data
[0] != 0 {
614 m
.secureRenegotiation
= true
622 type certificateMsg
struct {
624 certificates
[][]byte
627 func (m
*certificateMsg
) equal(i
interface{}) bool {
628 m1
, ok
:= i
.(*certificateMsg
)
633 return bytes
.Equal(m
.raw
, m1
.raw
) &&
634 eqByteSlices(m
.certificates
, m1
.certificates
)
637 func (m
*certificateMsg
) marshal() (x
[]byte) {
643 for _
, slice
:= range m
.certificates
{
647 length
:= 3 + 3*len(m
.certificates
) + i
648 x
= make([]byte, 4+length
)
649 x
[0] = typeCertificate
650 x
[1] = uint8(length
>> 16)
651 x
[2] = uint8(length
>> 8)
654 certificateOctets
:= length
- 3
655 x
[4] = uint8(certificateOctets
>> 16)
656 x
[5] = uint8(certificateOctets
>> 8)
657 x
[6] = uint8(certificateOctets
)
660 for _
, slice
:= range m
.certificates
{
661 y
[0] = uint8(len(slice
) >> 16)
662 y
[1] = uint8(len(slice
) >> 8)
663 y
[2] = uint8(len(slice
))
672 func (m
*certificateMsg
) unmarshal(data
[]byte) bool {
678 certsLen
:= uint32(data
[4])<<16 |
uint32(data
[5])<<8 |
uint32(data
[6])
679 if uint32(len(data
)) != certsLen
+7 {
689 certLen
:= uint32(d
[0])<<16 |
uint32(d
[1])<<8 |
uint32(d
[2])
690 if uint32(len(d
)) < 3+certLen
{
694 certsLen
-= 3 + certLen
698 m
.certificates
= make([][]byte, numCerts
)
700 for i
:= 0; i
< numCerts
; i
++ {
701 certLen
:= uint32(d
[0])<<16 |
uint32(d
[1])<<8 |
uint32(d
[2])
702 m
.certificates
[i
] = d
[3 : 3+certLen
]
709 type serverKeyExchangeMsg
struct {
714 func (m
*serverKeyExchangeMsg
) equal(i
interface{}) bool {
715 m1
, ok
:= i
.(*serverKeyExchangeMsg
)
720 return bytes
.Equal(m
.raw
, m1
.raw
) &&
721 bytes
.Equal(m
.key
, m1
.key
)
724 func (m
*serverKeyExchangeMsg
) marshal() []byte {
729 x
:= make([]byte, length
+4)
730 x
[0] = typeServerKeyExchange
731 x
[1] = uint8(length
>> 16)
732 x
[2] = uint8(length
>> 8)
740 func (m
*serverKeyExchangeMsg
) unmarshal(data
[]byte) bool {
749 type certificateStatusMsg
struct {
755 func (m
*certificateStatusMsg
) equal(i
interface{}) bool {
756 m1
, ok
:= i
.(*certificateStatusMsg
)
761 return bytes
.Equal(m
.raw
, m1
.raw
) &&
762 m
.statusType
== m1
.statusType
&&
763 bytes
.Equal(m
.response
, m1
.response
)
766 func (m
*certificateStatusMsg
) marshal() []byte {
772 if m
.statusType
== statusTypeOCSP
{
773 x
= make([]byte, 4+4+len(m
.response
))
774 x
[0] = typeCertificateStatus
775 l
:= len(m
.response
) + 4
779 x
[4] = statusTypeOCSP
785 copy(x
[8:], m
.response
)
787 x
= []byte{typeCertificateStatus
, 0, 0, 1, m
.statusType
}
794 func (m
*certificateStatusMsg
) unmarshal(data
[]byte) bool {
799 m
.statusType
= data
[4]
802 if m
.statusType
== statusTypeOCSP
{
806 respLen
:= uint32(data
[5])<<16 |
uint32(data
[6])<<8 |
uint32(data
[7])
807 if uint32(len(data
)) != 4+4+respLen
{
810 m
.response
= data
[8:]
815 type serverHelloDoneMsg
struct{}
817 func (m
*serverHelloDoneMsg
) equal(i
interface{}) bool {
818 _
, ok
:= i
.(*serverHelloDoneMsg
)
822 func (m
*serverHelloDoneMsg
) marshal() []byte {
824 x
[0] = typeServerHelloDone
828 func (m
*serverHelloDoneMsg
) unmarshal(data
[]byte) bool {
829 return len(data
) == 4
832 type clientKeyExchangeMsg
struct {
837 func (m
*clientKeyExchangeMsg
) equal(i
interface{}) bool {
838 m1
, ok
:= i
.(*clientKeyExchangeMsg
)
843 return bytes
.Equal(m
.raw
, m1
.raw
) &&
844 bytes
.Equal(m
.ciphertext
, m1
.ciphertext
)
847 func (m
*clientKeyExchangeMsg
) marshal() []byte {
851 length
:= len(m
.ciphertext
)
852 x
:= make([]byte, length
+4)
853 x
[0] = typeClientKeyExchange
854 x
[1] = uint8(length
>> 16)
855 x
[2] = uint8(length
>> 8)
857 copy(x
[4:], m
.ciphertext
)
863 func (m
*clientKeyExchangeMsg
) unmarshal(data
[]byte) bool {
868 l
:= int(data
[1])<<16 |
int(data
[2])<<8 |
int(data
[3])
869 if l
!= len(data
)-4 {
872 m
.ciphertext
= data
[4:]
876 type finishedMsg
struct {
881 func (m
*finishedMsg
) equal(i
interface{}) bool {
882 m1
, ok
:= i
.(*finishedMsg
)
887 return bytes
.Equal(m
.raw
, m1
.raw
) &&
888 bytes
.Equal(m
.verifyData
, m1
.verifyData
)
891 func (m
*finishedMsg
) marshal() (x
[]byte) {
896 x
= make([]byte, 4+len(m
.verifyData
))
898 x
[3] = byte(len(m
.verifyData
))
899 copy(x
[4:], m
.verifyData
)
904 func (m
*finishedMsg
) unmarshal(data
[]byte) bool {
909 m
.verifyData
= data
[4:]
913 type nextProtoMsg
struct {
918 func (m
*nextProtoMsg
) equal(i
interface{}) bool {
919 m1
, ok
:= i
.(*nextProtoMsg
)
924 return bytes
.Equal(m
.raw
, m1
.raw
) &&
928 func (m
*nextProtoMsg
) marshal() []byte {
937 padding
:= 32 - (l
+2)%32
938 length
:= l
+ padding
+ 2
939 x
:= make([]byte, length
+4)
940 x
[0] = typeNextProtocol
941 x
[1] = uint8(length
>> 16)
942 x
[2] = uint8(length
>> 8)
947 copy(y
[1:], []byte(m
.proto
[0:l
]))
956 func (m
*nextProtoMsg
) unmarshal(data
[]byte) bool {
963 protoLen
:= int(data
[0])
965 if len(data
) < protoLen
{
968 m
.proto
= string(data
[0:protoLen
])
969 data
= data
[protoLen
:]
974 paddingLen
:= int(data
[0])
976 if len(data
) != paddingLen
{
983 type certificateRequestMsg
struct {
985 // hasSignatureAndHash indicates whether this message includes a list
986 // of signature and hash functions. This change was introduced with TLS
988 hasSignatureAndHash
bool
990 certificateTypes
[]byte
991 signatureAndHashes
[]signatureAndHash
992 certificateAuthorities
[][]byte
995 func (m
*certificateRequestMsg
) equal(i
interface{}) bool {
996 m1
, ok
:= i
.(*certificateRequestMsg
)
1001 return bytes
.Equal(m
.raw
, m1
.raw
) &&
1002 bytes
.Equal(m
.certificateTypes
, m1
.certificateTypes
) &&
1003 eqByteSlices(m
.certificateAuthorities
, m1
.certificateAuthorities
) &&
1004 eqSignatureAndHashes(m
.signatureAndHashes
, m1
.signatureAndHashes
)
1007 func (m
*certificateRequestMsg
) marshal() (x
[]byte) {
1012 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
1013 length
:= 1 + len(m
.certificateTypes
) + 2
1015 for _
, ca
:= range m
.certificateAuthorities
{
1016 casLength
+= 2 + len(ca
)
1020 if m
.hasSignatureAndHash
{
1021 length
+= 2 + 2*len(m
.signatureAndHashes
)
1024 x
= make([]byte, 4+length
)
1025 x
[0] = typeCertificateRequest
1026 x
[1] = uint8(length
>> 16)
1027 x
[2] = uint8(length
>> 8)
1028 x
[3] = uint8(length
)
1030 x
[4] = uint8(len(m
.certificateTypes
))
1032 copy(x
[5:], m
.certificateTypes
)
1033 y
:= x
[5+len(m
.certificateTypes
):]
1035 if m
.hasSignatureAndHash
{
1036 n
:= len(m
.signatureAndHashes
) * 2
1037 y
[0] = uint8(n
>> 8)
1040 for _
, sigAndHash
:= range m
.signatureAndHashes
{
1041 y
[0] = sigAndHash
.hash
1042 y
[1] = sigAndHash
.signature
1047 y
[0] = uint8(casLength
>> 8)
1048 y
[1] = uint8(casLength
)
1050 for _
, ca
:= range m
.certificateAuthorities
{
1051 y
[0] = uint8(len(ca
) >> 8)
1052 y
[1] = uint8(len(ca
))
1062 func (m
*certificateRequestMsg
) unmarshal(data
[]byte) bool {
1069 length
:= uint32(data
[1])<<16 |
uint32(data
[2])<<8 |
uint32(data
[3])
1070 if uint32(len(data
))-4 != length
{
1074 numCertTypes
:= int(data
[4])
1076 if numCertTypes
== 0 ||
len(data
) <= numCertTypes
{
1080 m
.certificateTypes
= make([]byte, numCertTypes
)
1081 if copy(m
.certificateTypes
, data
) != numCertTypes
{
1085 data
= data
[numCertTypes
:]
1087 if m
.hasSignatureAndHash
{
1091 sigAndHashLen
:= uint16(data
[0])<<8 |
uint16(data
[1])
1093 if sigAndHashLen
&1 != 0 {
1096 if len(data
) < int(sigAndHashLen
) {
1099 numSigAndHash
:= sigAndHashLen
/ 2
1100 m
.signatureAndHashes
= make([]signatureAndHash
, numSigAndHash
)
1101 for i
:= range m
.signatureAndHashes
{
1102 m
.signatureAndHashes
[i
].hash
= data
[0]
1103 m
.signatureAndHashes
[i
].signature
= data
[1]
1111 casLength
:= uint16(data
[0])<<8 |
uint16(data
[1])
1113 if len(data
) < int(casLength
) {
1116 cas
:= make([]byte, casLength
)
1118 data
= data
[casLength
:]
1120 m
.certificateAuthorities
= nil
1125 caLen
:= uint16(cas
[0])<<8 |
uint16(cas
[1])
1128 if len(cas
) < int(caLen
) {
1132 m
.certificateAuthorities
= append(m
.certificateAuthorities
, cas
[:caLen
])
1142 type certificateVerifyMsg
struct {
1144 hasSignatureAndHash
bool
1145 signatureAndHash signatureAndHash
1149 func (m
*certificateVerifyMsg
) equal(i
interface{}) bool {
1150 m1
, ok
:= i
.(*certificateVerifyMsg
)
1155 return bytes
.Equal(m
.raw
, m1
.raw
) &&
1156 m
.hasSignatureAndHash
== m1
.hasSignatureAndHash
&&
1157 m
.signatureAndHash
.hash
== m1
.signatureAndHash
.hash
&&
1158 m
.signatureAndHash
.signature
== m1
.signatureAndHash
.signature
&&
1159 bytes
.Equal(m
.signature
, m1
.signature
)
1162 func (m
*certificateVerifyMsg
) marshal() (x
[]byte) {
1167 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1168 siglength
:= len(m
.signature
)
1169 length
:= 2 + siglength
1170 if m
.hasSignatureAndHash
{
1173 x
= make([]byte, 4+length
)
1174 x
[0] = typeCertificateVerify
1175 x
[1] = uint8(length
>> 16)
1176 x
[2] = uint8(length
>> 8)
1177 x
[3] = uint8(length
)
1179 if m
.hasSignatureAndHash
{
1180 y
[0] = m
.signatureAndHash
.hash
1181 y
[1] = m
.signatureAndHash
.signature
1184 y
[0] = uint8(siglength
>> 8)
1185 y
[1] = uint8(siglength
)
1186 copy(y
[2:], m
.signature
)
1193 func (m
*certificateVerifyMsg
) unmarshal(data
[]byte) bool {
1200 length
:= uint32(data
[1])<<16 |
uint32(data
[2])<<8 |
uint32(data
[3])
1201 if uint32(len(data
))-4 != length
{
1206 if m
.hasSignatureAndHash
{
1207 m
.signatureAndHash
.hash
= data
[0]
1208 m
.signatureAndHash
.signature
= data
[1]
1215 siglength
:= int(data
[0])<<8 + int(data
[1])
1217 if len(data
) != siglength
{
1226 type newSessionTicketMsg
struct {
1231 func (m
*newSessionTicketMsg
) equal(i
interface{}) bool {
1232 m1
, ok
:= i
.(*newSessionTicketMsg
)
1237 return bytes
.Equal(m
.raw
, m1
.raw
) &&
1238 bytes
.Equal(m
.ticket
, m1
.ticket
)
1241 func (m
*newSessionTicketMsg
) marshal() (x
[]byte) {
1246 // See http://tools.ietf.org/html/rfc5077#section-3.3
1247 ticketLen
:= len(m
.ticket
)
1248 length
:= 2 + 4 + ticketLen
1249 x
= make([]byte, 4+length
)
1250 x
[0] = typeNewSessionTicket
1251 x
[1] = uint8(length
>> 16)
1252 x
[2] = uint8(length
>> 8)
1253 x
[3] = uint8(length
)
1254 x
[8] = uint8(ticketLen
>> 8)
1255 x
[9] = uint8(ticketLen
)
1256 copy(x
[10:], m
.ticket
)
1263 func (m
*newSessionTicketMsg
) unmarshal(data
[]byte) bool {
1270 length
:= uint32(data
[1])<<16 |
uint32(data
[2])<<8 |
uint32(data
[3])
1271 if uint32(len(data
))-4 != length
{
1275 ticketLen
:= int(data
[8])<<8 + int(data
[9])
1276 if len(data
)-10 != ticketLen
{
1280 m
.ticket
= data
[10:]
1285 func eqUint16s(x
, y
[]uint16) bool {
1286 if len(x
) != len(y
) {
1289 for i
, v
:= range x
{
1297 func eqCurveIDs(x
, y
[]CurveID
) bool {
1298 if len(x
) != len(y
) {
1301 for i
, v
:= range x
{
1309 func eqStrings(x
, y
[]string) bool {
1310 if len(x
) != len(y
) {
1313 for i
, v
:= range x
{
1321 func eqByteSlices(x
, y
[][]byte) bool {
1322 if len(x
) != len(y
) {
1325 for i
, v
:= range x
{
1326 if !bytes
.Equal(v
, y
[i
]) {
1333 func eqSignatureAndHashes(x
, y
[]signatureAndHash
) bool {
1334 if len(x
) != len(y
) {
1337 for i
, v
:= range x
{
1339 if v
.hash
!= v2
.hash || v
.signature
!= v2
.signature
{