tls.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package option
  2. import (
  3. "crypto/tls"
  4. "encoding/json"
  5. "strings"
  6. E "github.com/sagernet/sing/common/exceptions"
  7. "github.com/sagernet/sing/common/json/badoption"
  8. )
  9. type InboundTLSOptions struct {
  10. Enabled bool `json:"enabled,omitempty"`
  11. ServerName string `json:"server_name,omitempty"`
  12. Insecure bool `json:"insecure,omitempty"`
  13. ALPN badoption.Listable[string] `json:"alpn,omitempty"`
  14. MinVersion string `json:"min_version,omitempty"`
  15. MaxVersion string `json:"max_version,omitempty"`
  16. CipherSuites badoption.Listable[string] `json:"cipher_suites,omitempty"`
  17. CurvePreferences badoption.Listable[CurvePreference] `json:"curve_preferences,omitempty"`
  18. Certificate badoption.Listable[string] `json:"certificate,omitempty"`
  19. CertificatePath string `json:"certificate_path,omitempty"`
  20. ClientAuthentication ClientAuthType `json:"client_authentication,omitempty"`
  21. ClientCertificate badoption.Listable[string] `json:"client_certificate,omitempty"`
  22. ClientCertificatePath badoption.Listable[string] `json:"client_certificate_path,omitempty"`
  23. ClientCertificatePublicKeySHA256 badoption.Listable[[]byte] `json:"client_certificate_public_key_sha256,omitempty"`
  24. Key badoption.Listable[string] `json:"key,omitempty"`
  25. KeyPath string `json:"key_path,omitempty"`
  26. KernelTx bool `json:"kernel_tx,omitempty"`
  27. KernelRx bool `json:"kernel_rx,omitempty"`
  28. HandshakeTimeout badoption.Duration `json:"handshake_timeout,omitempty"`
  29. CertificateProvider *CertificateProviderOptions `json:"certificate_provider,omitempty"`
  30. // Deprecated: use certificate_provider
  31. ACME *InboundACMEOptions `json:"acme,omitempty"`
  32. ECH *InboundECHOptions `json:"ech,omitempty"`
  33. Reality *InboundRealityOptions `json:"reality,omitempty"`
  34. }
  35. type ClientAuthType tls.ClientAuthType
  36. func (t ClientAuthType) MarshalJSON() ([]byte, error) {
  37. var stringValue string
  38. switch t {
  39. case ClientAuthType(tls.NoClientCert):
  40. stringValue = "no"
  41. case ClientAuthType(tls.RequestClientCert):
  42. stringValue = "request"
  43. case ClientAuthType(tls.RequireAnyClientCert):
  44. stringValue = "require-any"
  45. case ClientAuthType(tls.VerifyClientCertIfGiven):
  46. stringValue = "verify-if-given"
  47. case ClientAuthType(tls.RequireAndVerifyClientCert):
  48. stringValue = "require-and-verify"
  49. default:
  50. return nil, E.New("unknown client authentication type: ", int(t))
  51. }
  52. return json.Marshal(stringValue)
  53. }
  54. func (t *ClientAuthType) UnmarshalJSON(data []byte) error {
  55. var stringValue string
  56. err := json.Unmarshal(data, &stringValue)
  57. if err != nil {
  58. return err
  59. }
  60. switch stringValue {
  61. case "no":
  62. *t = ClientAuthType(tls.NoClientCert)
  63. case "request":
  64. *t = ClientAuthType(tls.RequestClientCert)
  65. case "require-any":
  66. *t = ClientAuthType(tls.RequireAnyClientCert)
  67. case "verify-if-given":
  68. *t = ClientAuthType(tls.VerifyClientCertIfGiven)
  69. case "require-and-verify":
  70. *t = ClientAuthType(tls.RequireAndVerifyClientCert)
  71. default:
  72. return E.New("unknown client authentication type: ", stringValue)
  73. }
  74. return nil
  75. }
  76. type InboundTLSOptionsContainer struct {
  77. TLS *InboundTLSOptions `json:"tls,omitempty"`
  78. }
  79. type InboundTLSOptionsWrapper interface {
  80. TakeInboundTLSOptions() *InboundTLSOptions
  81. ReplaceInboundTLSOptions(options *InboundTLSOptions)
  82. }
  83. func (o *InboundTLSOptionsContainer) TakeInboundTLSOptions() *InboundTLSOptions {
  84. return o.TLS
  85. }
  86. func (o *InboundTLSOptionsContainer) ReplaceInboundTLSOptions(options *InboundTLSOptions) {
  87. o.TLS = options
  88. }
  89. type OutboundTLSOptions struct {
  90. Enabled bool `json:"enabled,omitempty"`
  91. Engine string `json:"engine,omitempty"`
  92. DisableSNI bool `json:"disable_sni,omitempty"`
  93. ServerName string `json:"server_name,omitempty"`
  94. Insecure bool `json:"insecure,omitempty"`
  95. ALPN badoption.Listable[string] `json:"alpn,omitempty"`
  96. MinVersion string `json:"min_version,omitempty"`
  97. MaxVersion string `json:"max_version,omitempty"`
  98. CipherSuites badoption.Listable[string] `json:"cipher_suites,omitempty"`
  99. CurvePreferences badoption.Listable[CurvePreference] `json:"curve_preferences,omitempty"`
  100. Certificate badoption.Listable[string] `json:"certificate,omitempty"`
  101. CertificatePath string `json:"certificate_path,omitempty"`
  102. CertificatePublicKeySHA256 badoption.Listable[[]byte] `json:"certificate_public_key_sha256,omitempty"`
  103. ClientCertificate badoption.Listable[string] `json:"client_certificate,omitempty"`
  104. ClientCertificatePath string `json:"client_certificate_path,omitempty"`
  105. ClientKey badoption.Listable[string] `json:"client_key,omitempty"`
  106. ClientKeyPath string `json:"client_key_path,omitempty"`
  107. Fragment bool `json:"fragment,omitempty"`
  108. FragmentFallbackDelay badoption.Duration `json:"fragment_fallback_delay,omitempty"`
  109. RecordFragment bool `json:"record_fragment,omitempty"`
  110. Spoof string `json:"spoof,omitempty"`
  111. SpoofMethod string `json:"spoof_method,omitempty"`
  112. KernelTx bool `json:"kernel_tx,omitempty"`
  113. KernelRx bool `json:"kernel_rx,omitempty"`
  114. HandshakeTimeout badoption.Duration `json:"handshake_timeout,omitempty"`
  115. ECH *OutboundECHOptions `json:"ech,omitempty"`
  116. UTLS *OutboundUTLSOptions `json:"utls,omitempty"`
  117. Reality *OutboundRealityOptions `json:"reality,omitempty"`
  118. }
  119. type OutboundTLSOptionsContainer struct {
  120. TLS *OutboundTLSOptions `json:"tls,omitempty"`
  121. }
  122. type OutboundTLSOptionsWrapper interface {
  123. TakeOutboundTLSOptions() *OutboundTLSOptions
  124. ReplaceOutboundTLSOptions(options *OutboundTLSOptions)
  125. }
  126. func (o *OutboundTLSOptionsContainer) TakeOutboundTLSOptions() *OutboundTLSOptions {
  127. return o.TLS
  128. }
  129. func (o *OutboundTLSOptionsContainer) ReplaceOutboundTLSOptions(options *OutboundTLSOptions) {
  130. o.TLS = options
  131. }
  132. type CurvePreference tls.CurveID
  133. const (
  134. CurveP256 = 23
  135. CurveP384 = 24
  136. CurveP521 = 25
  137. X25519 = 29
  138. X25519MLKEM768 = 4588
  139. )
  140. func (c CurvePreference) MarshalJSON() ([]byte, error) {
  141. var stringValue string
  142. switch c {
  143. case CurvePreference(CurveP256):
  144. stringValue = "P256"
  145. case CurvePreference(CurveP384):
  146. stringValue = "P384"
  147. case CurvePreference(CurveP521):
  148. stringValue = "P521"
  149. case CurvePreference(X25519):
  150. stringValue = "X25519"
  151. case CurvePreference(X25519MLKEM768):
  152. stringValue = "X25519MLKEM768"
  153. default:
  154. return nil, E.New("unknown curve id: ", int(c))
  155. }
  156. return json.Marshal(stringValue)
  157. }
  158. func (c *CurvePreference) UnmarshalJSON(data []byte) error {
  159. var stringValue string
  160. err := json.Unmarshal(data, &stringValue)
  161. if err != nil {
  162. return err
  163. }
  164. switch strings.ToUpper(stringValue) {
  165. case "P256":
  166. *c = CurvePreference(CurveP256)
  167. case "P384":
  168. *c = CurvePreference(CurveP384)
  169. case "P521":
  170. *c = CurvePreference(CurveP521)
  171. case "X25519":
  172. *c = CurvePreference(X25519)
  173. case "X25519MLKEM768":
  174. *c = CurvePreference(X25519MLKEM768)
  175. default:
  176. return E.New("unknown curve name: ", stringValue)
  177. }
  178. return nil
  179. }
  180. type InboundRealityOptions struct {
  181. Enabled bool `json:"enabled,omitempty"`
  182. Handshake InboundRealityHandshakeOptions `json:"handshake,omitempty"`
  183. PrivateKey string `json:"private_key,omitempty"`
  184. ShortID badoption.Listable[string] `json:"short_id,omitempty"`
  185. MaxTimeDifference badoption.Duration `json:"max_time_difference,omitempty"`
  186. }
  187. type InboundRealityHandshakeOptions struct {
  188. ServerOptions
  189. DialerOptions
  190. }
  191. type InboundECHOptions struct {
  192. Enabled bool `json:"enabled,omitempty"`
  193. Key badoption.Listable[string] `json:"key,omitempty"`
  194. KeyPath string `json:"key_path,omitempty"`
  195. // Deprecated: not supported by stdlib
  196. PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"`
  197. // Deprecated: added by fault
  198. DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"`
  199. }
  200. type OutboundECHOptions struct {
  201. Enabled bool `json:"enabled,omitempty"`
  202. Config badoption.Listable[string] `json:"config,omitempty"`
  203. ConfigPath string `json:"config_path,omitempty"`
  204. QueryServerName string `json:"query_server_name,omitempty"`
  205. // Deprecated: not supported by stdlib
  206. PQSignatureSchemesEnabled bool `json:"pq_signature_schemes_enabled,omitempty"`
  207. // Deprecated: added by fault
  208. DynamicRecordSizingDisabled bool `json:"dynamic_record_sizing_disabled,omitempty"`
  209. }
  210. type OutboundUTLSOptions struct {
  211. Enabled bool `json:"enabled,omitempty"`
  212. Fingerprint string `json:"fingerprint,omitempty"`
  213. }
  214. type OutboundRealityOptions struct {
  215. Enabled bool `json:"enabled,omitempty"`
  216. PublicKey string `json:"public_key,omitempty"`
  217. ShortID string `json:"short_id,omitempty"`
  218. }