SpoofDPI/proxy/client_hello.go

67 lines
1.5 KiB
Go
Raw Normal View History

2024-08-11 13:54:06 +00:00
package proxy
import (
"encoding/binary"
"io"
)
const headerLen = 5
2024-08-13 21:33:58 +00:00
type TLSMessageType byte
const (
TLSInvalid TLSMessageType = 0x0
TLSChangeCipherSpec TLSMessageType = 0x14
TLSAlert TLSMessageType = 0x15
TLSHandshake TLSMessageType = 0x16
TLSApplicationData TLSMessageType = 0x17
TLSHeartbeat TLSMessageType = 0x18
)
type TlsMessage struct {
Header TlsHeader
2024-08-11 13:54:06 +00:00
Raw []byte //Header + Payload
RawHeader []byte
RawPayload []byte
}
2024-08-13 21:33:58 +00:00
type TlsHeader struct {
Type TLSMessageType
ProtoVersion uint16 // major | minor
2024-08-11 13:54:06 +00:00
PayloadLen uint16
}
2024-08-13 21:33:58 +00:00
func ReadTlsMessage(r io.Reader) (*TlsMessage, error) {
2024-08-11 13:54:06 +00:00
var rawHeader [5]byte
_, err := io.ReadFull(r, rawHeader[:])
if err != nil {
return nil, err
}
2024-08-13 21:33:58 +00:00
header := TlsHeader{
Type: TLSMessageType(rawHeader[0]),
2024-08-11 13:54:06 +00:00
ProtoVersion: binary.BigEndian.Uint16(rawHeader[1:3]),
PayloadLen: binary.BigEndian.Uint16(rawHeader[3:5]),
}
raw := make([]byte, header.PayloadLen+headerLen)
copy(raw[0:headerLen], rawHeader[:])
_, err = io.ReadFull(r, raw[headerLen:])
if err != nil {
return nil, err
}
2024-08-13 21:33:58 +00:00
hello := &TlsMessage{
Header: header,
Raw: raw,
RawHeader: raw[:headerLen],
RawPayload: raw[headerLen:],
2024-08-11 13:54:06 +00:00
}
return hello, nil
}
2024-08-13 21:33:58 +00:00
func IsClientHello(message *TlsMessage) bool {
// According to RFC 8446 section 4.
// first byte (Raw[5]) of handshake message should be 0x1 - means client_hello
return message.Header.Type == TLSHandshake &&
message.Raw[5] == 0x1
}