mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-20 09:00:04 +08:00
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Test / test (1.25, macos-13) (push) Waiting to run
Test / test (1.25, macos-latest) (push) Waiting to run
Test / test (1.25, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.25, ubuntu-latest) (push) Waiting to run
Test / test (1.25, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run
119 lines
3.6 KiB
Go
119 lines
3.6 KiB
Go
package encryption
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// NewClient new client from encryption string
|
|
// maybe return a nil *ClientInstance without any error, that means don't need to encrypt
|
|
func NewClient(encryption string) (*ClientInstance, error) {
|
|
switch encryption {
|
|
case "", "none": // We will not reject empty string like xray-core does, because we need to ensure compatibility
|
|
return nil, nil
|
|
}
|
|
if s := strings.Split(encryption, "."); len(s) >= 4 && s[0] == "mlkem768x25519plus" {
|
|
var xorMode uint32
|
|
switch s[1] {
|
|
case "native":
|
|
case "xorpub":
|
|
xorMode = 1
|
|
case "random":
|
|
xorMode = 2
|
|
default:
|
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
|
}
|
|
var seconds uint32
|
|
switch s[2] {
|
|
case "1rtt":
|
|
case "0rtt":
|
|
seconds = 1
|
|
default:
|
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
|
}
|
|
var nfsPKeysBytes [][]byte
|
|
var paddings []string
|
|
for _, r := range s[3:] {
|
|
if len(r) < 20 {
|
|
paddings = append(paddings, r)
|
|
continue
|
|
}
|
|
b, err := base64.RawURLEncoding.DecodeString(r)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
|
}
|
|
if len(b) != X25519PasswordSize && len(b) != MLKEM768ClientLength {
|
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
|
}
|
|
nfsPKeysBytes = append(nfsPKeysBytes, b)
|
|
}
|
|
padding := strings.Join(paddings, ".")
|
|
client := &ClientInstance{}
|
|
if err := client.Init(nfsPKeysBytes, xorMode, seconds, padding); err != nil {
|
|
return nil, fmt.Errorf("failed to use encryption: %w", err)
|
|
}
|
|
return client, nil
|
|
}
|
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
|
}
|
|
|
|
// NewServer new server from decryption string
|
|
// maybe return a nil *ServerInstance without any error, that means don't need to decrypt
|
|
func NewServer(decryption string) (*ServerInstance, error) {
|
|
switch decryption {
|
|
case "", "none": // We will not reject empty string like xray-core does, because we need to ensure compatibility
|
|
return nil, nil
|
|
}
|
|
if s := strings.Split(decryption, "."); len(s) >= 4 && s[0] == "mlkem768x25519plus" {
|
|
var xorMode uint32
|
|
switch s[1] {
|
|
case "native":
|
|
case "xorpub":
|
|
xorMode = 1
|
|
case "random":
|
|
xorMode = 2
|
|
default:
|
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
|
}
|
|
t := strings.SplitN(strings.TrimSuffix(s[2], "s"), "-", 2)
|
|
i, err := strconv.Atoi(t[0])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
|
}
|
|
secondsFrom := int64(i)
|
|
secondsTo := int64(0)
|
|
if len(t) == 2 {
|
|
i, err = strconv.Atoi(t[1])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
|
}
|
|
secondsTo = int64(i)
|
|
}
|
|
var nfsSKeysBytes [][]byte
|
|
var paddings []string
|
|
for _, r := range s[3:] {
|
|
if len(r) < 20 {
|
|
paddings = append(paddings, r)
|
|
continue
|
|
}
|
|
b, err := base64.RawURLEncoding.DecodeString(r)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
|
}
|
|
if len(b) != X25519PrivateKeySize && len(b) != MLKEM768SeedLength {
|
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
|
}
|
|
nfsSKeysBytes = append(nfsSKeysBytes, b)
|
|
}
|
|
padding := strings.Join(paddings, ".")
|
|
server := &ServerInstance{}
|
|
if err := server.Init(nfsSKeysBytes, xorMode, secondsFrom, secondsTo, padding); err != nil {
|
|
return nil, fmt.Errorf("failed to use decryption: %w", err)
|
|
}
|
|
return server, nil
|
|
}
|
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
|
}
|