mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-10-14 03:23:58 +00:00
81 lines
2.4 KiB
Go
81 lines
2.4 KiB
Go
package lua
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/ed25519"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"sync"
|
|
|
|
"github.com/xtls/xray-core/common/errors"
|
|
)
|
|
|
|
var privilegedKey struct {
|
|
sync.Once
|
|
publicKey ed25519.PublicKey
|
|
}
|
|
|
|
// SetPrivilegedPublicKey configures the trusted Ed25519 public key once at
|
|
// startup, before compiling scripts. An empty value disables authorization.
|
|
// Nonempty values must be unpadded Base64URL encodings of exactly 32 bytes.
|
|
func SetPrivilegedPublicKey(value string) error {
|
|
var publicKey ed25519.PublicKey
|
|
if value != "" {
|
|
decoded, err := decodePrivilegedValue(value, ed25519.PublicKeySize)
|
|
if err != nil {
|
|
return errors.New("invalid Lua privileged public key").Base(err)
|
|
}
|
|
publicKey = ed25519.PublicKey(decoded)
|
|
}
|
|
privilegedKey.Do(func() {
|
|
privilegedKey.publicKey = publicKey
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func decodePrivilegedValue(value string, size int) ([]byte, error) {
|
|
encoding := base64.RawURLEncoding.Strict()
|
|
if len(value) != encoding.EncodedLen(size) {
|
|
return nil, errors.New("expected an unpadded Base64URL encoding of ", size, " bytes")
|
|
}
|
|
decoded, err := encoding.DecodeString(value)
|
|
if err != nil || len(decoded) != size || encoding.EncodeToString(decoded) != value {
|
|
return nil, errors.New("expected an unpadded Base64URL encoding of ", size, " bytes")
|
|
}
|
|
return decoded, nil
|
|
}
|
|
|
|
func verifyPrivilegedSignature(code []byte) (bool, error) {
|
|
for len(code) != 0 {
|
|
line, rest, _ := bytes.Cut(code, []byte{'\n'})
|
|
code = rest
|
|
line = bytes.TrimSuffix(line, []byte{'\r'})
|
|
if len(bytes.TrimSpace(line)) == 0 {
|
|
continue
|
|
}
|
|
line, found := bytes.CutPrefix(bytes.TrimLeft(line, " \t"), []byte("--"))
|
|
if !found {
|
|
return false, nil
|
|
}
|
|
value, found := bytes.CutPrefix(bytes.TrimLeft(line, " \t"), []byte("@xray:privileged-signature="))
|
|
if !found {
|
|
return false, nil
|
|
}
|
|
|
|
publicKey := privilegedKey.publicKey
|
|
if len(publicKey) == 0 {
|
|
return false, errors.New("Lua privileged signature requires --lua-privileged-pubkey")
|
|
}
|
|
signature, err := decodePrivilegedValue(string(bytes.TrimSpace(value)), ed25519.SignatureSize)
|
|
if err != nil {
|
|
return false, errors.New("invalid Lua privileged signature").Base(err)
|
|
}
|
|
digest := sha256.Sum256(bytes.TrimSpace(rest))
|
|
if !ed25519.Verify(publicKey, digest[:], signature) {
|
|
return false, errors.New("Lua privileged signature verification failed")
|
|
}
|
|
return true, nil
|
|
}
|
|
return false, nil
|
|
}
|