runner: Parse SH/HRR/EE with byteReader.
Bug: 212 Change-Id: I454db0bfd59bac3729338c6f8d9e51efde0735eb Reviewed-on: https://boringssl-review.googlesource.com/23446 Reviewed-by: Steven Valdez <svaldez@google.com> Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
parent
7ce2378750
commit
bd911af514
@ -537,11 +537,7 @@ func (m *clientHelloMsg) marshal() []byte {
|
|||||||
|
|
||||||
srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
|
srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
|
||||||
for _, p := range m.srtpProtectionProfiles {
|
for _, p := range m.srtpProtectionProfiles {
|
||||||
// An SRTPProtectionProfile is defined as uint8[2],
|
srtpProtectionProfiles.addU16(p)
|
||||||
// not uint16. For some reason, we're storing it
|
|
||||||
// as a uint16.
|
|
||||||
srtpProtectionProfiles.addU8(byte(p >> 8))
|
|
||||||
srtpProtectionProfiles.addU8(byte(p))
|
|
||||||
}
|
}
|
||||||
srtpMki := useSrtpExt.addU8LengthPrefixed()
|
srtpMki := useSrtpExt.addU8LengthPrefixed()
|
||||||
srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
|
srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
|
||||||
@ -967,76 +963,56 @@ func (m *serverHelloMsg) marshal() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *serverHelloMsg) unmarshal(data []byte) bool {
|
func (m *serverHelloMsg) unmarshal(data []byte) bool {
|
||||||
if len(data) < 42 {
|
m.raw = data
|
||||||
|
reader := byteReader(data[4:])
|
||||||
|
if !reader.readU16(&m.vers) ||
|
||||||
|
!reader.readBytes(&m.random, 32) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.raw = data
|
|
||||||
m.vers = uint16(data[4])<<8 | uint16(data[5])
|
|
||||||
vers, ok := wireToVersion(m.vers, m.isDTLS)
|
vers, ok := wireToVersion(m.vers, m.isDTLS)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.random = data[6:38]
|
|
||||||
data = data[38:]
|
|
||||||
if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
|
if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
|
||||||
sessionIdLen := int(data[0])
|
if !reader.readU8LengthPrefixedBytes(&m.sessionId) {
|
||||||
if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.sessionId = data[1 : 1+sessionIdLen]
|
|
||||||
data = data[1+sessionIdLen:]
|
|
||||||
}
|
}
|
||||||
if len(data) < 2 {
|
if !reader.readU16(&m.cipherSuite) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
|
|
||||||
data = data[2:]
|
|
||||||
if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
|
if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
|
||||||
if len(data) < 1 {
|
if !reader.readU8(&m.compressionMethod) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.compressionMethod = data[0]
|
|
||||||
data = data[1:]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) == 0 && m.vers < VersionTLS13 {
|
if len(reader) == 0 && m.vers < VersionTLS13 {
|
||||||
// Extension data is optional before TLS 1.3.
|
// Extension data is optional before TLS 1.3.
|
||||||
m.extensions = serverExtensions{}
|
m.extensions = serverExtensions{}
|
||||||
m.omitExtensions = true
|
m.omitExtensions = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if len(data) < 2 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
extensionsLength := int(data[0])<<8 | int(data[1])
|
var extensions byteReader
|
||||||
data = data[2:]
|
if !reader.readU16LengthPrefixed(&extensions) || len(reader) != 0 {
|
||||||
if len(data) != extensionsLength {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse out the version from supported_versions if available.
|
// Parse out the version from supported_versions if available.
|
||||||
if m.vers == VersionTLS12 {
|
if m.vers == VersionTLS12 {
|
||||||
vdata := data
|
extensionsCopy := extensions
|
||||||
for len(vdata) != 0 {
|
for len(extensionsCopy) > 0 {
|
||||||
if len(vdata) < 4 {
|
var extension uint16
|
||||||
|
var body byteReader
|
||||||
|
if !extensionsCopy.readU16(&extension) ||
|
||||||
|
!extensionsCopy.readU16LengthPrefixed(&body) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
extension := uint16(vdata[0])<<8 | uint16(vdata[1])
|
|
||||||
length := int(vdata[2])<<8 | int(vdata[3])
|
|
||||||
vdata = vdata[4:]
|
|
||||||
|
|
||||||
if len(vdata) < length {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
d := vdata[:length]
|
|
||||||
vdata = vdata[length:]
|
|
||||||
|
|
||||||
if extension == extensionSupportedVersions {
|
if extension == extensionSupportedVersions {
|
||||||
if len(d) < 2 {
|
if !body.readU16(&m.vers) || len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.vers = uint16(d[0])<<8 | uint16(d[1])
|
|
||||||
vers, ok = wireToVersion(m.vers, m.isDTLS)
|
vers, ok = wireToVersion(m.vers, m.isDTLS)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
@ -1046,38 +1022,27 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if vers >= VersionTLS13 {
|
if vers >= VersionTLS13 {
|
||||||
for len(data) != 0 {
|
for len(extensions) > 0 {
|
||||||
if len(data) < 4 {
|
var extension uint16
|
||||||
|
var body byteReader
|
||||||
|
if !extensions.readU16(&extension) ||
|
||||||
|
!extensions.readU16LengthPrefixed(&body) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
extension := uint16(data[0])<<8 | uint16(data[1])
|
|
||||||
length := int(data[2])<<8 | int(data[3])
|
|
||||||
data = data[4:]
|
|
||||||
|
|
||||||
if len(data) < length {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
d := data[:length]
|
|
||||||
data = data[length:]
|
|
||||||
|
|
||||||
switch extension {
|
switch extension {
|
||||||
case extensionKeyShare:
|
case extensionKeyShare:
|
||||||
m.hasKeyShare = true
|
m.hasKeyShare = true
|
||||||
if len(d) < 4 {
|
var group uint16
|
||||||
|
if !body.readU16(&group) ||
|
||||||
|
!body.readU16LengthPrefixedBytes(&m.keyShare.keyExchange) ||
|
||||||
|
len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
|
m.keyShare.group = CurveID(group)
|
||||||
keyExchLen := int(d[2])<<8 | int(d[3])
|
|
||||||
if keyExchLen != len(d)-4 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
m.keyShare.keyExchange = make([]byte, keyExchLen)
|
|
||||||
copy(m.keyShare.keyExchange, d[4:])
|
|
||||||
case extensionPreSharedKey:
|
case extensionPreSharedKey:
|
||||||
if len(d) != 2 {
|
if !body.readU16(&m.pskIdentity) || len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
|
|
||||||
m.hasPSKIdentity = true
|
m.hasPSKIdentity = true
|
||||||
case extensionSupportedVersions:
|
case extensionSupportedVersions:
|
||||||
if !isResumptionExperiment(m.vers) {
|
if !isResumptionExperiment(m.vers) {
|
||||||
@ -1089,7 +1054,7 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if !m.extensions.unmarshal(data, vers) {
|
} else if !m.extensions.unmarshal(extensions, vers) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1121,23 +1086,12 @@ func (m *encryptedExtensionsMsg) marshal() []byte {
|
|||||||
|
|
||||||
func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
|
func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
|
||||||
m.raw = data
|
m.raw = data
|
||||||
if len(data) < 6 {
|
reader := byteReader(data[4:])
|
||||||
|
var extensions byteReader
|
||||||
|
if !reader.readU16LengthPrefixed(&extensions) || len(reader) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if data[0] != typeEncryptedExtensions {
|
return m.extensions.unmarshal(extensions, VersionTLS13)
|
||||||
return false
|
|
||||||
}
|
|
||||||
msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
|
|
||||||
data = data[4:]
|
|
||||||
if len(data) != msgLen {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
extLen := int(data[0])<<8 | int(data[1])
|
|
||||||
data = data[2:]
|
|
||||||
if extLen != len(data) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return m.extensions.unmarshal(data, VersionTLS13)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type serverExtensions struct {
|
type serverExtensions struct {
|
||||||
@ -1223,8 +1177,7 @@ func (m *serverExtensions) marshal(extensions *byteBuilder) {
|
|||||||
extension := extensions.addU16LengthPrefixed()
|
extension := extensions.addU16LengthPrefixed()
|
||||||
|
|
||||||
srtpProtectionProfiles := extension.addU16LengthPrefixed()
|
srtpProtectionProfiles := extension.addU16LengthPrefixed()
|
||||||
srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
|
srtpProtectionProfiles.addU16(m.srtpProtectionProfile)
|
||||||
srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
|
|
||||||
srtpMki := extension.addU8LengthPrefixed()
|
srtpMki := extension.addU8LengthPrefixed()
|
||||||
srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
|
srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
|
||||||
}
|
}
|
||||||
@ -1288,96 +1241,77 @@ func (m *serverExtensions) marshal(extensions *byteBuilder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
|
func (m *serverExtensions) unmarshal(data byteReader, version uint16) bool {
|
||||||
// Reset all fields.
|
// Reset all fields.
|
||||||
*m = serverExtensions{}
|
*m = serverExtensions{}
|
||||||
|
|
||||||
for len(data) != 0 {
|
for len(data) > 0 {
|
||||||
if len(data) < 4 {
|
var extension uint16
|
||||||
|
var body byteReader
|
||||||
|
if !data.readU16(&extension) ||
|
||||||
|
!data.readU16LengthPrefixed(&body) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
extension := uint16(data[0])<<8 | uint16(data[1])
|
|
||||||
length := int(data[2])<<8 | int(data[3])
|
|
||||||
data = data[4:]
|
|
||||||
if len(data) < length {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch extension {
|
switch extension {
|
||||||
case extensionNextProtoNeg:
|
case extensionNextProtoNeg:
|
||||||
m.nextProtoNeg = true
|
m.nextProtoNeg = true
|
||||||
d := data[:length]
|
for len(body) > 0 {
|
||||||
for len(d) > 0 {
|
var protocol []byte
|
||||||
l := int(d[0])
|
if !body.readU8LengthPrefixedBytes(&protocol) {
|
||||||
d = d[1:]
|
|
||||||
if l == 0 || l > len(d) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.nextProtos = append(m.nextProtos, string(d[:l]))
|
m.nextProtos = append(m.nextProtos, string(protocol))
|
||||||
d = d[l:]
|
|
||||||
}
|
}
|
||||||
case extensionStatusRequest:
|
case extensionStatusRequest:
|
||||||
if length > 0 {
|
if len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.ocspStapling = true
|
m.ocspStapling = true
|
||||||
case extensionSessionTicket:
|
case extensionSessionTicket:
|
||||||
if length > 0 {
|
if len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.ticketSupported = true
|
m.ticketSupported = true
|
||||||
case extensionRenegotiationInfo:
|
case extensionRenegotiationInfo:
|
||||||
if length < 1 || length != int(data[0])+1 {
|
if !body.readU8LengthPrefixedBytes(&m.secureRenegotiation) || len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.secureRenegotiation = data[1:length]
|
|
||||||
case extensionALPN:
|
case extensionALPN:
|
||||||
d := data[:length]
|
var protocols, protocol byteReader
|
||||||
if len(d) < 3 {
|
if !body.readU16LengthPrefixed(&protocols) ||
|
||||||
|
len(body) != 0 ||
|
||||||
|
!protocols.readU8LengthPrefixed(&protocol) ||
|
||||||
|
len(protocols) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
l := int(d[0])<<8 | int(d[1])
|
m.alpnProtocol = string(protocol)
|
||||||
if l != len(d)-2 {
|
m.alpnProtocolEmpty = len(protocol) == 0
|
||||||
return false
|
|
||||||
}
|
|
||||||
d = d[2:]
|
|
||||||
l = int(d[0])
|
|
||||||
if l != len(d)-1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
d = d[1:]
|
|
||||||
m.alpnProtocol = string(d)
|
|
||||||
m.alpnProtocolEmpty = len(d) == 0
|
|
||||||
case extensionChannelID:
|
case extensionChannelID:
|
||||||
if length > 0 {
|
if len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.channelIDRequested = true
|
m.channelIDRequested = true
|
||||||
case extensionExtendedMasterSecret:
|
case extensionExtendedMasterSecret:
|
||||||
if length != 0 {
|
if len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.extendedMasterSecret = true
|
m.extendedMasterSecret = true
|
||||||
case extensionUseSRTP:
|
case extensionUseSRTP:
|
||||||
if length < 2+2+1 {
|
var profiles, mki byteReader
|
||||||
|
if !body.readU16LengthPrefixed(&profiles) ||
|
||||||
|
!profiles.readU16(&m.srtpProtectionProfile) ||
|
||||||
|
len(profiles) != 0 ||
|
||||||
|
!body.readU8LengthPrefixed(&mki) ||
|
||||||
|
len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if data[0] != 0 || data[1] != 2 {
|
m.srtpMasterKeyIdentifier = string(mki)
|
||||||
return false
|
|
||||||
}
|
|
||||||
m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
|
|
||||||
d := data[4:length]
|
|
||||||
l := int(d[0])
|
|
||||||
if l != len(d)-1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
m.srtpMasterKeyIdentifier = string(d[1:])
|
|
||||||
case extensionSignedCertificateTimestamp:
|
case extensionSignedCertificateTimestamp:
|
||||||
m.sctList = data[:length]
|
m.sctList = []byte(body)
|
||||||
case extensionCustom:
|
case extensionCustom:
|
||||||
m.customExtension = string(data[:length])
|
m.customExtension = string(body)
|
||||||
case extensionServerName:
|
case extensionServerName:
|
||||||
if length != 0 {
|
if len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.serverNameAck = true
|
m.serverNameAck = true
|
||||||
@ -1387,21 +1321,16 @@ func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// http://tools.ietf.org/html/rfc4492#section-5.5.2
|
// http://tools.ietf.org/html/rfc4492#section-5.5.2
|
||||||
if length < 1 {
|
if !body.readU8LengthPrefixedBytes(&m.supportedPoints) || len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
l := int(data[0])
|
|
||||||
if length != l+1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
m.supportedPoints = data[1 : 1+l]
|
|
||||||
case extensionSupportedCurves:
|
case extensionSupportedCurves:
|
||||||
// The server can only send supported_curves in TLS 1.3.
|
// The server can only send supported_curves in TLS 1.3.
|
||||||
if version < VersionTLS13 {
|
if version < VersionTLS13 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case extensionEarlyData:
|
case extensionEarlyData:
|
||||||
if version < VersionTLS13 || length != 0 {
|
if version < VersionTLS13 || len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.hasEarlyData = true
|
m.hasEarlyData = true
|
||||||
@ -1409,7 +1338,6 @@ func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
|
|||||||
// Unknown extensions are illegal from the server.
|
// Unknown extensions are illegal from the server.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
data = data[length:]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -1490,73 +1418,56 @@ func (m *helloRetryRequestMsg) marshal() []byte {
|
|||||||
|
|
||||||
func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
|
func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
|
||||||
m.raw = data
|
m.raw = data
|
||||||
if len(data) < 8 {
|
reader := byteReader(data[4:])
|
||||||
|
if !reader.readU16(&m.vers) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.vers = uint16(data[4])<<8 | uint16(data[5])
|
|
||||||
data = data[6:]
|
|
||||||
if m.isServerHello {
|
if m.isServerHello {
|
||||||
if len(data) < 33 {
|
var random []byte
|
||||||
|
var compressionMethod byte
|
||||||
|
if !reader.readBytes(&random, 32) ||
|
||||||
|
!reader.readU8LengthPrefixedBytes(&m.sessionId) ||
|
||||||
|
!reader.readU16(&m.cipherSuite) ||
|
||||||
|
!reader.readU8(&compressionMethod) ||
|
||||||
|
compressionMethod != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
data = data[32:] // Random
|
} else if isDraft21(m.vers) && !reader.readU16(&m.cipherSuite) {
|
||||||
sessionIdLen := int(data[0])
|
|
||||||
if sessionIdLen > 32 || len(data) < 1+sessionIdLen+3 {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.sessionId = data[1 : 1+sessionIdLen]
|
var extensions byteReader
|
||||||
data = data[1+sessionIdLen:]
|
if !reader.readU16LengthPrefixed(&extensions) || len(reader) != 0 {
|
||||||
m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
|
|
||||||
data = data[2:]
|
|
||||||
data = data[1:] // Compression Method
|
|
||||||
} else {
|
|
||||||
if isDraft21(m.vers) {
|
|
||||||
m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
|
|
||||||
data = data[2:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extLen := int(data[0])<<8 | int(data[1])
|
|
||||||
data = data[2:]
|
|
||||||
if len(data) != extLen || len(data) == 0 {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for len(data) > 0 {
|
for len(extensions) > 0 {
|
||||||
if len(data) < 4 {
|
var extension uint16
|
||||||
|
var body byteReader
|
||||||
|
if !extensions.readU16(&extension) ||
|
||||||
|
!extensions.readU16LengthPrefixed(&body) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
extension := uint16(data[0])<<8 | uint16(data[1])
|
|
||||||
length := int(data[2])<<8 | int(data[3])
|
|
||||||
data = data[4:]
|
|
||||||
if len(data) < length {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch extension {
|
switch extension {
|
||||||
case extensionSupportedVersions:
|
case extensionSupportedVersions:
|
||||||
if length != 2 || !m.isServerHello {
|
if !m.isServerHello ||
|
||||||
|
!body.readU16(&m.vers) ||
|
||||||
|
len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.vers = uint16(data[0])<<8 | uint16(data[1])
|
|
||||||
case extensionKeyShare:
|
case extensionKeyShare:
|
||||||
if length != 2 {
|
var v uint16
|
||||||
|
if !body.readU16(&v) || len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
m.hasSelectedGroup = true
|
m.hasSelectedGroup = true
|
||||||
m.selectedGroup = CurveID(data[0])<<8 | CurveID(data[1])
|
m.selectedGroup = CurveID(v)
|
||||||
case extensionCookie:
|
case extensionCookie:
|
||||||
if length < 2 {
|
if !body.readU16LengthPrefixedBytes(&m.cookie) || len(body) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
cookieLen := int(data[0])<<8 | int(data[1])
|
|
||||||
if 2+cookieLen != length {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
m.cookie = data[2 : 2+cookieLen]
|
|
||||||
default:
|
default:
|
||||||
// Unknown extensions are illegal from the server.
|
// Unknown extensions are illegal from the server.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
data = data[length:]
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user