mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-08-30 02:15:32 +00:00
Merge branch 'XTLS:main' into target
This commit is contained in:
commit
b19469ffaf
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@ -65,7 +65,7 @@ jobs:
|
|||||||
echo "LATEST=$LATEST" >>${GITHUB_ENV}
|
echo "LATEST=$LATEST" >>${GITHUB_ENV}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
|
2
.github/workflows/release-win7.yml
vendored
2
.github/workflows/release-win7.yml
vendored
@ -63,7 +63,7 @@ jobs:
|
|||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout codebase
|
- name: Checkout codebase
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Show workflow information
|
- name: Show workflow information
|
||||||
run: |
|
run: |
|
||||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -153,7 +153,7 @@ jobs:
|
|||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout codebase
|
- name: Checkout codebase
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Set up NDK
|
- name: Set up NDK
|
||||||
if: matrix.goos == 'android'
|
if: matrix.goos == 'android'
|
||||||
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -45,7 +45,7 @@ jobs:
|
|||||||
os: [windows-latest, ubuntu-latest, macos-latest]
|
os: [windows-latest, ubuntu-latest, macos-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout codebase
|
- name: Checkout codebase
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
|
@ -18,31 +18,31 @@ func Test_parseResponse(t *testing.T) {
|
|||||||
|
|
||||||
ans := new(dns.Msg)
|
ans := new(dns.Msg)
|
||||||
ans.Id = 0
|
ans.Id = 0
|
||||||
p = append(p, common.Must2(ans.Pack()).([]byte))
|
p = append(p, common.Must2(ans.Pack()))
|
||||||
|
|
||||||
p = append(p, []byte{})
|
p = append(p, []byte{})
|
||||||
|
|
||||||
ans = new(dns.Msg)
|
ans = new(dns.Msg)
|
||||||
ans.Id = 1
|
ans.Id = 1
|
||||||
ans.Answer = append(ans.Answer,
|
ans.Answer = append(ans.Answer,
|
||||||
common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")),
|
||||||
common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")),
|
||||||
common.Must2(dns.NewRR("google.com. IN A 8.8.8.8")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN A 8.8.8.8")),
|
||||||
common.Must2(dns.NewRR("google.com. IN A 8.8.4.4")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN A 8.8.4.4")),
|
||||||
)
|
)
|
||||||
p = append(p, common.Must2(ans.Pack()).([]byte))
|
p = append(p, common.Must2(ans.Pack()))
|
||||||
|
|
||||||
ans = new(dns.Msg)
|
ans = new(dns.Msg)
|
||||||
ans.Id = 2
|
ans.Id = 2
|
||||||
ans.Answer = append(ans.Answer,
|
ans.Answer = append(ans.Answer,
|
||||||
common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")),
|
||||||
common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")),
|
||||||
common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")),
|
||||||
common.Must2(dns.NewRR("google.com. IN CNAME test.google.com")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN CNAME test.google.com")),
|
||||||
common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8888")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8888")),
|
||||||
common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8844")).(dns.RR),
|
common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8844")),
|
||||||
)
|
)
|
||||||
p = append(p, common.Must2(ans.Pack()).([]byte))
|
p = append(p, common.Must2(ans.Pack()))
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -13,6 +13,8 @@ const (
|
|||||||
Size = 8192
|
Size = 8192
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrBufferFull = errors.New("buffer is full")
|
||||||
|
|
||||||
var zero = [Size * 10]byte{0}
|
var zero = [Size * 10]byte{0}
|
||||||
|
|
||||||
var pool = bytespool.GetPool(Size)
|
var pool = bytespool.GetPool(Size)
|
||||||
@ -244,6 +246,14 @@ func (b *Buffer) Cap() int32 {
|
|||||||
return int32(len(b.v))
|
return int32(len(b.v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Available returns the available capacity of the buffer content.
|
||||||
|
func (b *Buffer) Available() int32 {
|
||||||
|
if b == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int32(len(b.v)) - b.end
|
||||||
|
}
|
||||||
|
|
||||||
// IsEmpty returns true if the buffer is empty.
|
// IsEmpty returns true if the buffer is empty.
|
||||||
func (b *Buffer) IsEmpty() bool {
|
func (b *Buffer) IsEmpty() bool {
|
||||||
return b.Len() == 0
|
return b.Len() == 0
|
||||||
@ -258,13 +268,16 @@ func (b *Buffer) IsFull() bool {
|
|||||||
func (b *Buffer) Write(data []byte) (int, error) {
|
func (b *Buffer) Write(data []byte) (int, error) {
|
||||||
nBytes := copy(b.v[b.end:], data)
|
nBytes := copy(b.v[b.end:], data)
|
||||||
b.end += int32(nBytes)
|
b.end += int32(nBytes)
|
||||||
|
if nBytes < len(data) {
|
||||||
|
return nBytes, ErrBufferFull
|
||||||
|
}
|
||||||
return nBytes, nil
|
return nBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteByte writes a single byte into the buffer.
|
// WriteByte writes a single byte into the buffer.
|
||||||
func (b *Buffer) WriteByte(v byte) error {
|
func (b *Buffer) WriteByte(v byte) error {
|
||||||
if b.IsFull() {
|
if b.IsFull() {
|
||||||
return errors.New("buffer full")
|
return ErrBufferFull
|
||||||
}
|
}
|
||||||
b.v[b.end] = v
|
b.v[b.end] = v
|
||||||
b.end++
|
b.end++
|
||||||
|
@ -144,7 +144,7 @@ func Compact(mb MultiBuffer) MultiBuffer {
|
|||||||
|
|
||||||
for i := 1; i < len(mb); i++ {
|
for i := 1; i < len(mb); i++ {
|
||||||
curr := mb[i]
|
curr := mb[i]
|
||||||
if last.Len()+curr.Len() > Size {
|
if curr.Len() > last.Available() {
|
||||||
mb2 = append(mb2, last)
|
mb2 = append(mb2, last)
|
||||||
last = curr
|
last = curr
|
||||||
} else {
|
} else {
|
||||||
|
@ -175,6 +175,29 @@ func TestCompact(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCompactWithConsumed(t *testing.T) {
|
||||||
|
// make a consumed buffer (a.Start != 0)
|
||||||
|
a := New()
|
||||||
|
for range 8192 {
|
||||||
|
common.Must2(a.WriteString("a"))
|
||||||
|
}
|
||||||
|
a.Read(make([]byte, 2))
|
||||||
|
|
||||||
|
b := New()
|
||||||
|
for range 2 {
|
||||||
|
common.Must2(b.WriteString("b"))
|
||||||
|
}
|
||||||
|
|
||||||
|
mb := MultiBuffer{a, b}
|
||||||
|
cmb := Compact(mb)
|
||||||
|
mbc := &MultiBufferContainer{mb}
|
||||||
|
mbc.Read(make([]byte, 8190))
|
||||||
|
|
||||||
|
if w := cmb.String(); w != "bb" {
|
||||||
|
t.Error("unexpected Compact result ", w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkSplitBytes(b *testing.B) {
|
func BenchmarkSplitBytes(b *testing.B) {
|
||||||
var mb MultiBuffer
|
var mb MultiBuffer
|
||||||
raw := make([]byte, Size)
|
raw := make([]byte, Size)
|
||||||
|
@ -23,7 +23,9 @@ func Must(err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Must2 panics if the second parameter is not nil, otherwise returns the first parameter.
|
// Must2 panics if the second parameter is not nil, otherwise returns the first parameter.
|
||||||
func Must2(v interface{}, err error) interface{} {
|
// This is useful when function returned "sth, err" and avoid many "if err != nil"
|
||||||
|
// Internal usage only, if user input can cause err, it must be handled
|
||||||
|
func Must2[T any](v T, err error) T {
|
||||||
Must(err)
|
Must(err)
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,7 @@ func NewAesCTRStream(key []byte, iv []byte) cipher.Stream {
|
|||||||
|
|
||||||
// NewAesGcm creates a AEAD cipher based on AES-GCM.
|
// NewAesGcm creates a AEAD cipher based on AES-GCM.
|
||||||
func NewAesGcm(key []byte) cipher.AEAD {
|
func NewAesGcm(key []byte) cipher.AEAD {
|
||||||
block, err := aes.NewCipher(key)
|
block := common.Must2(aes.NewCipher(key))
|
||||||
common.Must(err)
|
aead := common.Must2(cipher.NewGCM(block))
|
||||||
aead, err := cipher.NewGCM(block)
|
|
||||||
common.Must(err)
|
|
||||||
return aead
|
return aead
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ package crypto_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
@ -18,11 +16,8 @@ import (
|
|||||||
func TestAuthenticationReaderWriter(t *testing.T) {
|
func TestAuthenticationReaderWriter(t *testing.T) {
|
||||||
key := make([]byte, 16)
|
key := make([]byte, 16)
|
||||||
rand.Read(key)
|
rand.Read(key)
|
||||||
block, err := aes.NewCipher(key)
|
|
||||||
common.Must(err)
|
|
||||||
|
|
||||||
aead, err := cipher.NewGCM(block)
|
aead := NewAesGcm(key)
|
||||||
common.Must(err)
|
|
||||||
|
|
||||||
const payloadSize = 1024 * 80
|
const payloadSize = 1024 * 80
|
||||||
rawPayload := make([]byte, payloadSize)
|
rawPayload := make([]byte, payloadSize)
|
||||||
@ -71,7 +66,7 @@ func TestAuthenticationReaderWriter(t *testing.T) {
|
|||||||
t.Error(r)
|
t.Error(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = reader.ReadMultiBuffer()
|
_, err := reader.ReadMultiBuffer()
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
t.Error("error: ", err)
|
t.Error("error: ", err)
|
||||||
}
|
}
|
||||||
@ -80,11 +75,8 @@ func TestAuthenticationReaderWriter(t *testing.T) {
|
|||||||
func TestAuthenticationReaderWriterPacket(t *testing.T) {
|
func TestAuthenticationReaderWriterPacket(t *testing.T) {
|
||||||
key := make([]byte, 16)
|
key := make([]byte, 16)
|
||||||
common.Must2(rand.Read(key))
|
common.Must2(rand.Read(key))
|
||||||
block, err := aes.NewCipher(key)
|
|
||||||
common.Must(err)
|
|
||||||
|
|
||||||
aead, err := cipher.NewGCM(block)
|
aead := NewAesGcm(key)
|
||||||
common.Must(err)
|
|
||||||
|
|
||||||
cache := buf.New()
|
cache := buf.New()
|
||||||
iv := make([]byte, 12)
|
iv := make([]byte, 12)
|
||||||
|
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
|||||||
module github.com/xtls/xray-core
|
module github.com/xtls/xray-core
|
||||||
|
|
||||||
go 1.24
|
go 1.25
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cloudflare/circl v1.6.1
|
github.com/cloudflare/circl v1.6.1
|
||||||
|
@ -6,9 +6,7 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/xtls/xray-core/main/commands/base"
|
"github.com/xtls/xray-core/main/commands/base"
|
||||||
. "github.com/xtls/xray-core/transport/internet/tls"
|
. "github.com/xtls/xray-core/transport/internet/tls"
|
||||||
@ -139,14 +137,15 @@ func printCertificates(certs []*x509.Certificate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func printTLSConnDetail(tlsConn *gotls.Conn) {
|
func printTLSConnDetail(tlsConn *gotls.Conn) {
|
||||||
|
connectionState := tlsConn.ConnectionState()
|
||||||
var tlsVersion string
|
var tlsVersion string
|
||||||
if tlsConn.ConnectionState().Version == gotls.VersionTLS13 {
|
if connectionState.Version == gotls.VersionTLS13 {
|
||||||
tlsVersion = "TLS 1.3"
|
tlsVersion = "TLS 1.3"
|
||||||
} else if tlsConn.ConnectionState().Version == gotls.VersionTLS12 {
|
} else if connectionState.Version == gotls.VersionTLS12 {
|
||||||
tlsVersion = "TLS 1.2"
|
tlsVersion = "TLS 1.2"
|
||||||
}
|
}
|
||||||
fmt.Println("TLS Version: ", tlsVersion)
|
fmt.Println("TLS Version: ", tlsVersion)
|
||||||
curveID := *(*gotls.CurveID)(unsafe.Pointer(reflect.ValueOf(tlsConn).Elem().FieldByName("curveID").UnsafeAddr()))
|
curveID := connectionState.CurveID
|
||||||
if curveID != 0 {
|
if curveID != 0 {
|
||||||
PostQuantum := (curveID == gotls.X25519MLKEM768)
|
PostQuantum := (curveID == gotls.X25519MLKEM768)
|
||||||
fmt.Println("TLS Post-Quantum key exchange: ", PostQuantum, "("+curveID.String()+")")
|
fmt.Println("TLS Post-Quantum key exchange: ", PostQuantum, "("+curveID.String()+")")
|
||||||
|
@ -91,7 +91,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dest.Port == 0 {
|
if dest.Port == 0 {
|
||||||
dest.Port = net.Port(common.Must2(strconv.Atoi(port)).(int))
|
dest.Port = net.Port(common.Must2(strconv.Atoi(port)))
|
||||||
}
|
}
|
||||||
if d.portMap != nil && d.portMap[port] != "" {
|
if d.portMap != nil && d.portMap[port] != "" {
|
||||||
h, p, _ := net.SplitHostPort(d.portMap[port])
|
h, p, _ := net.SplitHostPort(d.portMap[port])
|
||||||
@ -99,7 +99,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn st
|
|||||||
dest.Address = net.ParseAddress(h)
|
dest.Address = net.ParseAddress(h)
|
||||||
}
|
}
|
||||||
if len(p) > 0 {
|
if len(p) > 0 {
|
||||||
dest.Port = net.Port(common.Must2(strconv.Atoi(p)).(int))
|
dest.Port = net.Port(common.Must2(strconv.Atoi(p)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package shadowsocks
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
@ -58,11 +57,7 @@ func (a *MemoryAccount) CheckIV(iv []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createAesGcm(key []byte) cipher.AEAD {
|
func createAesGcm(key []byte) cipher.AEAD {
|
||||||
block, err := aes.NewCipher(key)
|
return crypto.NewAesGcm(key)
|
||||||
common.Must(err)
|
|
||||||
gcm, err := cipher.NewGCM(block)
|
|
||||||
common.Must(err)
|
|
||||||
return gcm
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createChaCha20Poly1305(key []byte) cipher.AEAD {
|
func createChaCha20Poly1305(key []byte) cipher.AEAD {
|
||||||
|
@ -2,14 +2,13 @@ package aead
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
|
"github.com/xtls/xray-core/common/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SealVMessAEADHeader(key [16]byte, data []byte) []byte {
|
func SealVMessAEADHeader(key [16]byte, data []byte) []byte {
|
||||||
@ -34,15 +33,7 @@ func SealVMessAEADHeader(key [16]byte, data []byte) []byte {
|
|||||||
|
|
||||||
payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]
|
payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]
|
||||||
|
|
||||||
payloadHeaderLengthAEADAESBlock, err := aes.NewCipher(payloadHeaderLengthAEADKey)
|
payloadHeaderAEAD := crypto.NewAesGcm(payloadHeaderLengthAEADKey)
|
||||||
if err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
payloadHeaderAEAD, err := cipher.NewGCM(payloadHeaderLengthAEADAESBlock)
|
|
||||||
if err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
payloadHeaderLengthAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderLengthAEADNonce, aeadPayloadLengthSerializedByte, generatedAuthID[:])
|
payloadHeaderLengthAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderLengthAEADNonce, aeadPayloadLengthSerializedByte, generatedAuthID[:])
|
||||||
}
|
}
|
||||||
@ -54,15 +45,7 @@ func SealVMessAEADHeader(key [16]byte, data []byte) []byte {
|
|||||||
|
|
||||||
payloadHeaderAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]
|
payloadHeaderAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]
|
||||||
|
|
||||||
payloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderAEADKey)
|
payloadHeaderAEAD := crypto.NewAesGcm(payloadHeaderAEADKey)
|
||||||
if err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
payloadHeaderAEAD, err := cipher.NewGCM(payloadHeaderAEADAESBlock)
|
|
||||||
if err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
payloadHeaderAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderAEADNonce, data, generatedAuthID[:])
|
payloadHeaderAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderAEADNonce, data, generatedAuthID[:])
|
||||||
}
|
}
|
||||||
@ -104,15 +87,7 @@ func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte,
|
|||||||
|
|
||||||
payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(authid[:]), string(nonce[:]))[:12]
|
payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(authid[:]), string(nonce[:]))[:12]
|
||||||
|
|
||||||
payloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderLengthAEADKey)
|
payloadHeaderLengthAEAD := crypto.NewAesGcm(payloadHeaderLengthAEADKey)
|
||||||
if err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
payloadHeaderLengthAEAD, err := cipher.NewGCM(payloadHeaderAEADAESBlock)
|
|
||||||
if err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
decryptedAEADHeaderLengthPayload, erropenAEAD := payloadHeaderLengthAEAD.Open(nil, payloadHeaderLengthAEADNonce, payloadHeaderLengthAEADEncrypted[:], authid[:])
|
decryptedAEADHeaderLengthPayload, erropenAEAD := payloadHeaderLengthAEAD.Open(nil, payloadHeaderLengthAEADNonce, payloadHeaderLengthAEADEncrypted[:], authid[:])
|
||||||
|
|
||||||
@ -145,15 +120,7 @@ func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte,
|
|||||||
return nil, false, bytesRead, err
|
return nil, false, bytesRead, err
|
||||||
}
|
}
|
||||||
|
|
||||||
payloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderAEADKey)
|
payloadHeaderAEAD := crypto.NewAesGcm(payloadHeaderAEADKey)
|
||||||
if err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
payloadHeaderAEAD, err := cipher.NewGCM(payloadHeaderAEADAESBlock)
|
|
||||||
if err != nil {
|
|
||||||
panic(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
decryptedAEADHeaderPayload, erropenAEAD := payloadHeaderAEAD.Open(nil, payloadHeaderAEADNonce, payloadHeaderAEADEncrypted, authid[:])
|
decryptedAEADHeaderPayload, erropenAEAD := payloadHeaderAEAD.Open(nil, payloadHeaderAEADNonce, payloadHeaderAEADEncrypted, authid[:])
|
||||||
|
|
||||||
|
@ -3,8 +3,6 @@ package encoding
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
@ -182,8 +180,7 @@ func (c *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.Respon
|
|||||||
aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)
|
aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)
|
||||||
aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]
|
aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]
|
||||||
|
|
||||||
aeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block)
|
aeadResponseHeaderLengthEncryptionAEAD := crypto.NewAesGcm(aeadResponseHeaderLengthEncryptionKey)
|
||||||
aeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD)
|
|
||||||
|
|
||||||
var aeadEncryptedResponseHeaderLength [18]byte
|
var aeadEncryptedResponseHeaderLength [18]byte
|
||||||
var decryptedResponseHeaderLength int
|
var decryptedResponseHeaderLength int
|
||||||
@ -205,8 +202,7 @@ func (c *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.Respon
|
|||||||
aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)
|
aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)
|
||||||
aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]
|
aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]
|
||||||
|
|
||||||
aeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block)
|
aeadResponseHeaderPayloadEncryptionAEAD := crypto.NewAesGcm(aeadResponseHeaderPayloadEncryptionKey)
|
||||||
aeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD)
|
|
||||||
|
|
||||||
encryptedResponseHeaderBuffer := make([]byte, decryptedResponseHeaderLength+16)
|
encryptedResponseHeaderBuffer := make([]byte, decryptedResponseHeaderLength+16)
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ package encoding
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
@ -350,8 +348,7 @@ func (s *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, wr
|
|||||||
aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)
|
aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)
|
||||||
aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]
|
aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]
|
||||||
|
|
||||||
aeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block)
|
aeadResponseHeaderLengthEncryptionAEAD := crypto.NewAesGcm(aeadResponseHeaderLengthEncryptionKey)
|
||||||
aeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD)
|
|
||||||
|
|
||||||
aeadResponseHeaderLengthEncryptionBuffer := bytes.NewBuffer(nil)
|
aeadResponseHeaderLengthEncryptionBuffer := bytes.NewBuffer(nil)
|
||||||
|
|
||||||
@ -365,8 +362,7 @@ func (s *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, wr
|
|||||||
aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)
|
aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)
|
||||||
aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]
|
aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]
|
||||||
|
|
||||||
aeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block)
|
aeadResponseHeaderPayloadEncryptionAEAD := crypto.NewAesGcm(aeadResponseHeaderPayloadEncryptionKey)
|
||||||
aeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD)
|
|
||||||
|
|
||||||
aeadEncryptedHeaderPayload := aeadResponseHeaderPayloadEncryptionAEAD.Seal(nil, aeadResponseHeaderPayloadEncryptionIV, aeadEncryptedHeaderBuffer.Bytes(), nil)
|
aeadEncryptedHeaderPayload := aeadResponseHeaderPayloadEncryptionAEAD.Seal(nil, aeadResponseHeaderPayloadEncryptionIV, aeadEncryptedHeaderBuffer.Bytes(), nil)
|
||||||
common.Must2(io.Copy(writer, bytes.NewReader(aeadEncryptedHeaderPayload)))
|
common.Must2(io.Copy(writer, bytes.NewReader(aeadEncryptedHeaderPayload)))
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package kcp
|
package kcp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewAEADAESGCMBasedOnSeed(seed string) cipher.AEAD {
|
func NewAEADAESGCMBasedOnSeed(seed string) cipher.AEAD {
|
||||||
hashedSeed := sha256.Sum256([]byte(seed))
|
hashedSeed := sha256.Sum256([]byte(seed))
|
||||||
aesBlock := common.Must2(aes.NewCipher(hashedSeed[:16])).(cipher.Block)
|
return crypto.NewAesGcm(hashedSeed[:])
|
||||||
return common.Must2(cipher.NewGCM(aesBlock)).(cipher.AEAD)
|
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@ package reality
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/ecdh"
|
"crypto/ecdh"
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
@ -169,8 +167,7 @@ func UClient(c net.Conn, config *Config, ctx context.Context, dest net.Destinati
|
|||||||
if _, err := hkdf.New(sha256.New, uConn.AuthKey, hello.Random[:20], []byte("REALITY")).Read(uConn.AuthKey); err != nil {
|
if _, err := hkdf.New(sha256.New, uConn.AuthKey, hello.Random[:20], []byte("REALITY")).Read(uConn.AuthKey); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
block, _ := aes.NewCipher(uConn.AuthKey)
|
aead := crypto.NewAesGcm(uConn.AuthKey)
|
||||||
aead, _ := cipher.NewGCM(block)
|
|
||||||
if config.Show {
|
if config.Show {
|
||||||
fmt.Printf("REALITY localAddr: %v\tuConn.AuthKey[:16]: %v\tAEAD: %T\n", localAddr, uConn.AuthKey[:16], aead)
|
fmt.Printf("REALITY localAddr: %v\tuConn.AuthKey[:16]: %v\tAEAD: %T\n", localAddr, uConn.AuthKey[:16], aead)
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
|
|||||||
if transportConfiguration.DownloadSettings != nil {
|
if transportConfiguration.DownloadSettings != nil {
|
||||||
globalDialerAccess.Lock()
|
globalDialerAccess.Lock()
|
||||||
if streamSettings.DownloadSettings == nil {
|
if streamSettings.DownloadSettings == nil {
|
||||||
streamSettings.DownloadSettings = common.Must2(internet.ToMemoryStreamConfig(transportConfiguration.DownloadSettings)).(*internet.MemoryStreamConfig)
|
streamSettings.DownloadSettings = common.Must2(internet.ToMemoryStreamConfig(transportConfiguration.DownloadSettings))
|
||||||
if streamSettings.SocketSettings != nil && streamSettings.SocketSettings.Penetrate {
|
if streamSettings.SocketSettings != nil && streamSettings.SocketSettings.Penetrate {
|
||||||
streamSettings.DownloadSettings.SocketSettings = streamSettings.SocketSettings
|
streamSettings.DownloadSettings.SocketSettings = streamSettings.SocketSettings
|
||||||
}
|
}
|
||||||
@ -489,15 +489,16 @@ func (w uploadWriter) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
buffer := buf.New()
|
buffer := buf.MultiBufferContainer{}
|
||||||
n, err := buffer.Write(b)
|
common.Must2(buffer.Write(b))
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = w.WriteMultiBuffer([]*buf.Buffer{buffer})
|
var writed int
|
||||||
if err != nil {
|
for _, buff := range buffer.MultiBuffer {
|
||||||
return 0, err
|
err := w.WriteMultiBuffer(buf.MultiBuffer{buff})
|
||||||
|
if err != nil {
|
||||||
|
return writed, err
|
||||||
|
}
|
||||||
|
writed += int(buff.Len())
|
||||||
}
|
}
|
||||||
return n, nil
|
return writed, nil
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package splithttp_test
|
package splithttp_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -421,18 +422,12 @@ func Test_maxUpload(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var uploadSize int
|
uploadReceived := make([]byte, 10001)
|
||||||
listen, err := ListenXH(context.Background(), net.LocalHostIP, listenPort, streamSettings, func(conn stat.Connection) {
|
listen, err := ListenXH(context.Background(), net.LocalHostIP, listenPort, streamSettings, func(conn stat.Connection) {
|
||||||
go func(c stat.Connection) {
|
go func(c stat.Connection) {
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
var b [10240]byte
|
|
||||||
c.SetReadDeadline(time.Now().Add(2 * time.Second))
|
c.SetReadDeadline(time.Now().Add(2 * time.Second))
|
||||||
n, err := c.Read(b[:])
|
io.ReadFull(c, uploadReceived)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadSize = n
|
|
||||||
|
|
||||||
common.Must2(c.Write([]byte("Response")))
|
common.Must2(c.Write([]byte("Response")))
|
||||||
}(conn)
|
}(conn)
|
||||||
@ -441,10 +436,12 @@ func Test_maxUpload(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
conn, err := Dial(ctx, net.TCPDestination(net.DomainAddress("localhost"), listenPort), streamSettings)
|
conn, err := Dial(ctx, net.TCPDestination(net.DomainAddress("localhost"), listenPort), streamSettings)
|
||||||
|
common.Must(err)
|
||||||
|
|
||||||
// send a slightly too large upload
|
// send a slightly too large upload
|
||||||
var upload [10001]byte
|
upload := make([]byte, 10001)
|
||||||
_, err = conn.Write(upload[:])
|
rand.Read(upload)
|
||||||
|
_, err = conn.Write(upload)
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
|
|
||||||
var b [10240]byte
|
var b [10240]byte
|
||||||
@ -455,8 +452,8 @@ func Test_maxUpload(t *testing.T) {
|
|||||||
}
|
}
|
||||||
common.Must(conn.Close())
|
common.Must(conn.Close())
|
||||||
|
|
||||||
if uploadSize > 10000 || uploadSize == 0 {
|
if !bytes.Equal(upload, uploadReceived) {
|
||||||
t.Error("incorrect upload size: ", uploadSize)
|
t.Error("incorrect upload", upload, uploadReceived)
|
||||||
}
|
}
|
||||||
|
|
||||||
common.Must(listen.Close())
|
common.Must(listen.Close())
|
||||||
|
Loading…
Reference in New Issue
Block a user