tls_cf.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // Copyright 2021 Cloudflare, Inc. All rights reserved. Use of this source code
  2. // is governed by a BSD-style license that can be found in the LICENSE file.
  3. package tls
  4. import (
  5. "time"
  6. circlPki "github.com/cloudflare/circl/pki"
  7. circlSign "github.com/cloudflare/circl/sign"
  8. "github.com/cloudflare/circl/sign/eddilithium3"
  9. )
  10. const (
  11. // Constants for ECH status events.
  12. echStatusBypassed = 1 + iota
  13. echStatusInner
  14. echStatusOuter
  15. )
  16. // To add a signature scheme from Circl
  17. //
  18. // 1. make sure it implements TLSScheme and CertificateScheme,
  19. // 2. follow the instructions in crypto/x509/x509_cf.go
  20. // 3. add a signature<NameOfAlg> to the iota in common.go
  21. // 4. add row in the circlSchemes lists below
  22. var circlSchemes = [...]struct {
  23. sigType uint8
  24. scheme circlSign.Scheme
  25. }{
  26. {signatureEdDilithium3, eddilithium3.Scheme()},
  27. }
  28. func circlSchemeBySigType(sigType uint8) circlSign.Scheme {
  29. for _, cs := range circlSchemes {
  30. if cs.sigType == sigType {
  31. return cs.scheme
  32. }
  33. }
  34. return nil
  35. }
  36. func sigTypeByCirclScheme(scheme circlSign.Scheme) uint8 {
  37. for _, cs := range circlSchemes {
  38. if cs.scheme == scheme {
  39. return cs.sigType
  40. }
  41. }
  42. return 0
  43. }
  44. var supportedSignatureAlgorithmsWithCircl []SignatureScheme
  45. // supportedSignatureAlgorithms returns enabled signature schemes. PQ signature
  46. // schemes are only included when tls.Config#PQSignatureSchemesEnabled is set.
  47. func (c *Config) supportedSignatureAlgorithms() []SignatureScheme {
  48. if c != nil && c.PQSignatureSchemesEnabled {
  49. return supportedSignatureAlgorithmsWithCircl
  50. }
  51. return supportedSignatureAlgorithms
  52. }
  53. func init() {
  54. supportedSignatureAlgorithmsWithCircl = append([]SignatureScheme{}, supportedSignatureAlgorithms...)
  55. for _, cs := range circlSchemes {
  56. supportedSignatureAlgorithmsWithCircl = append(supportedSignatureAlgorithmsWithCircl,
  57. SignatureScheme(cs.scheme.(circlPki.TLSScheme).TLSIdentifier()))
  58. }
  59. }
  60. // CFEvent is a value emitted at various points in the handshake that is
  61. // handled by the callback Config.CFEventHandler.
  62. type CFEvent interface {
  63. Name() string
  64. }
  65. // CFEventTLS13ClientHandshakeTimingInfo carries intra-stack time durations for
  66. // TLS 1.3 client-state machine changes. It can be used for tracking metrics
  67. // during a connection. Some durations may be sensitive, such as the amount of
  68. // time to process a particular handshake message, so this event should only be
  69. // used for experimental purposes.
  70. type CFEventTLS13ClientHandshakeTimingInfo struct {
  71. timer func() time.Time
  72. start time.Time
  73. WriteClientHello time.Duration
  74. ProcessServerHello time.Duration
  75. ReadEncryptedExtensions time.Duration
  76. ReadCertificate time.Duration
  77. ReadCertificateVerify time.Duration
  78. ReadServerFinished time.Duration
  79. WriteCertificate time.Duration
  80. WriteCertificateVerify time.Duration
  81. WriteClientFinished time.Duration
  82. }
  83. // Name is required by the CFEvent interface.
  84. func (e CFEventTLS13ClientHandshakeTimingInfo) Name() string {
  85. return "TLS13ClientHandshakeTimingInfo"
  86. }
  87. func (e CFEventTLS13ClientHandshakeTimingInfo) elapsedTime() time.Duration {
  88. if e.timer == nil {
  89. return 0
  90. }
  91. return e.timer().Sub(e.start)
  92. }
  93. func createTLS13ClientHandshakeTimingInfo(timerFunc func() time.Time) CFEventTLS13ClientHandshakeTimingInfo {
  94. timer := time.Now
  95. if timerFunc != nil {
  96. timer = timerFunc
  97. }
  98. return CFEventTLS13ClientHandshakeTimingInfo{
  99. timer: timer,
  100. start: timer(),
  101. }
  102. }
  103. // CFEventTLS13ServerHandshakeTimingInfo carries intra-stack time durations
  104. // for TLS 1.3 state machine changes. It can be used for tracking metrics during a
  105. // connection. Some durations may be sensitive, such as the amount of time to
  106. // process a particular handshake message, so this event should only be used
  107. // for experimental purposes.
  108. type CFEventTLS13ServerHandshakeTimingInfo struct {
  109. timer func() time.Time
  110. start time.Time
  111. ProcessClientHello time.Duration
  112. WriteServerHello time.Duration
  113. WriteEncryptedExtensions time.Duration
  114. WriteCertificate time.Duration
  115. WriteCertificateVerify time.Duration
  116. WriteServerFinished time.Duration
  117. ReadCertificate time.Duration
  118. ReadCertificateVerify time.Duration
  119. ReadClientFinished time.Duration
  120. }
  121. // Name is required by the CFEvent interface.
  122. func (e CFEventTLS13ServerHandshakeTimingInfo) Name() string {
  123. return "TLS13ServerHandshakeTimingInfo"
  124. }
  125. func (e CFEventTLS13ServerHandshakeTimingInfo) elapsedTime() time.Duration {
  126. if e.timer == nil {
  127. return 0
  128. }
  129. return e.timer().Sub(e.start)
  130. }
  131. func createTLS13ServerHandshakeTimingInfo(timerFunc func() time.Time) CFEventTLS13ServerHandshakeTimingInfo {
  132. timer := time.Now
  133. if timerFunc != nil {
  134. timer = timerFunc
  135. }
  136. return CFEventTLS13ServerHandshakeTimingInfo{
  137. timer: timer,
  138. start: timer(),
  139. }
  140. }
  141. // CFEventECHClientStatus is emitted once it is known whether the client
  142. // bypassed, offered, or greased ECH.
  143. type CFEventECHClientStatus int
  144. // Bypassed returns true if the client bypassed ECH.
  145. func (e CFEventECHClientStatus) Bypassed() bool {
  146. return e == echStatusBypassed
  147. }
  148. // Offered returns true if the client offered ECH.
  149. func (e CFEventECHClientStatus) Offered() bool {
  150. return e == echStatusInner
  151. }
  152. // Greased returns true if the client greased ECH.
  153. func (e CFEventECHClientStatus) Greased() bool {
  154. return e == echStatusOuter
  155. }
  156. // Name is required by the CFEvent interface.
  157. func (e CFEventECHClientStatus) Name() string {
  158. return "ech client status"
  159. }
  160. // CFEventECHServerStatus is emitted once it is known whether the client
  161. // bypassed, offered, or greased ECH.
  162. type CFEventECHServerStatus int
  163. // Bypassed returns true if the client bypassed ECH.
  164. func (e CFEventECHServerStatus) Bypassed() bool {
  165. return e == echStatusBypassed
  166. }
  167. // Accepted returns true if the client offered ECH.
  168. func (e CFEventECHServerStatus) Accepted() bool {
  169. return e == echStatusInner
  170. }
  171. // Rejected returns true if the client greased ECH.
  172. func (e CFEventECHServerStatus) Rejected() bool {
  173. return e == echStatusOuter
  174. }
  175. // Name is required by the CFEvent interface.
  176. func (e CFEventECHServerStatus) Name() string {
  177. return "ech server status"
  178. }
  179. // CFEventECHPublicNameMismatch is emitted if the outer SNI does not match
  180. // match the public name of the ECH configuration. Note that we do not record
  181. // the outer SNI in order to avoid collecting this potentially sensitive data.
  182. type CFEventECHPublicNameMismatch struct{}
  183. // Name is required by the CFEvent interface.
  184. func (e CFEventECHPublicNameMismatch) Name() string {
  185. return "ech public name does not match outer sni"
  186. }
  187. // For backwards compatibility.
  188. type CFEventTLS13NegotiatedKEX = CFEventTLSNegotiatedNamedKEX
  189. // CFEventTLSNegotiatedNamedKEX is emitted when a key agreement mechanism has been
  190. // established that uses a named group. This includes all key agreements
  191. // in TLSv1.3, but excludes RSA and DH in TLS 1.2 and earlier.
  192. type CFEventTLSNegotiatedNamedKEX struct {
  193. KEX CurveID
  194. }
  195. func (e CFEventTLSNegotiatedNamedKEX) Name() string {
  196. return "CFEventTLSNegotiatedNamedKEX"
  197. }
  198. // CFEventTLS13HRR is emitted when a HRR is sent or received
  199. type CFEventTLS13HRR struct{}
  200. func (e CFEventTLS13HRR) Name() string {
  201. return "CFEventTLS13HRR"
  202. }