tls.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package vmess
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "errors"
  6. "net"
  7. "github.com/metacubex/mihomo/component/ca"
  8. tlsC "github.com/metacubex/mihomo/component/tls"
  9. )
  10. type TLSConfig struct {
  11. Host string
  12. SkipCertVerify bool
  13. FingerPrint string
  14. ClientFingerprint string
  15. NextProtos []string
  16. Reality *tlsC.RealityConfig
  17. }
  18. func StreamTLSConn(ctx context.Context, conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
  19. tlsConfig := &tls.Config{
  20. ServerName: cfg.Host,
  21. InsecureSkipVerify: cfg.SkipCertVerify,
  22. NextProtos: cfg.NextProtos,
  23. }
  24. var err error
  25. tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, cfg.FingerPrint)
  26. if err != nil {
  27. return nil, err
  28. }
  29. if len(cfg.ClientFingerprint) != 0 {
  30. if cfg.Reality == nil {
  31. utlsConn, valid := GetUTLSConn(conn, cfg.ClientFingerprint, tlsConfig)
  32. if valid {
  33. err := utlsConn.(*tlsC.UConn).HandshakeContext(ctx)
  34. return utlsConn, err
  35. }
  36. } else {
  37. return tlsC.GetRealityConn(ctx, conn, cfg.ClientFingerprint, tlsConfig, cfg.Reality)
  38. }
  39. }
  40. if cfg.Reality != nil {
  41. return nil, errors.New("REALITY is based on uTLS, please set a client-fingerprint")
  42. }
  43. tlsConn := tls.Client(conn, tlsConfig)
  44. err = tlsConn.HandshakeContext(ctx)
  45. return tlsConn, err
  46. }
  47. func GetUTLSConn(conn net.Conn, ClientFingerprint string, tlsConfig *tls.Config) (net.Conn, bool) {
  48. if fingerprint, exists := tlsC.GetFingerprint(ClientFingerprint); exists {
  49. utlsConn := tlsC.UClient(conn, tlsConfig, fingerprint)
  50. return utlsConn, true
  51. }
  52. return nil, false
  53. }