1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-26 01:15:38 +00:00

isolate tls settings

This commit is contained in:
Shelikhoo 2021-09-04 12:48:23 +01:00
parent 38210fd74a
commit df9624a965
No known key found for this signature in database
GPG Key ID: C4D5E79D22B25316
3 changed files with 124 additions and 105 deletions

View File

@ -0,0 +1,9 @@
package tlscfg
import "github.com/v2fly/v2ray-core/v4/common/errors"
type errPathObjHolder struct{}
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}

View File

@ -0,0 +1,112 @@
package tlscfg
import (
"encoding/base64"
"github.com/golang/protobuf/proto"
"github.com/v2fly/v2ray-core/v4/common/platform/filesystem"
"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
"github.com/v2fly/v2ray-core/v4/transport/internet/tls"
"strings"
)
//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen
type TLSConfig struct {
Insecure bool `json:"allowInsecure"`
Certs []*TLSCertConfig `json:"certificates"`
ServerName string `json:"serverName"`
ALPN *cfgcommon.StringList `json:"alpn"`
EnableSessionResumption bool `json:"enableSessionResumption"`
DisableSystemRoot bool `json:"disableSystemRoot"`
PinnedPeerCertificateChainSha256 *[]string `json:"pinnedPeerCertificateChainSha256"`
VerifyClientCertificate bool `json:"verifyClientCertificate"`
}
// Build implements Buildable.
func (c *TLSConfig) Build() (proto.Message, error) {
config := new(tls.Config)
config.Certificate = make([]*tls.Certificate, len(c.Certs))
for idx, certConf := range c.Certs {
cert, err := certConf.Build()
if err != nil {
return nil, err
}
config.Certificate[idx] = cert
}
serverName := c.ServerName
config.AllowInsecure = c.Insecure
config.VerifyClientCertificate = c.VerifyClientCertificate
if len(c.ServerName) > 0 {
config.ServerName = serverName
}
if c.ALPN != nil && len(*c.ALPN) > 0 {
config.NextProtocol = []string(*c.ALPN)
}
config.EnableSessionResumption = c.EnableSessionResumption
config.DisableSystemRoot = c.DisableSystemRoot
if c.PinnedPeerCertificateChainSha256 != nil {
config.PinnedPeerCertificateChainSha256 = [][]byte{}
for _, v := range *c.PinnedPeerCertificateChainSha256 {
hashValue, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return nil, err
}
config.PinnedPeerCertificateChainSha256 = append(config.PinnedPeerCertificateChainSha256, hashValue)
}
}
return config, nil
}
type TLSCertConfig struct {
CertFile string `json:"certificateFile"`
CertStr []string `json:"certificate"`
KeyFile string `json:"keyFile"`
KeyStr []string `json:"key"`
Usage string `json:"usage"`
}
// Build implements Buildable.
func (c *TLSCertConfig) Build() (*tls.Certificate, error) {
certificate := new(tls.Certificate)
cert, err := readFileOrString(c.CertFile, c.CertStr)
if err != nil {
return nil, newError("failed to parse certificate").Base(err)
}
certificate.Certificate = cert
if len(c.KeyFile) > 0 || len(c.KeyStr) > 0 {
key, err := readFileOrString(c.KeyFile, c.KeyStr)
if err != nil {
return nil, newError("failed to parse key").Base(err)
}
certificate.Key = key
}
switch strings.ToLower(c.Usage) {
case "encipherment":
certificate.Usage = tls.Certificate_ENCIPHERMENT
case "verify":
certificate.Usage = tls.Certificate_AUTHORITY_VERIFY
case "verifyclient":
certificate.Usage = tls.Certificate_AUTHORITY_VERIFY_CLIENT
case "issue":
certificate.Usage = tls.Certificate_AUTHORITY_ISSUE
default:
certificate.Usage = tls.Certificate_ENCIPHERMENT
}
return certificate, nil
}
func readFileOrString(f string, s []string) ([]byte, error) {
if len(f) > 0 {
return filesystem.ReadFile(f)
}
if len(s) > 0 {
return []byte(strings.Join(s, "\n")), nil
}
return nil, newError("both file and bytes are empty.")
}

View File

