package inbound import ( "crypto/tls" "os" "github.com/sagernet/sing-box/option" E "github.com/sagernet/sing/common/exceptions" ) func NewTLSConfig(options option.InboundTLSOptions) (*tls.Config, error) { if !options.Enabled { return nil, nil } var tlsConfig tls.Config if options.ServerName != "" { tlsConfig.ServerName = options.ServerName } if len(options.ALPN) > 0 { tlsConfig.NextProtos = options.ALPN } if options.MinVersion != "" { minVersion, err := option.ParseTLSVersion(options.MinVersion) if err != nil { return nil, E.Cause(err, "parse min_version") } tlsConfig.MinVersion = minVersion } if options.MaxVersion != "" { maxVersion, err := option.ParseTLSVersion(options.MaxVersion) if err != nil { return nil, E.Cause(err, "parse max_version") } tlsConfig.MaxVersion = maxVersion } if options.CipherSuites != nil { find: for _, cipherSuite := range options.CipherSuites { for _, tlsCipherSuite := range tls.CipherSuites() { if cipherSuite == tlsCipherSuite.Name { tlsConfig.CipherSuites = append(tlsConfig.CipherSuites, tlsCipherSuite.ID) continue find } } return nil, E.New("unknown cipher_suite: ", cipherSuite) } } var certificate []byte if options.Certificate != "" { certificate = []byte(options.Certificate) } else if options.CertificatePath != "" { content, err := os.ReadFile(options.CertificatePath) if err != nil { return nil, E.Cause(err, "read certificate") } certificate = content } var key []byte if options.Key != "" { key = []byte(options.Key) } else if options.KeyPath != "" { content, err := os.ReadFile(options.KeyPath) if err != nil { return nil, E.Cause(err, "read key") } key = content } if certificate == nil { return nil, E.New("missing certificate") } if key == nil { return nil, E.New("missing key") } keyPair, err := tls.X509KeyPair(certificate, key) if err != nil { return nil, E.Cause(err, "parse x509 key pair") } tlsConfig.Certificates = []tls.Certificate{keyPair} return &tlsConfig, nil }