tls.go 9.6 KB

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