package faketls
import (
"crypto/hmac"
"crypto/sha256"
"encoding/binary"
"io"
"github.com/go-faster/errors"
"github.com/gotd/td/bin"
"github.com/gotd/td/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
}
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 {})
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 )
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 (r [:], b .Buf [randomOffset :randomOffset +32 ])
_, err = w .Write (b .Buf )
return r , err
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .