move gotd fork into repo. (#111)

- update to latest telegram layer
- remove some references to fields in tg.Entities that don't exist in
the schema
- originally added here:
https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e
  - referenced here
-
https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3
-
https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
This commit is contained in:
Adam Van Ymeren
2025-06-27 20:03:37 -07:00
committed by GitHub
parent 0952df0244
commit 7a04f298d2
19264 changed files with 1539697 additions and 84 deletions
+124
View File
@@ -0,0 +1,124 @@
package faketls
import (
"crypto/hmac"
"crypto/sha256"
"encoding/binary"
"io"
"github.com/go-faster/errors"
"go.mau.fi/mautrix-telegram/pkg/gotd/bin"
"go.mau.fi/mautrix-telegram/pkg/gotd/clock"
)
const clientHelloLength = 517
func createClientHello(b *bin.Buffer, sessionID [32]byte, domain string, key [32]byte) (randomOffset int) {
S := func(s string) {
b.Buf = append(b.Buf, s...)
}
Z := func(n int) {
randomOffset = len(b.Buf)
b.Expand(n)
}
G := func(_ int) {
b.Expand(0)
}
R := func() {
b.Buf = append(b.Buf, sessionID[:]...)
}
D := func() {
b.Buf = append(b.Buf, domain...)
}
K := func() {
b.Buf = append(b.Buf, key[:]...)
}
var stack []int
Open := func() {
stack = append(stack, b.Len())
b.Expand(2)
}
Close := func() {
lastIdx := len(stack) - 1
s := stack[lastIdx]
stack = stack[:lastIdx]
length := b.Len() - (s + 2)
binary.BigEndian.PutUint16(b.Buf[s:], uint16(length))
}
S("\x16\x03\x01\x02\x00\x01\x00\x01\xfc\x03\x03")
Z(32)
S("\x20")
R()
S("\x00\x20")
G(0)
S("\x13\x01\x13\x02\x13\x03\xc0\x2b\xc0\x2f\xc0\x2c\xc0\x30\xcc\xa9" +
"\xcc\xa8\xc0\x13\xc0\x14\x00\x9c\x00\x9d\x00\x2f\x00\x35\x01\x00" +
"\x01\x93")
G(2)
S("\x00\x00\x00\x00")
Open()
Open()
S("\x00")
Open()
D()
Close()
Close()
Close()
S("\x00\x17\x00\x00\xff\x01\x00\x01\x00\x00\x0a\x00\x0a\x00\x08")
G(4)
S("\x00\x1d\x00\x17\x00\x18\x00\x0b\x00\x02\x01\x00\x00\x23\x00\x00" +
"\x00\x10\x00\x0e\x00\x0c\x02\x68\x32\x08\x68\x74\x74\x70\x2f\x31" +
"\x2e\x31\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\x0d\x00\x12\x00" +
"\x10\x04\x03\x08\x04\x04\x01\x05\x03\x08\x05\x05\x01\x08\x06\x06" +
"\x01\x00\x12\x00\x00\x00\x33\x00\x2b\x00\x29")
G(4)
S("\x00\x01\x00\x00\x1d\x00\x20")
K()
S("\x00\x2d\x00\x02\x01\x01\x00\x2b\x00\x0b\x0a")
G(6)
S("\x03\x04\x03\x03\x03\x02\x03\x01\x00\x1b\x00\x03\x02\x00\x02")
G(3)
S("\x00\x01\x00\x00\x15")
if pad := clientHelloLength - b.Len(); pad > 0 {
b.Expand(pad)
}
return randomOffset
}
// writeClientHello writes faketls ClientHello.
//
// See https://tools.ietf.org/html/rfc5246#section-7.4.1.1.
func writeClientHello(
w io.Writer,
now clock.Clock,
sessionID [32]byte,
domain string,
secret []byte,
) (r [32]byte, err error) {
b := &bin.Buffer{
Buf: make([]byte, 0, 576),
}
randomOffset := createClientHello(b, sessionID, domain, [32]byte{})
// https://github.com/tdlib/td/blob/27d3fdd09d90f6b77ecbcce50b1e86dc4b3dd366/td/mtproto/TlsInit.cpp#L380-L384
mac := hmac.New(sha256.New, secret)
if _, err := mac.Write(b.Buf); err != nil {
return [32]byte{}, errors.Wrap(err, "hmac write")
}
s := mac.Sum(nil)
copy(b.Buf[randomOffset:randomOffset+32], s)
// Overwrite last 4 bytes using final := original ^ timestamp.
old := binary.LittleEndian.Uint32(b.Buf[randomOffset+28 : randomOffset+32])
old ^= uint32(now.Now().Unix())
binary.LittleEndian.PutUint32(b.Buf[randomOffset+28:randomOffset+32], old)
// Copy ClientRandom for later use.
copy(r[:], b.Buf[randomOffset:randomOffset+32])
_, err = w.Write(b.Buf)
return r, err
}
+2
View File
@@ -0,0 +1,2 @@
// Package faketls contains faketls implementation.
package faketls
+112
View File
@@ -0,0 +1,112 @@
package faketls
import (
"bytes"
"io"
"sync"
"github.com/go-faster/errors"
"go.mau.fi/mautrix-telegram/pkg/gotd/clock"
"go.mau.fi/mautrix-telegram/pkg/gotd/mtproxy"
)
// FakeTLS implements FakeTLS obfuscation protocol.
type FakeTLS struct {
rand io.Reader
clock clock.Clock
conn io.ReadWriter
version [2]byte
firstPacket bool
readBuf bytes.Buffer
readBufMux sync.Mutex
}
// NewFakeTLS creates new FakeTLS.
func NewFakeTLS(r io.Reader, conn io.ReadWriter) *FakeTLS {
return &FakeTLS{
rand: r,
clock: clock.System,
conn: conn,
version: Version12Bytes,
readBuf: bytes.Buffer{},
}
}
// Handshake performs FakeTLS handshake.
func (o *FakeTLS) Handshake(protocol [4]byte, dc int, s mtproxy.Secret) error {
o.readBufMux.Lock()
o.readBuf.Reset()
o.readBufMux.Unlock()
var sessionID [32]byte
if _, err := o.rand.Read(sessionID[:]); err != nil {
return errors.Wrap(err, "generate sessionID")
}
clientDigest, err := writeClientHello(o.conn, o.clock, sessionID, s.CloakHost, s.Secret)
if err != nil {
return errors.Wrap(err, "send ClientHello")
}
if err := readServerHello(o.conn, clientDigest, s.Secret); err != nil {
return errors.Wrap(err, "receive ServerHello")
}
return nil
}
// Write implements io.Writer.
func (o *FakeTLS) Write(b []byte) (n int, err error) {
// Some proxies require sending first packet with RecordTypeChangeCipherSpec.
//
// See https://github.com/tdlib/td/blob/master/td/mtproto/TcpTransport.cpp#L266.
if !o.firstPacket {
_, err = writeRecord(o.conn, record{
Type: RecordTypeChangeCipherSpec,
Version: o.version,
Data: []byte("\x01"),
})
if err != nil {
return 0, errors.Wrap(err, "write first TLS packet")
}
o.firstPacket = true
}
n, err = writeRecord(o.conn, record{
Type: RecordTypeApplication,
Version: o.version,
Data: b,
})
if err != nil {
return 0, errors.Wrap(err, "write TLS record")
}
return
}
// Read implements io.Reader.
func (o *FakeTLS) Read(b []byte) (n int, err error) {
o.readBufMux.Lock()
defer o.readBufMux.Unlock()
if o.readBuf.Len() > 0 {
return o.readBuf.Read(b)
}
rec, err := readRecord(o.conn)
if err != nil {
return 0, errors.Wrap(err, "read TLS record")
}
switch rec.Type {
case RecordTypeChangeCipherSpec:
case RecordTypeApplication:
case RecordTypeHandshake:
return 0, errors.New("unexpected record type handshake")
default:
return 0, errors.Errorf("unsupported record type %v", rec.Type)
}
o.readBuf.Write(rec.Data)
return o.readBuf.Read(b)
}
+59
View File
@@ -0,0 +1,59 @@
package faketls
import (
"bytes"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/gotd/neo"
)
func TestTLS(t *testing.T) {
a := require.New(t)
secret := [32]byte{}
sessionID := [32]byte{}
c := neo.NewTime(time.Date(2010, 10, 10, 1, 1, 1, 0, time.UTC))
b := bytes.NewBuffer(nil)
_, err := writeClientHello(b, c, sessionID, "google.com", secret[:])
a.NoError(err)
testVector := []byte{
0x16, 0x03, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0xfc, 0x03, 0x03, 0xf9, 0x75, 0x5f, 0xdd, 0xb9,
0xe3, 0x46, 0x57, 0x5a, 0x26, 0x71, 0xfa, 0x29, 0x7f, 0xab, 0xf0, 0xa1, 0xf3, 0x69, 0x4f, 0x72,
0xe0, 0xc3, 0x8f, 0x62, 0x77, 0x5c, 0x8f, 0x5a, 0xf8, 0xa2, 0xa9, 0x20, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x13, 0x01,
0x13, 0x02, 0x13, 0x03, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xcc, 0xa9, 0xcc, 0xa8,
0xc0, 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00, 0x01, 0x93,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0x00, 0x0a, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a,
0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,
0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74,
0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0d, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05,
0x01, 0x08, 0x06, 0x06, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2b, 0x00, 0x29, 0x00,
0x01, 0x00, 0x00, 0x1d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x2b, 0x00, 0x0b,
0x0a, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x03, 0x01, 0x00, 0x1b, 0x00, 0x03, 0x02, 0x00, 0x02,
0x00, 0x01, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
}
a.Equal(testVector, b.Bytes())
}
+76
View File
@@ -0,0 +1,76 @@
package faketls
import (
"bytes"
"encoding/binary"
"io"
"github.com/go-faster/errors"
)
const maxTLSRecordDataLength = 16384 + 24
type record struct {
Type RecordType
Version [2]byte
Data []byte
}
func readRecord(r io.Reader) (record, error) {
rec := record{}
buf := make([]byte, 5)
if _, err := io.ReadFull(r, buf); err != nil {
return record{}, err
}
rec.Type = RecordType(buf[0])
versionRaw := buf[1:3]
switch {
case bytes.Equal(versionRaw, Version13Bytes[:]):
rec.Version = Version13Bytes
case bytes.Equal(versionRaw, Version12Bytes[:]):
rec.Version = Version12Bytes
case bytes.Equal(versionRaw, Version11Bytes[:]):
rec.Version = Version11Bytes
case bytes.Equal(versionRaw, Version10Bytes[:]):
rec.Version = Version10Bytes
default:
return record{}, errors.Errorf("unknown protocol version %v", versionRaw)
}
length := binary.BigEndian.Uint16(buf[3:])
if length > maxTLSRecordDataLength {
return record{}, errors.New("record length is too big")
}
rec.Data = make([]byte, length)
if _, err := io.ReadFull(r, rec.Data); err != nil {
return record{}, err
}
return rec, nil
}
func writeRecord(w io.Writer, r record) (int, error) {
buf := [...]byte{
byte(r.Type),
r.Version[0], r.Version[1],
}
if _, err := w.Write(buf[:]); err != nil {
return 0, errors.Wrap(err, "type and version")
}
binary.BigEndian.PutUint16(buf[:2], uint16(len(r.Data)))
if _, err := w.Write(buf[:2]); err != nil {
return 0, errors.Wrap(err, "data length")
}
n, err := w.Write(r.Data)
if err != nil {
return 0, errors.Wrap(err, "data")
}
return n, nil
}
+24
View File
@@ -0,0 +1,24 @@
package faketls
import (
"bytes"
"testing"
"github.com/stretchr/testify/require"
)
func TestRecord(t *testing.T) {
a := require.New(t)
r := record{
Type: RecordTypeApplication,
Version: Version10Bytes,
Data: []byte(`abcd`),
}
buf := bytes.NewBuffer(nil)
_, err := writeRecord(buf, r)
a.NoError(err)
r2, err := readRecord(buf)
a.NoError(err)
a.Equal(r, r2)
}
+65
View File
@@ -0,0 +1,65 @@
package faketls
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"io"
"github.com/go-faster/errors"
)
// readServerHello reads faketls ServerHello.
func readServerHello(r io.Reader, clientRandom [32]byte, secret []byte) error {
packetBuf := bytes.NewBuffer(nil)
r = io.TeeReader(r, packetBuf)
handshake, err := readRecord(r)
if err != nil {
return errors.Wrap(err, "handshake record")
}
if handshake.Type != RecordTypeHandshake {
return errors.Wrap(err, "unexpected record type")
}
changeCipher, err := readRecord(r)
if err != nil {
return errors.Wrap(err, "change cipher record")
}
if changeCipher.Type != RecordTypeChangeCipherSpec {
return errors.Wrap(err, "unexpected record type")
}
cert, err := readRecord(r)
if err != nil {
return errors.Wrap(err, "cert record")
}
if cert.Type != RecordTypeApplication {
return errors.Wrap(err, "unexpected record type")
}
// `$record_header = type 1 byte + version 2 bytes + payload_length 2 bytes = 5 bytes`
// `$server_hello_header = type 1 bytes + version 2 bytes + length 3 bytes = 6 bytes`
// `$offset = $record_header + $server_hello_header = 11 bytes`
const serverRandomOffset = 11
packet := packetBuf.Bytes()
// Copy original digest.
var originalDigest [32]byte
copy(originalDigest[:], packet[serverRandomOffset:serverRandomOffset+32])
// Fill original digest by zeros.
var zeros [32]byte
copy(packet[serverRandomOffset:serverRandomOffset+32], zeros[:])
mac := hmac.New(sha256.New, secret)
if _, err := mac.Write(clientRandom[:]); err != nil {
return errors.Wrap(err, "hmac write")
}
if _, err := mac.Write(packet); err != nil {
return errors.Wrap(err, "hmac write")
}
if !bytes.Equal(mac.Sum(nil), originalDigest[:]) {
return errors.New("hmac digest mismatch")
}
return nil
}
@@ -0,0 +1,57 @@
package faketls
import (
"bytes"
"encoding/hex"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/require"
)
func Test_readServerHello(t *testing.T) {
p := filepath.Join("testdata", "server_hello")
entries, err := os.ReadDir(p)
if err != nil {
t.Fatal(err)
}
clientRandom := map[string][32]uint8{
"alexbers.hex": {
0xa1, 0x32, 0xe3, 0x91, 0x60, 0x83, 0xb3, 0x14, 0xc1, 0xb9, 0x74, 0xd0, 0x57, 0x85, 0xe8, 0xee,
0x70, 0x45, 0x6e, 0x5f, 0x86, 0x6d, 0x96, 0x57, 0xd5, 0x0a, 0x5c, 0x08, 0xea, 0x38, 0x31, 0x8e,
},
"mtgv2.hex": {
0xca, 0x36, 0xbb, 0xa8, 0x33, 0x80, 0x9a, 0x33, 0xaa, 0x62, 0x7e, 0xbb, 0x5a, 0x32, 0xa1, 0x01,
0x02, 0xd1, 0xa6, 0x1e, 0x1e, 0x6c, 0x58, 0xa4, 0x61, 0xd9, 0x34, 0x57, 0x4d, 0x2e, 0x2e, 0xa3,
},
}
secret := []uint8{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
}
for _, entry := range entries {
if entry.IsDir() {
t.Error("Unexpected directory in testdata")
continue
}
fileName := entry.Name()
t.Run(fileName, func(t *testing.T) {
a := require.New(t)
data, err := os.ReadFile(filepath.Join(p, fileName))
a.NoError(err)
decode, err := hex.DecodeString(strings.TrimSpace(string(data)))
a.NoError(err)
r := bytes.NewReader(decode)
a.NoError(readServerHello(r, clientRandom[entry.Name()], secret))
a.Zero(r.Len(), "should read all data")
})
}
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
160303007a02000076030304794e0ec450abbe0de461b3088d0c487114bdf377733be767eb99cf92ad7eac200de22030bd1329ebfffc70476cf3075efbb95aea776bfa96ab6788c4bff59b2f130100002e002b0002030400330024001d0020df3a68806eecc284a06d8cd934d2a6f1486ab47759457cd0a7a75883fd7e725614030300010117030305c096a8cd3e601b32e3703565d402547894916120178d2330163d3b13e0d7bca02b49fadd55111c2a69fcc75b8e56bdf567eaab01337b19714345e4222c06067cec94dfcdfefc82d2294893ed16d5953fbfc3f7fece2e690dedf46d41b698438237bdee2cb87af0b082e7036d8d42cf9f994407af21b888583f70f5b6a6182881bce5e802b2afd6f5aa45ba043388457010fd649e2c4b98efe11eae85743cbc37b256b06d08b36110ff923febac033487ff8a7fc422b6cd95c2056fa6b15585b34dc21cf588bc2ce0b84d230ff4b97c5e15ffe8a0cc0cc29768d2a17d590e7d5cc082afac040b4e6159a67405d6164f8870704cff8d492afb79b7d93953271f7e7fbd89c8489c99d92e4f3747213deeb5db0feabad6fc1217308bb68c84282ac2cc3d2e1b7e76f86b35d06137fc90fc228995a25f87dfa369dc97b027a76d2ad14f7f1cd60d2ee634c4f3fec49ea5d1d9582b124a4dd7ad082fd2dae39cb59612d67c9eb320bf85f1d8caa72910cda30f57ca888cba453ee3604dcad3ba0768429b4c51855499aba65070c3e2fcbe020c60376e9823c43da8dc098d22eec9c05514d8dc94bc5b8e34812356d44be5d02755643a297e84d126d0cbb628da90cf88d3a0e2c2ad03d34ca3c4d0d1cd35d7f5db041ea2e1a2cb27413c6d8dbbbe3914bfd651ebcc2cadc66083143147f5b8b2534b2d87dc708a9e1fc13ae1fe7055ad3e8b267a63088b2c5e119e2a2540924e7c76e4b0740bf99c0a95be7cc110b6c2432afa1de48b33ddd8a6429dfcfa87c140c435f3c7277cac129697ac8667a952f97688cfe570af4a9ee8dee285c94b459f7836a57c58d02c16e78a900de75728e30b22d37845db718e1fcd03bf85839bbfe16bfd3c8c10e301f247e177a00eb07e439ac5be339e63f057a58ea1ad54ba311866fb977788da894c4c097f78727c72531895cdc98d1976883238c8af3f1f753f1eda49396c36093b2170fc7b577bf82b282be6843b03d74c9a6b82d9f3c6791e42e8e90612ed926b7f26d89d09c62461f9faa4c647a0218f62aa272882777624da48f66daa9d998cf4ccf80b7248f0adbfd329ffa047b514ce8d9c64a55f303438f385726946be120ad2c52c3a3d0f26f4c196994fcef3da70703e06280283a864d612c40054186b767e7fc7df68d272ff7f2f80d4cdb1ae53df04c90f944e3b00316007d69e67531e45b6a3f99cdc60a6f43c77552a1d41f341448148f30063457060a824508704ec807bb41d6706f975ba7a5d56b350e06b01600eb3c627d512a437b2033a82f92bba0fbb07ae01ca2b3a6b2a72f3a935f52feea83751fbaddf81c8bcfe38c810ca376bb1c731e57d66e3e023f975421abc5dfcf8e176bc1ae5ac8849cffe3754ea2950afc4db6baa9fbd2c7d14bbc8c1042d017d2ae766d40729f08c2ff5e32afe96325bae777f3f5e519278fb3c111b2fefc1082309d89aea356542c932c19664f4f02943f83b7e1f0db48a2e4e3ec3d7eea5718e5a9d7bf9294ca7bbf8baa8857dc6a6b04a46fb8654091a7e599f5aa5fd2084091b3024b101be86baed574a587b5b945b16af190d6e759353be612b280cac604960b690a7c831353a767cb20551b397e7ae6a3293b7db12ca996fb823716e004b3399a2b7f37520844f7fe377a345dc2a0c80b64bffdef417faa610ac0ada3bd6fbff61f8e08fbdf66a48e3434c9f46c9dcb73c48526a2caff41029406950c768dc6a215d520f1901b12024315ed5fd8de0700b55b07e545f5ffd6037e2b23433e186951320104ab534d2fcfd9d37b93172933a9f7ecc3f007b01ffab8c902287b1d70c214e4c5b54f3d3e91e740e14cac69525504fdc35ed0322561e83d5d7fa90859140342429761cc18e1ff1f133e3535368235bb1a77a6373008cbd45d4495ae858d601c31532b8f9e8e5ebbebaf73fd9d0cbddaa866b8017c415fbc37df38c34f6b2bc99354b4d52066f8a89beafe8da91275abee0531ea6a28c50a43117fa774855e9106d7177a5408f64aa2e7a58bdc89873d506ff2bf26e21a232362d76c15686dd8b19c13fdafaae357c5229e1f4
+35
View File
@@ -0,0 +1,35 @@
package faketls
// RecordType represents TLS record type byte.
type RecordType uint8
const (
// RecordTypeChangeCipherSpec is ChangeCipherSpec record type byte.
RecordTypeChangeCipherSpec RecordType = 0x14
// RecordTypeAlert is Alert record type byte.
RecordTypeAlert RecordType = 0x15
// RecordTypeHandshake is Handshake record type byte.
RecordTypeHandshake RecordType = 0x16
// RecordTypeApplication is Application record type byte.
RecordTypeApplication RecordType = 0x17
// RecordTypeHeartbeat is Heartbeat record type byte.
RecordTypeHeartbeat RecordType = 0x18
)
// HandshakeType represents TLS handshake record type byte.
type HandshakeType uint8
const (
// HandshakeTypeClient is client handshake message type.
HandshakeTypeClient HandshakeType = 0x01
// HandshakeTypeServer is server handshake message type.
HandshakeTypeServer HandshakeType = 0x02
)
// Possible versions.
var (
Version10Bytes = [2]byte{0x03, 0x01}
Version11Bytes = [2]byte{0x03, 0x02}
Version12Bytes = [2]byte{0x03, 0x03}
Version13Bytes = [2]byte{0x03, 0x04}
)