u_quic.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // Copyright 2023 The uTLS Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package tls
  5. import (
  6. "context"
  7. "errors"
  8. "fmt"
  9. )
  10. // A UQUICConn represents a connection which uses a QUIC implementation as the underlying
  11. // transport as described in RFC 9001.
  12. //
  13. // Methods of UQUICConn are not safe for concurrent use.
  14. type UQUICConn struct {
  15. conn *UConn
  16. sessionTicketSent bool
  17. }
  18. // QUICClient returns a new TLS client side connection using QUICTransport as the
  19. // underlying transport. The config cannot be nil.
  20. //
  21. // The config's MinVersion must be at least TLS 1.3.
  22. func UQUICClient(config *QUICConfig, clientHelloID ClientHelloID) *UQUICConn {
  23. return newUQUICConn(UClient(nil, config.TLSConfig, clientHelloID))
  24. }
  25. func newUQUICConn(uconn *UConn) *UQUICConn {
  26. uconn.quic = &quicState{
  27. signalc: make(chan struct{}),
  28. blockedc: make(chan struct{}),
  29. }
  30. uconn.quic.events = uconn.quic.eventArr[:0]
  31. return &UQUICConn{
  32. conn: uconn,
  33. }
  34. }
  35. // Start starts the client or server handshake protocol.
  36. // It may produce connection events, which may be read with NextEvent.
  37. //
  38. // Start must be called at most once.
  39. func (q *UQUICConn) Start(ctx context.Context) error {
  40. if q.conn.quic.started {
  41. return quicError(errors.New("tls: Start called more than once"))
  42. }
  43. q.conn.quic.started = true
  44. if q.conn.config.MinVersion < VersionTLS13 {
  45. return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.13"))
  46. }
  47. go q.conn.HandshakeContext(ctx)
  48. if _, ok := <-q.conn.quic.blockedc; !ok {
  49. return q.conn.handshakeErr
  50. }
  51. return nil
  52. }
  53. func (q *UQUICConn) ApplyPreset(p *ClientHelloSpec) error {
  54. return q.conn.ApplyPreset(p)
  55. }
  56. // NextEvent returns the next event occurring on the connection.
  57. // It returns an event with a Kind of QUICNoEvent when no events are available.
  58. func (q *UQUICConn) NextEvent() QUICEvent {
  59. qs := q.conn.quic
  60. if last := qs.nextEvent - 1; last >= 0 && len(qs.events[last].Data) > 0 {
  61. // Write over some of the previous event's data,
  62. // to catch callers erroniously retaining it.
  63. qs.events[last].Data[0] = 0
  64. }
  65. if qs.nextEvent >= len(qs.events) {
  66. qs.events = qs.events[:0]
  67. qs.nextEvent = 0
  68. return QUICEvent{Kind: QUICNoEvent}
  69. }
  70. e := qs.events[qs.nextEvent]
  71. qs.events[qs.nextEvent] = QUICEvent{} // zero out references to data
  72. qs.nextEvent++
  73. return e
  74. }
  75. // Close closes the connection and stops any in-progress handshake.
  76. func (q *UQUICConn) Close() error {
  77. if q.conn.quic.cancel == nil {
  78. return nil // never started
  79. }
  80. q.conn.quic.cancel()
  81. for range q.conn.quic.blockedc {
  82. // Wait for the handshake goroutine to return.
  83. }
  84. return q.conn.handshakeErr
  85. }
  86. // HandleData handles handshake bytes received from the peer.
  87. // It may produce connection events, which may be read with NextEvent.
  88. func (q *UQUICConn) HandleData(level QUICEncryptionLevel, data []byte) error {
  89. c := q.conn
  90. if c.in.level != level {
  91. return quicError(c.in.setErrorLocked(errors.New("tls: handshake data received at wrong level")))
  92. }
  93. c.quic.readbuf = data
  94. <-c.quic.signalc
  95. _, ok := <-c.quic.blockedc
  96. if ok {
  97. // The handshake goroutine is waiting for more data.
  98. return nil
  99. }
  100. // The handshake goroutine has exited.
  101. c.handshakeMutex.Lock()
  102. defer c.handshakeMutex.Unlock()
  103. c.hand.Write(c.quic.readbuf)
  104. c.quic.readbuf = nil
  105. for q.conn.hand.Len() >= 4 && q.conn.handshakeErr == nil {
  106. b := q.conn.hand.Bytes()
  107. n := int(b[1])<<16 | int(b[2])<<8 | int(b[3])
  108. if n > maxHandshake {
  109. q.conn.handshakeErr = fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)
  110. break
  111. }
  112. if len(b) < 4+n {
  113. return nil
  114. }
  115. if err := q.conn.handlePostHandshakeMessage(); err != nil {
  116. q.conn.handshakeErr = err
  117. }
  118. }
  119. if q.conn.handshakeErr != nil {
  120. return quicError(q.conn.handshakeErr)
  121. }
  122. return nil
  123. }
  124. // SendSessionTicket sends a session ticket to the client.
  125. // It produces connection events, which may be read with NextEvent.
  126. // Currently, it can only be called once.
  127. func (q *UQUICConn) SendSessionTicket(opts QUICSessionTicketOptions) error {
  128. c := q.conn
  129. if !c.isHandshakeComplete.Load() {
  130. return quicError(errors.New("tls: SendSessionTicket called before handshake completed"))
  131. }
  132. if c.isClient {
  133. return quicError(errors.New("tls: SendSessionTicket called on the client"))
  134. }
  135. if q.sessionTicketSent {
  136. return quicError(errors.New("tls: SendSessionTicket called multiple times"))
  137. }
  138. q.sessionTicketSent = true
  139. return quicError(c.sendSessionTicket(opts.EarlyData))
  140. }
  141. // ConnectionState returns basic TLS details about the connection.
  142. func (q *UQUICConn) ConnectionState() ConnectionState {
  143. return q.conn.ConnectionState()
  144. }
  145. // SetTransportParameters sets the transport parameters to send to the peer.
  146. //
  147. // Server connections may delay setting the transport parameters until after
  148. // receiving the client's transport parameters. See QUICTransportParametersRequired.
  149. func (q *UQUICConn) SetTransportParameters(params []byte) {
  150. if params == nil {
  151. params = []byte{}
  152. }
  153. q.conn.quic.transportParams = params // this won't be used for building ClientHello when using a preset
  154. // // instead, we set the transport parameters hold by the ClientHello
  155. // for _, ext := range q.conn.Extensions {
  156. // if qtp, ok := ext.(*QUICTransportParametersExtension); ok {
  157. // qtp.TransportParametersExtData = params
  158. // }
  159. // }
  160. if q.conn.quic.started {
  161. <-q.conn.quic.signalc
  162. <-q.conn.quic.blockedc
  163. }
  164. }
  165. func (uc *UConn) QUICSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
  166. uc.quic.events = append(uc.quic.events, QUICEvent{
  167. Kind: QUICSetReadSecret,
  168. Level: level,
  169. Suite: suite,
  170. Data: secret,
  171. })
  172. }
  173. func (uc *UConn) QUICSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
  174. uc.quic.events = append(uc.quic.events, QUICEvent{
  175. Kind: QUICSetWriteSecret,
  176. Level: level,
  177. Suite: suite,
  178. Data: secret,
  179. })
  180. }
  181. func (uc *UConn) QUICGetTransportParameters() ([]byte, error) {
  182. if uc.quic.transportParams == nil {
  183. uc.quic.events = append(uc.quic.events, QUICEvent{
  184. Kind: QUICTransportParametersRequired,
  185. })
  186. }
  187. for uc.quic.transportParams == nil {
  188. if err := uc.quicWaitForSignal(); err != nil {
  189. return nil, err
  190. }
  191. }
  192. return uc.quic.transportParams, nil
  193. }