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
25 duplicateExtension bool
28 func (m *clientHelloMsg) equal(i interface{}) bool {
29 m1, ok := i.(*clientHelloMsg)
34 return bytes.Equal(m.raw, m1.raw) &&
36 bytes.Equal(m.random, m1.random) &&
37 bytes.Equal(m.sessionId, m1.sessionId) &&
38 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
39 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
40 m.nextProtoNeg == m1.nextProtoNeg &&
41 m.serverName == m1.serverName &&
42 m.ocspStapling == m1.ocspStapling &&
43 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
44 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
45 m.ticketSupported == m1.ticketSupported &&
46 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
47 eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
48 m.secureRenegotiation == m1.secureRenegotiation
51 func (m *clientHelloMsg) marshal() []byte {
56 length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods)
63 extensionsLength += 1 + 2 + 2
66 if len(m.serverName) > 0 {
67 extensionsLength += 5 + len(m.serverName)
70 if len(m.supportedCurves) > 0 {
71 extensionsLength += 2 + 2*len(m.supportedCurves)
74 if len(m.supportedPoints) > 0 {
75 extensionsLength += 1 + len(m.supportedPoints)
78 if m.ticketSupported {
79 extensionsLength += len(m.sessionTicket)
82 if len(m.signatureAndHashes) > 0 {
83 extensionsLength += 2 + 2*len(m.signatureAndHashes)
86 if m.secureRenegotiation {
90 if m.duplicateExtension {
93 if numExtensions > 0 {
94 extensionsLength += 4 * numExtensions
95 length += 2 + extensionsLength
98 x := make([]byte, 4+length)
99 x[0] = typeClientHello
100 x[1] = uint8(length >> 16)
101 x[2] = uint8(length >> 8)
103 x[4] = uint8(m.vers >> 8)
105 copy(x[6:38], m.random)
106 x[38] = uint8(len(m.sessionId))
107 copy(x[39:39+len(m.sessionId)], m.sessionId)
108 y := x[39+len(m.sessionId):]
109 y[0] = uint8(len(m.cipherSuites) >> 7)
110 y[1] = uint8(len(m.cipherSuites) << 1)
111 for i, suite := range m.cipherSuites {
112 y[2+i*2] = uint8(suite >> 8)
113 y[3+i*2] = uint8(suite)
115 z := y[2+len(m.cipherSuites)*2:]
116 z[0] = uint8(len(m.compressionMethods))
117 copy(z[1:], m.compressionMethods)
119 z = z[1+len(m.compressionMethods):]
120 if numExtensions > 0 {
121 z[0] = byte(extensionsLength >> 8)
122 z[1] = byte(extensionsLength)
125 if m.duplicateExtension {
126 // Add a duplicate bogus extension at the beginning and end.
132 z[0] = byte(extensionNextProtoNeg >> 8)
133 z[1] = byte(extensionNextProtoNeg & 0xff)
134 // The length is always 0
137 if len(m.serverName) > 0 {
138 z[0] = byte(extensionServerName >> 8)
139 z[1] = byte(extensionServerName & 0xff)
140 l := len(m.serverName) + 5
145 // RFC 3546, section 3.1
148 // NameType name_type;
149 // select (name_type) {
150 // case host_name: HostName;
155 // host_name(0), (255)
158 // opaque HostName<1..2^16-1>;
161 // ServerName server_name_list<1..2^16-1>
164 z[0] = byte((len(m.serverName) + 3) >> 8)
165 z[1] = byte(len(m.serverName) + 3)
166 z[3] = byte(len(m.serverName) >> 8)
167 z[4] = byte(len(m.serverName))
168 copy(z[5:], []byte(m.serverName))
172 // RFC 4366, section 3.6
173 z[0] = byte(extensionStatusRequest >> 8)
174 z[1] = byte(extensionStatusRequest)
177 z[4] = 1 // OCSP type
178 // Two zero valued uint16s for the two lengths.
181 if len(m.supportedCurves) > 0 {
182 // http://tools.ietf.org/html/rfc4492#section-5.5.1
183 z[0] = byte(extensionSupportedCurves >> 8)
184 z[1] = byte(extensionSupportedCurves)
185 l := 2 + 2*len(m.supportedCurves)
192 for _, curve := range m.supportedCurves {
193 z[0] = byte(curve >> 8)
198 if len(m.supportedPoints) > 0 {
199 // http://tools.ietf.org/html/rfc4492#section-5.5.2
200 z[0] = byte(extensionSupportedPoints >> 8)
201 z[1] = byte(extensionSupportedPoints)
202 l := 1 + len(m.supportedPoints)
208 for _, pointFormat := range m.supportedPoints {
209 z[0] = byte(pointFormat)
213 if m.ticketSupported {
214 // http://tools.ietf.org/html/rfc5077#section-3.2
215 z[0] = byte(extensionSessionTicket >> 8)
216 z[1] = byte(extensionSessionTicket)
217 l := len(m.sessionTicket)
221 copy(z, m.sessionTicket)
222 z = z[len(m.sessionTicket):]
224 if len(m.signatureAndHashes) > 0 {
225 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
226 z[0] = byte(extensionSignatureAlgorithms >> 8)
227 z[1] = byte(extensionSignatureAlgorithms)
228 l := 2 + 2*len(m.signatureAndHashes)
237 for _, sigAndHash := range m.signatureAndHashes {
238 z[0] = sigAndHash.hash
239 z[1] = sigAndHash.signature
243 if m.secureRenegotiation {
244 z[0] = byte(extensionRenegotiationInfo >> 8)
245 z[1] = byte(extensionRenegotiationInfo & 0xff)
250 if m.duplicateExtension {
251 // Add a duplicate bogus extension at the beginning and end.
262 func (m *clientHelloMsg) unmarshal(data []byte) bool {
267 m.vers = uint16(data[4])<<8 | uint16(data[5])
268 m.random = data[6:38]
269 sessionIdLen := int(data[38])
270 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
273 m.sessionId = data[39 : 39+sessionIdLen]
274 data = data[39+sessionIdLen:]
278 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
279 // they are uint16s, the number must be even.
280 cipherSuiteLen := int(data[0])<<8 | int(data[1])
281 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
284 numCipherSuites := cipherSuiteLen / 2
285 m.cipherSuites = make([]uint16, numCipherSuites)
286 for i := 0; i < numCipherSuites; i++ {
287 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
288 if m.cipherSuites[i] == scsvRenegotiation {
289 m.secureRenegotiation = true
292 data = data[2+cipherSuiteLen:]
296 compressionMethodsLen := int(data[0])
297 if len(data) < 1+compressionMethodsLen {
300 m.compressionMethods = data[1 : 1+compressionMethodsLen]
302 data = data[1+compressionMethodsLen:]
304 m.nextProtoNeg = false
306 m.ocspStapling = false
307 m.ticketSupported = false
308 m.sessionTicket = nil
309 m.signatureAndHashes = nil
312 // ClientHello is optionally followed by extension data
319 extensionsLength := int(data[0])<<8 | int(data[1])
321 if extensionsLength != len(data) {
329 extension := uint16(data[0])<<8 | uint16(data[1])
330 length := int(data[2])<<8 | int(data[3])
332 if len(data) < length {
337 case extensionServerName:
341 numNames := int(data[0])<<8 | int(data[1])
343 for i := 0; i < numNames; i++ {
348 nameLen := int(d[1])<<8 | int(d[2])
350 if len(d) < nameLen {
354 m.serverName = string(d[0:nameLen])
359 case extensionNextProtoNeg:
363 m.nextProtoNeg = true
364 case extensionStatusRequest:
365 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
366 case extensionSupportedCurves:
367 // http://tools.ietf.org/html/rfc4492#section-5.5.1
371 l := int(data[0])<<8 | int(data[1])
372 if l%2 == 1 || length != l+2 {
376 m.supportedCurves = make([]CurveID, numCurves)
378 for i := 0; i < numCurves; i++ {
379 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
382 case extensionSupportedPoints:
383 // http://tools.ietf.org/html/rfc4492#section-5.5.2
391 m.supportedPoints = make([]uint8, l)
392 copy(m.supportedPoints, data[1:])
393 case extensionSessionTicket:
394 // http://tools.ietf.org/html/rfc5077#section-3.2
395 m.ticketSupported = true
396 m.sessionTicket = data[:length]
397 case extensionSignatureAlgorithms:
398 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
399 if length < 2 || length&1 != 0 {
402 l := int(data[0])<<8 | int(data[1])
408 m.signatureAndHashes = make([]signatureAndHash, n)
409 for i := range m.signatureAndHashes {
410 m.signatureAndHashes[i].hash = d[0]
411 m.signatureAndHashes[i].signature = d[1]
414 case extensionRenegotiationInfo + 1:
415 if length != 1 || data[0] != 0 {
418 m.secureRenegotiation = true
426 type serverHelloMsg struct {
432 compressionMethod uint8
437 secureRenegotiation bool
438 duplicateExtension bool
441 func (m *serverHelloMsg) equal(i interface{}) bool {
442 m1, ok := i.(*serverHelloMsg)
447 return bytes.Equal(m.raw, m1.raw) &&
449 bytes.Equal(m.random, m1.random) &&
450 bytes.Equal(m.sessionId, m1.sessionId) &&
451 m.cipherSuite == m1.cipherSuite &&
452 m.compressionMethod == m1.compressionMethod &&
453 m.nextProtoNeg == m1.nextProtoNeg &&
454 eqStrings(m.nextProtos, m1.nextProtos) &&
455 m.ocspStapling == m1.ocspStapling &&
456 m.ticketSupported == m1.ticketSupported &&
457 m.secureRenegotiation == m1.secureRenegotiation
460 func (m *serverHelloMsg) marshal() []byte {
465 length := 38 + len(m.sessionId)
467 extensionsLength := 0
472 for _, v := range m.nextProtos {
473 nextProtoLen += len(v)
475 nextProtoLen += len(m.nextProtos)
476 extensionsLength += nextProtoLen
481 if m.ticketSupported {
484 if m.secureRenegotiation {
485 extensionsLength += 1
488 if m.duplicateExtension {
491 if numExtensions > 0 {
492 extensionsLength += 4 * numExtensions
493 length += 2 + extensionsLength
496 x := make([]byte, 4+length)
497 x[0] = typeServerHello
498 x[1] = uint8(length >> 16)
499 x[2] = uint8(length >> 8)
501 x[4] = uint8(m.vers >> 8)
503 copy(x[6:38], m.random)
504 x[38] = uint8(len(m.sessionId))
505 copy(x[39:39+len(m.sessionId)], m.sessionId)
506 z := x[39+len(m.sessionId):]
507 z[0] = uint8(m.cipherSuite >> 8)
508 z[1] = uint8(m.cipherSuite)
509 z[2] = uint8(m.compressionMethod)
512 if numExtensions > 0 {
513 z[0] = byte(extensionsLength >> 8)
514 z[1] = byte(extensionsLength)
517 if m.duplicateExtension {
518 // Add a duplicate bogus extension at the beginning and end.
524 z[0] = byte(extensionNextProtoNeg >> 8)
525 z[1] = byte(extensionNextProtoNeg & 0xff)
526 z[2] = byte(nextProtoLen >> 8)
527 z[3] = byte(nextProtoLen)
530 for _, v := range m.nextProtos {
536 copy(z[1:], []byte(v[0:l]))
541 z[0] = byte(extensionStatusRequest >> 8)
542 z[1] = byte(extensionStatusRequest)
545 if m.ticketSupported {
546 z[0] = byte(extensionSessionTicket >> 8)
547 z[1] = byte(extensionSessionTicket)
550 if m.secureRenegotiation {
551 z[0] = byte(extensionRenegotiationInfo >> 8)
552 z[1] = byte(extensionRenegotiationInfo & 0xff)
557 if m.duplicateExtension {
558 // Add a duplicate bogus extension at the beginning and end.
569 func (m *serverHelloMsg) unmarshal(data []byte) bool {
574 m.vers = uint16(data[4])<<8 | uint16(data[5])
575 m.random = data[6:38]
576 sessionIdLen := int(data[38])
577 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
580 m.sessionId = data[39 : 39+sessionIdLen]
581 data = data[39+sessionIdLen:]
585 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
586 m.compressionMethod = data[2]
589 m.nextProtoNeg = false
591 m.ocspStapling = false
592 m.ticketSupported = false
595 // ServerHello is optionally followed by extension data
602 extensionsLength := int(data[0])<<8 | int(data[1])
604 if len(data) != extensionsLength {
612 extension := uint16(data[0])<<8 | uint16(data[1])
613 length := int(data[2])<<8 | int(data[3])
615 if len(data) < length {
620 case extensionNextProtoNeg:
621 m.nextProtoNeg = true
626 if l == 0 || l > len(d) {
629 m.nextProtos = append(m.nextProtos, string(d[:l]))
632 case extensionStatusRequest:
636 m.ocspStapling = true
637 case extensionSessionTicket:
641 m.ticketSupported = true
642 case extensionRenegotiationInfo:
643 if length != 1 || data[0] != 0 {
646 m.secureRenegotiation = true
654 type certificateMsg struct {
656 certificates [][]byte
659 func (m *certificateMsg) equal(i interface{}) bool {
660 m1, ok := i.(*certificateMsg)
665 return bytes.Equal(m.raw, m1.raw) &&
666 eqByteSlices(m.certificates, m1.certificates)
669 func (m *certificateMsg) marshal() (x []byte) {
675 for _, slice := range m.certificates {
679 length := 3 + 3*len(m.certificates) + i
680 x = make([]byte, 4+length)
681 x[0] = typeCertificate
682 x[1] = uint8(length >> 16)
683 x[2] = uint8(length >> 8)
686 certificateOctets := length - 3
687 x[4] = uint8(certificateOctets >> 16)
688 x[5] = uint8(certificateOctets >> 8)
689 x[6] = uint8(certificateOctets)
692 for _, slice := range m.certificates {
693 y[0] = uint8(len(slice) >> 16)
694 y[1] = uint8(len(slice) >> 8)
695 y[2] = uint8(len(slice))
704 func (m *certificateMsg) unmarshal(data []byte) bool {
710 certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
711 if uint32(len(data)) != certsLen+7 {
721 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
722 if uint32(len(d)) < 3+certLen {
726 certsLen -= 3 + certLen
730 m.certificates = make([][]byte, numCerts)
732 for i := 0; i < numCerts; i++ {
733 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
734 m.certificates[i] = d[3 : 3+certLen]
741 type serverKeyExchangeMsg struct {
746 func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
747 m1, ok := i.(*serverKeyExchangeMsg)
752 return bytes.Equal(m.raw, m1.raw) &&
753 bytes.Equal(m.key, m1.key)
756 func (m *serverKeyExchangeMsg) marshal() []byte {
761 x := make([]byte, length+4)
762 x[0] = typeServerKeyExchange
763 x[1] = uint8(length >> 16)
764 x[2] = uint8(length >> 8)
772 func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
781 type certificateStatusMsg struct {
787 func (m *certificateStatusMsg) equal(i interface{}) bool {
788 m1, ok := i.(*certificateStatusMsg)
793 return bytes.Equal(m.raw, m1.raw) &&
794 m.statusType == m1.statusType &&
795 bytes.Equal(m.response, m1.response)
798 func (m *certificateStatusMsg) marshal() []byte {
804 if m.statusType == statusTypeOCSP {
805 x = make([]byte, 4+4+len(m.response))
806 x[0] = typeCertificateStatus
807 l := len(m.response) + 4
811 x[4] = statusTypeOCSP
817 copy(x[8:], m.response)
819 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
826 func (m *certificateStatusMsg) unmarshal(data []byte) bool {
831 m.statusType = data[4]
834 if m.statusType == statusTypeOCSP {
838 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
839 if uint32(len(data)) != 4+4+respLen {
842 m.response = data[8:]
847 type serverHelloDoneMsg struct{}
849 func (m *serverHelloDoneMsg) equal(i interface{}) bool {
850 _, ok := i.(*serverHelloDoneMsg)
854 func (m *serverHelloDoneMsg) marshal() []byte {
856 x[0] = typeServerHelloDone
860 func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
861 return len(data) == 4
864 type clientKeyExchangeMsg struct {
869 func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
870 m1, ok := i.(*clientKeyExchangeMsg)
875 return bytes.Equal(m.raw, m1.raw) &&
876 bytes.Equal(m.ciphertext, m1.ciphertext)
879 func (m *clientKeyExchangeMsg) marshal() []byte {
883 length := len(m.ciphertext)
884 x := make([]byte, length+4)
885 x[0] = typeClientKeyExchange
886 x[1] = uint8(length >> 16)
887 x[2] = uint8(length >> 8)
889 copy(x[4:], m.ciphertext)
895 func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
900 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
901 if l != len(data)-4 {
904 m.ciphertext = data[4:]
908 type finishedMsg struct {
913 func (m *finishedMsg) equal(i interface{}) bool {
914 m1, ok := i.(*finishedMsg)
919 return bytes.Equal(m.raw, m1.raw) &&
920 bytes.Equal(m.verifyData, m1.verifyData)
923 func (m *finishedMsg) marshal() (x []byte) {
928 x = make([]byte, 4+len(m.verifyData))
930 x[3] = byte(len(m.verifyData))
931 copy(x[4:], m.verifyData)
936 func (m *finishedMsg) unmarshal(data []byte) bool {
941 m.verifyData = data[4:]
945 type nextProtoMsg struct {
950 func (m *nextProtoMsg) equal(i interface{}) bool {
951 m1, ok := i.(*nextProtoMsg)
956 return bytes.Equal(m.raw, m1.raw) &&
960 func (m *nextProtoMsg) marshal() []byte {
969 padding := 32 - (l+2)%32
970 length := l + padding + 2
971 x := make([]byte, length+4)
972 x[0] = typeNextProtocol
973 x[1] = uint8(length >> 16)
974 x[2] = uint8(length >> 8)
979 copy(y[1:], []byte(m.proto[0:l]))
988 func (m *nextProtoMsg) unmarshal(data []byte) bool {
995 protoLen := int(data[0])
997 if len(data) < protoLen {
1000 m.proto = string(data[0:protoLen])
1001 data = data[protoLen:]
1006 paddingLen := int(data[0])
1008 if len(data) != paddingLen {
1015 type certificateRequestMsg struct {
1017 // hasSignatureAndHash indicates whether this message includes a list
1018 // of signature and hash functions. This change was introduced with TLS
1020 hasSignatureAndHash bool
1022 certificateTypes []byte
1023 signatureAndHashes []signatureAndHash
1024 certificateAuthorities [][]byte
1027 func (m *certificateRequestMsg) equal(i interface{}) bool {
1028 m1, ok := i.(*certificateRequestMsg)
1033 return bytes.Equal(m.raw, m1.raw) &&
1034 bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
1035 eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
1036 eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
1039 func (m *certificateRequestMsg) marshal() (x []byte) {
1044 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
1045 length := 1 + len(m.certificateTypes) + 2
1047 for _, ca := range m.certificateAuthorities {
1048 casLength += 2 + len(ca)
1052 if m.hasSignatureAndHash {
1053 length += 2 + 2*len(m.signatureAndHashes)
1056 x = make([]byte, 4+length)
1057 x[0] = typeCertificateRequest
1058 x[1] = uint8(length >> 16)
1059 x[2] = uint8(length >> 8)
1060 x[3] = uint8(length)
1062 x[4] = uint8(len(m.certificateTypes))
1064 copy(x[5:], m.certificateTypes)
1065 y := x[5+len(m.certificateTypes):]
1067 if m.hasSignatureAndHash {
1068 n := len(m.signatureAndHashes) * 2
1069 y[0] = uint8(n >> 8)
1072 for _, sigAndHash := range m.signatureAndHashes {
1073 y[0] = sigAndHash.hash
1074 y[1] = sigAndHash.signature
1079 y[0] = uint8(casLength >> 8)
1080 y[1] = uint8(casLength)
1082 for _, ca := range m.certificateAuthorities {
1083 y[0] = uint8(len(ca) >> 8)
1084 y[1] = uint8(len(ca))
1094 func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1101 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1102 if uint32(len(data))-4 != length {
1106 numCertTypes := int(data[4])
1108 if numCertTypes == 0 || len(data) <= numCertTypes {
1112 m.certificateTypes = make([]byte, numCertTypes)
1113 if copy(m.certificateTypes, data) != numCertTypes {
1117 data = data[numCertTypes:]
1119 if m.hasSignatureAndHash {
1123 sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
1125 if sigAndHashLen&1 != 0 {
1128 if len(data) < int(sigAndHashLen) {
1131 numSigAndHash := sigAndHashLen / 2
1132 m.signatureAndHashes = make([]signatureAndHash, numSigAndHash)
1133 for i := range m.signatureAndHashes {
1134 m.signatureAndHashes[i].hash = data[0]
1135 m.signatureAndHashes[i].signature = data[1]
1143 casLength := uint16(data[0])<<8 | uint16(data[1])
1145 if len(data) < int(casLength) {
1148 cas := make([]byte, casLength)
1150 data = data[casLength:]
1152 m.certificateAuthorities = nil
1157 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1160 if len(cas) < int(caLen) {
1164 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1174 type certificateVerifyMsg struct {
1176 hasSignatureAndHash bool
1177 signatureAndHash signatureAndHash
1181 func (m *certificateVerifyMsg) equal(i interface{}) bool {
1182 m1, ok := i.(*certificateVerifyMsg)
1187 return bytes.Equal(m.raw, m1.raw) &&
1188 m.hasSignatureAndHash == m1.hasSignatureAndHash &&
1189 m.signatureAndHash.hash == m1.signatureAndHash.hash &&
1190 m.signatureAndHash.signature == m1.signatureAndHash.signature &&
1191 bytes.Equal(m.signature, m1.signature)
1194 func (m *certificateVerifyMsg) marshal() (x []byte) {
1199 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1200 siglength := len(m.signature)
1201 length := 2 + siglength
1202 if m.hasSignatureAndHash {
1205 x = make([]byte, 4+length)
1206 x[0] = typeCertificateVerify
1207 x[1] = uint8(length >> 16)
1208 x[2] = uint8(length >> 8)
1209 x[3] = uint8(length)
1211 if m.hasSignatureAndHash {
1212 y[0] = m.signatureAndHash.hash
1213 y[1] = m.signatureAndHash.signature
1216 y[0] = uint8(siglength >> 8)
1217 y[1] = uint8(siglength)
1218 copy(y[2:], m.signature)
1225 func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1232 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1233 if uint32(len(data))-4 != length {
1238 if m.hasSignatureAndHash {
1239 m.signatureAndHash.hash = data[0]
1240 m.signatureAndHash.signature = data[1]
1247 siglength := int(data[0])<<8 + int(data[1])
1249 if len(data) != siglength {
1258 type newSessionTicketMsg struct {
1263 func (m *newSessionTicketMsg) equal(i interface{}) bool {
1264 m1, ok := i.(*newSessionTicketMsg)
1269 return bytes.Equal(m.raw, m1.raw) &&
1270 bytes.Equal(m.ticket, m1.ticket)
1273 func (m *newSessionTicketMsg) marshal() (x []byte) {
1278 // See http://tools.ietf.org/html/rfc5077#section-3.3
1279 ticketLen := len(m.ticket)
1280 length := 2 + 4 + ticketLen
1281 x = make([]byte, 4+length)
1282 x[0] = typeNewSessionTicket
1283 x[1] = uint8(length >> 16)
1284 x[2] = uint8(length >> 8)
1285 x[3] = uint8(length)
1286 x[8] = uint8(ticketLen >> 8)
1287 x[9] = uint8(ticketLen)
1288 copy(x[10:], m.ticket)
1295 func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1302 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1303 if uint32(len(data))-4 != length {
1307 ticketLen := int(data[8])<<8 + int(data[9])
1308 if len(data)-10 != ticketLen {
1312 m.ticket = data[10:]
1317 type v2ClientHelloMsg struct {
1320 cipherSuites []uint16
1325 func (m *v2ClientHelloMsg) equal(i interface{}) bool {
1326 m1, ok := i.(*v2ClientHelloMsg)
1331 return bytes.Equal(m.raw, m1.raw) &&
1332 m.vers == m1.vers &&
1333 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
1334 bytes.Equal(m.sessionId, m1.sessionId) &&
1335 bytes.Equal(m.challenge, m1.challenge)
1338 func (m *v2ClientHelloMsg) marshal() []byte {
1343 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1345 x := make([]byte, length)
1347 x[1] = uint8(m.vers >> 8)
1348 x[2] = uint8(m.vers)
1349 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1350 x[4] = uint8(len(m.cipherSuites) * 3)
1351 x[5] = uint8(len(m.sessionId) >> 8)
1352 x[6] = uint8(len(m.sessionId))
1353 x[7] = uint8(len(m.challenge) >> 8)
1354 x[8] = uint8(len(m.challenge))
1356 for i, spec := range m.cipherSuites {
1358 y[i*3+1] = uint8(spec >> 8)
1359 y[i*3+2] = uint8(spec)
1361 y = y[len(m.cipherSuites)*3:]
1362 copy(y, m.sessionId)
1363 y = y[len(m.sessionId):]
1364 copy(y, m.challenge)
1371 func eqUint16s(x, y []uint16) bool {
1372 if len(x) != len(y) {
1375 for i, v := range x {
1383 func eqCurveIDs(x, y []CurveID) bool {
1384 if len(x) != len(y) {
1387 for i, v := range x {
1395 func eqStrings(x, y []string) bool {
1396 if len(x) != len(y) {
1399 for i, v := range x {
1407 func eqByteSlices(x, y [][]byte) bool {
1408 if len(x) != len(y) {
1411 for i, v := range x {
1412 if !bytes.Equal(v, y[i]) {
1419 func eqSignatureAndHashes(x, y []signatureAndHash) bool {
1420 if len(x) != len(y) {
1423 for i, v := range x {
1425 if v.hash != v2.hash || v.signature != v2.signature {