@ -1,14 +1,13 @@
package v4
import (
"encoding/base64"
"encoding/json"
"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/loader"
"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/tlscfg"
"strings"
"github.com/golang/protobuf/proto"
"github.com/v2fly/v2ray-core/v4/common/platform/filesystem"
"github.com/v2fly/v2ray-core/v4/common/protocol"
"github.com/v2fly/v2ray-core/v4/common/serial"
"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
@ -19,7 +18,6 @@ import (
"github.com/v2fly/v2ray-core/v4/transport/internet/kcp"
"github.com/v2fly/v2ray-core/v4/transport/internet/quic"
"github.com/v2fly/v2ray-core/v4/transport/internet/tcp"
"github.com/v2fly/v2ray-core/v4/transport/internet/tls"
"github.com/v2fly/v2ray-core/v4/transport/internet/websocket"
)
@ -261,106 +259,6 @@ func (c *DomainSocketConfig) Build() (proto.Message, error) {
}, nil
}
func readFileOrString(f string, s []string) ([]byte, error) {
if len(f) > 0 {
return filesystem.ReadFile(f)
}
if len(s) > 0 {
return []byte(strings.Join(s, "\n")), nil
}
return nil, newError("both file and bytes are empty.")
}
type TLSCertConfig struct {
CertFile string `json:"certificateFile"`
CertStr []string `json:"certificate"`
KeyFile string `json:"keyFile"`
KeyStr []string `json:"key"`
Usage string `json:"usage"`
}
// Build implements Buildable.
func (c *TLSCertConfig) Build() (*tls.Certificate, error) {
certificate := new(tls.Certificate)
cert, err := readFileOrString(c.CertFile, c.CertStr)
if err != nil {
return nil, newError("failed to parse certificate").Base(err)
}
certificate.Certificate = cert
if len(c.KeyFile) > 0 || len(c.KeyStr) > 0 {
key, err := readFileOrString(c.KeyFile, c.KeyStr)
if err != nil {
return nil, newError("failed to parse key").Base(err)
}
certificate.Key = key
}
switch strings.ToLower(c.Usage) {
case "encipherment":
certificate.Usage = tls.Certificate_ENCIPHERMENT
case "verify":
certificate.Usage = tls.Certificate_AUTHORITY_VERIFY
case "verifyclient":
certificate.Usage = tls.Certificate_AUTHORITY_VERIFY_CLIENT
case "issue":
certificate.Usage = tls.Certificate_AUTHORITY_ISSUE
default:
certificate.Usage = tls.Certificate_ENCIPHERMENT
}
return certificate, nil
}
type TLSConfig struct {
Insecure bool `json:"allowInsecure"`
Certs []*TLSCertConfig `json:"certificates"`
ServerName string `json:"serverName"`
ALPN *cfgcommon.StringList `json:"alpn"`
EnableSessionResumption bool `json:"enableSessionResumption"`
DisableSystemRoot bool `json:"disableSystemRoot"`
PinnedPeerCertificateChainSha256 *[]string `json:"pinnedPeerCertificateChainSha256"`
VerifyClientCertificate bool `json:"verifyClientCertificate"`
}
// Build implements Buildable.
func (c *TLSConfig) Build() (proto.Message, error) {
config := new(tls.Config)
config.Certificate = make([]*tls.Certificate, len(c.Certs))
for idx, certConf := range c.Certs {
cert, err := certConf.Build()
if err != nil {
return nil, err
}
config.Certificate[idx] = cert
}
serverName := c.ServerName
config.AllowInsecure = c.Insecure
config.VerifyClientCertificate = c.VerifyClientCertificate
if len(c.ServerName) > 0 {
config.ServerName = serverName
}
if c.ALPN != nil && len(*c.ALPN) > 0 {
config.NextProtocol = []string(*c.ALPN)
}
config.EnableSessionResumption = c.EnableSessionResumption
config.DisableSystemRoot = c.DisableSystemRoot
if c.PinnedPeerCertificateChainSha256 != nil {
config.PinnedPeerCertificateChainSha256 = [][]byte{}
for _, v := range *c.PinnedPeerCertificateChainSha256 {
hashValue, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return nil, err
}
config.PinnedPeerCertificateChainSha256 = append(config.PinnedPeerCertificateChainSha256, hashValue)
}
}
return config, nil
}
type TransportProtocol string
// Build implements Buildable.
@ -425,7 +323,7 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
type StreamConfig struct {
Network *TransportProtocol `json:"network"`
Security string `json:"security"`
TLSSettings *TLSConfig `json:"tlsSettings"`
TLSSettings *tlscfg.TLSConfig `json:"tlsSettings"`
TCPSettings *TCPConfig `json:"tcpSettings"`
KCPSettings *KCPConfig `json:"kcpSettings"`
WSSettings *WebSocketConfig `json:"wsSettings"`
@ -452,7 +350,7 @@ func (c *StreamConfig) Build() (*internet.StreamConfig, error) {
if strings.EqualFold(c.Security, "tls") {
tlsSettings := c.TLSSettings
if tlsSettings == nil {
tlsSettings = &TLSConfig{}
tlsSettings = &tlscfg.TLSConfig{}
}
ts, err := tlsSettings.Build()
if err != nil {