FILE / ScuroNeko/mtg

faketls/client_protocol.go

Исходный файл и его история в репозитории.
FILE 038b2b200db55d01e6eaf8e893b1a0e8445583b1
Files
mtg/faketls/client_protocol.go
T

104 lines
2.5 KiB
Go

package faketls
import (
"bufio"
"encoding/binary"
"errors"
"fmt"
"io"
"time"
"github.com/9seconds/mtg/antireplay"
"github.com/9seconds/mtg/conntypes"
"github.com/9seconds/mtg/obfuscated2"
"github.com/9seconds/mtg/protocol"
"github.com/9seconds/mtg/stats"
"github.com/9seconds/mtg/tlstypes"
"github.com/9seconds/mtg/wrappers/stream"
)
type ClientProtocol struct {
obfuscated2.ClientProtocol
}
func (c *ClientProtocol) Handshake(socket conntypes.StreamReadWriteCloser) (conntypes.StreamReadWriteCloser, error) {
rewinded := stream.NewRewind(socket)
bufferedReader := bufio.NewReader(rewinded)
for _, expected := range faketlsStartBytes {
if actual, err := bufferedReader.ReadByte(); err != nil || actual != expected {
fmt.Println("!!!!!!!!!!!! ERROR !!!!!!!!!!!!", err)
return nil, errors.New("qqq")
}
}
rewinded.Rewind()
rewinded = stream.NewRewind(rewinded)
if err := c.tlsHandshake(rewinded); err != nil {
fmt.Println("!!!!!!!!!!!! ERROR !!!!!!!!!!!!", err)
return nil, errors.New("qqq")
}
conn := stream.NewFakeTLS(socket)
conn, err := c.ClientProtocol.Handshake(conn)
if err != nil {
return nil, err
}
return conn, err
}
func (c *ClientProtocol) tlsHandshake(conn io.ReadWriter) error {
helloRecord, err := tlstypes.ReadRecord(conn)
if err != nil {
return fmt.Errorf("cannot read initial record: %w", err)
}
clientHello, err := tlstypes.ParseClientHello(helloRecord.Data.Bytes())
if err != nil {
return fmt.Errorf("cannot parse client hello: %w", err)
}
digest := clientHello.Digest()
for i := 0; i < len(digest)-4; i++ {
if digest[i] != 0 {
return errBadDigest
}
}
timestamp := int64(binary.LittleEndian.Uint32(digest[len(digest)-4:]))
createdAt := time.Unix(timestamp, 0)
timeDiff := time.Since(createdAt)
if (timeDiff > TimeSkew || timeDiff < -TimeSkew) && timestamp > TimeFromBoot {
return errBadTime
}
if antireplay.Cache.HasTLS(clientHello.Random[:]) {
stats.Stats.AntiReplayDetected()
return errors.New("antireplay detected")
}
antireplay.Cache.AddTLS(clientHello.Random[:])
hostCert, err := connectionServerInstance.get()
if err != nil {
return fmt.Errorf("cannot get host certificate: %w", err)
}
serverHello := tlstypes.NewServerHello(clientHello)
serverHelloPacket := serverHello.WelcomePacket(hostCert)
if _, err := conn.Write(serverHelloPacket); err != nil {
return fmt.Errorf("cannot send welcome packet: %w", err)
}
return nil
}
func MakeClientProtocol() protocol.ClientProtocol {
return &ClientProtocol{}
}