github.com/imannamdari/v2ray-core/v5@v5.0.5/infra/conf/cfgcommon/tlscfg/tls.go (about) 1 package tlscfg 2 3 import ( 4 "encoding/base64" 5 "strings" 6 7 "github.com/golang/protobuf/proto" 8 9 "github.com/imannamdari/v2ray-core/v5/common/platform/filesystem" 10 "github.com/imannamdari/v2ray-core/v5/infra/conf/cfgcommon" 11 "github.com/imannamdari/v2ray-core/v5/transport/internet/tls" 12 ) 13 14 //go:generate go run github.com/imannamdari/v2ray-core/v5/common/errors/errorgen 15 16 type TLSConfig struct { 17 Insecure bool `json:"allowInsecure"` 18 Certs []*TLSCertConfig `json:"certificates"` 19 ServerName string `json:"serverName"` 20 ALPN *cfgcommon.StringList `json:"alpn"` 21 EnableSessionResumption bool `json:"enableSessionResumption"` 22 DisableSystemRoot bool `json:"disableSystemRoot"` 23 PinnedPeerCertificateChainSha256 *[]string `json:"pinnedPeerCertificateChainSha256"` 24 VerifyClientCertificate bool `json:"verifyClientCertificate"` 25 EnableEch bool `json:"enableEch"` 26 EchSetting *TLSEchSetting `json:"echSetting"` 27 } 28 29 // Build implements Buildable. 30 func (c *TLSConfig) Build() (proto.Message, error) { 31 config := new(tls.Config) 32 config.Certificate = make([]*tls.Certificate, len(c.Certs)) 33 for idx, certConf := range c.Certs { 34 cert, err := certConf.Build() 35 if err != nil { 36 return nil, err 37 } 38 config.Certificate[idx] = cert 39 } 40 serverName := c.ServerName 41 config.AllowInsecure = c.Insecure 42 config.VerifyClientCertificate = c.VerifyClientCertificate 43 if len(c.ServerName) > 0 { 44 config.ServerName = serverName 45 } 46 if c.ALPN != nil && len(*c.ALPN) > 0 { 47 config.NextProtocol = []string(*c.ALPN) 48 } 49 config.EnableSessionResumption = c.EnableSessionResumption 50 config.DisableSystemRoot = c.DisableSystemRoot 51 52 if c.PinnedPeerCertificateChainSha256 != nil { 53 config.PinnedPeerCertificateChainSha256 = [][]byte{} 54 for _, v := range *c.PinnedPeerCertificateChainSha256 { 55 hashValue, err := base64.StdEncoding.DecodeString(v) 56 if err != nil { 57 return nil, err 58 } 59 config.PinnedPeerCertificateChainSha256 = append(config.PinnedPeerCertificateChainSha256, hashValue) 60 } 61 } 62 63 config.EnableEch = c.EnableEch 64 if c.EchSetting != nil { 65 config.EchSetting, _ = c.EchSetting.Build() 66 } 67 68 return config, nil 69 } 70 71 type TLSCertConfig struct { 72 CertFile string `json:"certificateFile"` 73 CertStr []string `json:"certificate"` 74 KeyFile string `json:"keyFile"` 75 KeyStr []string `json:"key"` 76 Usage string `json:"usage"` 77 } 78 79 // Build implements Buildable. 80 func (c *TLSCertConfig) Build() (*tls.Certificate, error) { 81 certificate := new(tls.Certificate) 82 83 cert, err := readFileOrString(c.CertFile, c.CertStr) 84 if err != nil { 85 return nil, newError("failed to parse certificate").Base(err) 86 } 87 certificate.Certificate = cert 88 89 if len(c.KeyFile) > 0 || len(c.KeyStr) > 0 { 90 key, err := readFileOrString(c.KeyFile, c.KeyStr) 91 if err != nil { 92 return nil, newError("failed to parse key").Base(err) 93 } 94 certificate.Key = key 95 } 96 97 switch strings.ToLower(c.Usage) { 98 case "encipherment": 99 certificate.Usage = tls.Certificate_ENCIPHERMENT 100 case "verify": 101 certificate.Usage = tls.Certificate_AUTHORITY_VERIFY 102 case "verifyclient": 103 certificate.Usage = tls.Certificate_AUTHORITY_VERIFY_CLIENT 104 case "issue": 105 certificate.Usage = tls.Certificate_AUTHORITY_ISSUE 106 default: 107 certificate.Usage = tls.Certificate_ENCIPHERMENT 108 } 109 110 return certificate, nil 111 } 112 113 func readFileOrString(f string, s []string) ([]byte, error) { 114 if len(f) > 0 { 115 return filesystem.ReadFile(f) 116 } 117 if len(s) > 0 { 118 return []byte(strings.Join(s, "\n")), nil 119 } 120 return nil, newError("both file and bytes are empty.") 121 } 122 123 type TLSEchSetting struct { 124 DnsAddr string `json:"dnsAddr"` 125 InitEchKey string `json:"initEchKey"` 126 } 127 128 func (c *TLSEchSetting) Build() (*tls.ECHSetting, error) { 129 setting := new(tls.ECHSetting) 130 131 setting.DnsAddr = c.DnsAddr 132 setting.InitEchKey = c.InitEchKey 133 134 return setting, nil 135 }