Files
sing-box-extended/protocol/masque/config.go

90 lines
2.9 KiB
Go

package masque
import (
"crypto/ecdsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"net"
)
type Config struct {
PrivateKey string `json:"private_key"` // Base64-encoded ECDSA private key
EndpointV4 string `json:"endpoint_v4"` // IPv4 address of the endpoint
EndpointV6 string `json:"endpoint_v6"` // IPv6 address of the endpoint
EndpointH2V4 string `json:"endpoint_h2_v4"` // IPv4 address used in HTTP/2 mode
EndpointH2V6 string `json:"endpoint_h2_v6"` // IPv6 address used in HTTP/2 mode
EndpointPubKey string `json:"endpoint_pub_key"` // PEM-encoded ECDSA public key of the endpoint to verify against
License string `json:"license"` // Application license key
ID string `json:"id"` // Device unique identifier
AccessToken string `json:"access_token"` // Authentication token for API access
IPv4 string `json:"ipv4"` // Assigned IPv4 address
IPv6 string `json:"ipv6"` // Assigned IPv6 address
}
func (c *Config) GetEcPrivateKey() (*ecdsa.PrivateKey, error) {
privKeyB64, err := base64.StdEncoding.DecodeString(c.PrivateKey)
if err != nil {
return nil, fmt.Errorf("failed to decode private key: %v", err)
}
privKey, err := x509.ParseECPrivateKey(privKeyB64)
if err != nil {
return nil, fmt.Errorf("failed to parse private key: %v", err)
}
return privKey, nil
}
func (c *Config) GetEcEndpointPublicKey() (*ecdsa.PublicKey, error) {
endpointPubKeyB64, _ := pem.Decode([]byte(c.EndpointPubKey))
if endpointPubKeyB64 == nil {
return nil, fmt.Errorf("failed to decode endpoint public key")
}
pubKey, err := x509.ParsePKIXPublicKey(endpointPubKeyB64.Bytes)
if err != nil {
return nil, fmt.Errorf("failed to parse public key: %v", err)
}
ecPubKey, ok := pubKey.(*ecdsa.PublicKey)
if !ok {
return nil, fmt.Errorf("failed to assert public key as ECDSA")
}
return ecPubKey, nil
}
func (c *Config) SelectEndpointFromConfig(useHTTP2 bool, useIPv6 bool, port int) (net.Addr, error) {
if useHTTP2 {
if useIPv6 {
if c.EndpointH2V6 == "" {
return nil, fmt.Errorf("--http2 with --ipv6 requires config endpoint_h2_v6 to be set")
}
ip := net.ParseIP(c.EndpointH2V6)
if ip == nil {
return nil, fmt.Errorf("invalid endpoint_h2_v6 value %q", c.EndpointH2V6)
}
return &net.TCPAddr{IP: ip, Port: port}, nil
}
v4 := c.EndpointH2V4
ip := net.ParseIP(v4)
if ip == nil {
return nil, fmt.Errorf("invalid endpoint_h2_v4 value %q")
}
return &net.TCPAddr{IP: ip, Port: port}, nil
}
if useIPv6 {
ip := net.ParseIP(c.EndpointV6)
if ip == nil {
return nil, fmt.Errorf("invalid endpoint_v6 value %q", c.EndpointV6)
}
return &net.UDPAddr{IP: ip, Port: port}, nil
}
ip := net.ParseIP(c.EndpointV4)
if ip == nil {
return nil, fmt.Errorf("invalid endpoint_v4 value %q", c.EndpointV4)
}
return &net.UDPAddr{IP: ip, Port: port}, nil
}