2022-01-08 06:35:32 +00:00
|
|
|
package packet
|
2022-01-07 18:01:54 +00:00
|
|
|
|
2024-08-14 08:01:14 +00:00
|
|
|
import (
|
|
|
|
"encoding/binary"
|
2024-08-20 16:31:56 +00:00
|
|
|
"fmt"
|
2024-08-14 08:01:14 +00:00
|
|
|
"io"
|
|
|
|
)
|
|
|
|
|
|
|
|
type TLSMessageType byte
|
|
|
|
|
|
|
|
const (
|
2024-08-20 16:31:56 +00:00
|
|
|
TLSMaxPayloadLen uint16 = 16384 // 16 KB
|
2024-08-14 08:01:14 +00:00
|
|
|
TLSHeaderLen = 5
|
|
|
|
TLSInvalid TLSMessageType = 0x0
|
|
|
|
TLSChangeCipherSpec TLSMessageType = 0x14
|
|
|
|
TLSAlert TLSMessageType = 0x15
|
|
|
|
TLSHandshake TLSMessageType = 0x16
|
|
|
|
TLSApplicationData TLSMessageType = 0x17
|
|
|
|
TLSHeartbeat TLSMessageType = 0x18
|
|
|
|
)
|
|
|
|
|
|
|
|
type TLSMessage struct {
|
|
|
|
Header TLSHeader
|
|
|
|
Raw []byte //Header + Payload
|
|
|
|
RawHeader []byte
|
|
|
|
RawPayload []byte
|
2022-01-07 18:01:54 +00:00
|
|
|
}
|
|
|
|
|
2024-08-14 08:01:14 +00:00
|
|
|
type TLSHeader struct {
|
|
|
|
Type TLSMessageType
|
|
|
|
ProtoVersion uint16 // major | minor
|
|
|
|
PayloadLen uint16
|
|
|
|
}
|
|
|
|
|
|
|
|
func ReadTLSMessage(r io.Reader) (*TLSMessage, error) {
|
|
|
|
var rawHeader [TLSHeaderLen]byte
|
|
|
|
_, err := io.ReadFull(r, rawHeader[:])
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
header := TLSHeader{
|
|
|
|
Type: TLSMessageType(rawHeader[0]),
|
|
|
|
ProtoVersion: binary.BigEndian.Uint16(rawHeader[1:3]),
|
|
|
|
PayloadLen: binary.BigEndian.Uint16(rawHeader[3:5]),
|
|
|
|
}
|
2024-08-20 16:31:56 +00:00
|
|
|
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)
|
|
|
|
}
|
2024-08-14 08:01:14 +00:00
|
|
|
raw := make([]byte, header.PayloadLen+TLSHeaderLen)
|
|
|
|
copy(raw[0:TLSHeaderLen], rawHeader[:])
|
|
|
|
_, err = io.ReadFull(r, raw[TLSHeaderLen:])
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
hello := &TLSMessage{
|
|
|
|
Header: header,
|
|
|
|
Raw: raw,
|
|
|
|
RawHeader: raw[:TLSHeaderLen],
|
|
|
|
RawPayload: raw[TLSHeaderLen:],
|
2022-01-07 18:01:54 +00:00
|
|
|
}
|
2024-08-14 08:01:14 +00:00
|
|
|
return hello, nil
|
2022-01-07 18:01:54 +00:00
|
|
|
}
|
|
|
|
|
2024-08-14 08:01:14 +00:00
|
|
|
func (m *TLSMessage) IsClientHello() bool {
|
|
|
|
// According to RFC 8446 section 4.
|
|
|
|
// first byte (Raw[5]) of handshake message should be 0x1 - means client_hello
|
2024-08-20 16:31:56 +00:00
|
|
|
return len(m.Raw) > TLSHeaderLen &&
|
|
|
|
m.Header.Type == TLSHandshake &&
|
|
|
|
m.Raw[5] == 0x01
|
2022-01-11 17:15:45 +00:00
|
|
|
}
|