fix: check TLS if payload with invalid length (#172)

* fix: check payload

* fix: check max payload len

---------

Co-authored-by: Andrey Semenov <semenov.ao@greendatasoft.ru>
This commit is contained in:
LiquidTheDangerous 2024-08-20 21:31:56 +05:00 committed by xvzc
parent da1d3f4c9e
commit 73e5fec093

View File

@ -2,12 +2,14 @@ package packet
import ( import (
"encoding/binary" "encoding/binary"
"fmt"
"io" "io"
) )
type TLSMessageType byte type TLSMessageType byte
const ( const (
TLSMaxPayloadLen uint16 = 16384 // 16 KB
TLSHeaderLen = 5 TLSHeaderLen = 5
TLSInvalid TLSMessageType = 0x0 TLSInvalid TLSMessageType = 0x0
TLSChangeCipherSpec TLSMessageType = 0x14 TLSChangeCipherSpec TLSMessageType = 0x14
@ -42,7 +44,10 @@ func ReadTLSMessage(r io.Reader) (*TLSMessage, error) {
ProtoVersion: binary.BigEndian.Uint16(rawHeader[1:3]), ProtoVersion: binary.BigEndian.Uint16(rawHeader[1:3]),
PayloadLen: binary.BigEndian.Uint16(rawHeader[3:5]), PayloadLen: binary.BigEndian.Uint16(rawHeader[3:5]),
} }
if header.PayloadLen > TLSMaxPayloadLen {
// Corrupted header? Check integer overflow
return nil, fmt.Errorf("invalid TLS header. Type: %x, ProtoVersion: %x, PayloadLen: %x", header.Type, header.ProtoVersion, header.PayloadLen)
}
raw := make([]byte, header.PayloadLen+TLSHeaderLen) raw := make([]byte, header.PayloadLen+TLSHeaderLen)
copy(raw[0:TLSHeaderLen], rawHeader[:]) copy(raw[0:TLSHeaderLen], rawHeader[:])
_, err = io.ReadFull(r, raw[TLSHeaderLen:]) _, err = io.ReadFull(r, raw[TLSHeaderLen:])
@ -62,5 +67,7 @@ func ReadTLSMessage(r io.Reader) (*TLSMessage, error) {
func (m *TLSMessage) IsClientHello() bool { func (m *TLSMessage) IsClientHello() bool {
// According to RFC 8446 section 4. // According to RFC 8446 section 4.
// first byte (Raw[5]) of handshake message should be 0x1 - means client_hello // first byte (Raw[5]) of handshake message should be 0x1 - means client_hello
return m.Header.Type == TLSHandshake && m.Raw[5] == 0x01 return len(m.Raw) > TLSHeaderLen &&
m.Header.Type == TLSHandshake &&
m.Raw[5] == 0x01
} }