tls.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package dialer
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "crypto/x509"
  6. "net"
  7. "net/netip"
  8. "os"
  9. C "github.com/sagernet/sing-box/constant"
  10. "github.com/sagernet/sing-box/option"
  11. E "github.com/sagernet/sing/common/exceptions"
  12. M "github.com/sagernet/sing/common/metadata"
  13. N "github.com/sagernet/sing/common/network"
  14. )
  15. type TLSDialer struct {
  16. dialer N.Dialer
  17. config *tls.Config
  18. }
  19. func NewTLS(dialer N.Dialer, serverAddress string, options option.OutboundTLSOptions) (N.Dialer, error) {
  20. if !options.Enabled {
  21. return dialer, nil
  22. }
  23. var serverName string
  24. if options.ServerName != "" {
  25. serverName = options.ServerName
  26. } else if serverAddress != "" {
  27. if _, err := netip.ParseAddr(serverName); err != nil {
  28. serverName = serverAddress
  29. }
  30. }
  31. if serverName == "" && options.Insecure {
  32. return nil, E.New("missing server_name or insecure=true")
  33. }
  34. var tlsConfig tls.Config
  35. if options.DisableSNI {
  36. tlsConfig.ServerName = "127.0.0.1"
  37. } else {
  38. tlsConfig.ServerName = serverName
  39. }
  40. if options.Insecure {
  41. tlsConfig.InsecureSkipVerify = options.Insecure
  42. } else if options.DisableSNI {
  43. tlsConfig.InsecureSkipVerify = true
  44. tlsConfig.VerifyConnection = func(state tls.ConnectionState) error {
  45. verifyOptions := x509.VerifyOptions{
  46. DNSName: serverName,
  47. Intermediates: x509.NewCertPool(),
  48. }
  49. for _, cert := range state.PeerCertificates[1:] {
  50. verifyOptions.Intermediates.AddCert(cert)
  51. }
  52. _, err := state.PeerCertificates[0].Verify(verifyOptions)
  53. return err
  54. }
  55. }
  56. return &TLSDialer{
  57. dialer: dialer,
  58. config: &tlsConfig,
  59. }, nil
  60. }
  61. func (d *TLSDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  62. if network != C.NetworkTCP {
  63. return nil, os.ErrInvalid
  64. }
  65. conn, err := d.dialer.DialContext(ctx, network, destination)
  66. if err != nil {
  67. return nil, err
  68. }
  69. tlsConn := tls.Client(conn, d.config)
  70. ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTCPTimeout)
  71. defer cancel()
  72. err = tlsConn.HandshakeContext(ctx)
  73. return tlsConn, err
  74. }
  75. func (d *TLSDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  76. return nil, os.ErrInvalid
  77. }