ktls_read.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // Copyright 2009 The Go 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. //go:build linux && go1.25 && badlinkname
  5. package ktls
  6. import (
  7. "bytes"
  8. "crypto/tls"
  9. "fmt"
  10. "io"
  11. "net"
  12. "unsafe"
  13. )
  14. func (c *Conn) Read(b []byte) (int, error) {
  15. if !c.kernelRx {
  16. return c.Conn.Read(b)
  17. }
  18. if len(b) == 0 {
  19. // Put this after Handshake, in case people were calling
  20. // Read(nil) for the side effect of the Handshake.
  21. return 0, nil
  22. }
  23. c.rawConn.In.Lock()
  24. defer c.rawConn.In.Unlock()
  25. for c.rawConn.Input.Len() == 0 {
  26. if err := c.readRecord(); err != nil {
  27. return 0, err
  28. }
  29. for c.rawConn.Hand.Len() > 0 {
  30. if err := c.handlePostHandshakeMessage(); err != nil {
  31. return 0, err
  32. }
  33. }
  34. }
  35. n, _ := c.rawConn.Input.Read(b)
  36. // If a close-notify alert is waiting, read it so that we can return (n,
  37. // EOF) instead of (n, nil), to signal to the HTTP response reading
  38. // goroutine that the connection is now closed. This eliminates a race
  39. // where the HTTP response reading goroutine would otherwise not observe
  40. // the EOF until its next read, by which time a client goroutine might
  41. // have already tried to reuse the HTTP connection for a new request.
  42. // See https://golang.org/cl/76400046 and https://golang.org/issue/3514
  43. if n != 0 && c.rawConn.Input.Len() == 0 && c.rawConn.RawInput.Len() > 0 &&
  44. c.rawConn.RawInput.Bytes()[0] == recordTypeAlert {
  45. if err := c.readRecord(); err != nil {
  46. return n, err // will be io.EOF on closeNotify
  47. }
  48. }
  49. return n, nil
  50. }
  51. func (c *Conn) readRecord() error {
  52. if *c.rawConn.In.Err != nil {
  53. return *c.rawConn.In.Err
  54. }
  55. typ, data, err := c.readRawRecord()
  56. if err != nil {
  57. return err
  58. }
  59. if len(data) > maxPlaintext {
  60. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertRecordOverflow))
  61. }
  62. // Application Data messages are always protected.
  63. if c.rawConn.In.Cipher == nil && typ == recordTypeApplicationData {
  64. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertUnexpectedMessage))
  65. }
  66. //if typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 {
  67. // This is a state-advancing message: reset the retry count.
  68. // c.retryCount = 0
  69. //}
  70. // Handshake messages MUST NOT be interleaved with other record types in TLS 1.3.
  71. if *c.rawConn.Vers == tls.VersionTLS13 && typ != recordTypeHandshake && c.rawConn.Hand.Len() > 0 {
  72. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertUnexpectedMessage))
  73. }
  74. switch typ {
  75. default:
  76. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertUnexpectedMessage))
  77. case recordTypeAlert:
  78. //if c.quic != nil {
  79. // return c.rawConn.In.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
  80. //}
  81. if len(data) != 2 {
  82. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertUnexpectedMessage))
  83. }
  84. if data[1] == alertCloseNotify {
  85. return c.rawConn.In.SetErrorLocked(io.EOF)
  86. }
  87. if *c.rawConn.Vers == tls.VersionTLS13 {
  88. // TLS 1.3 removed warning-level alerts except for alertUserCanceled
  89. // (RFC 8446, § 6.1). Since at least one major implementation
  90. // (https://bugs.openjdk.org/browse/JDK-8323517) misuses this alert,
  91. // many TLS stacks now ignore it outright when seen in a TLS 1.3
  92. // handshake (e.g. BoringSSL, NSS, Rustls).
  93. if data[1] == alertUserCanceled {
  94. // Like TLS 1.2 alertLevelWarning alerts, we drop the record and retry.
  95. return c.retryReadRecord( /*expectChangeCipherSpec*/ )
  96. }
  97. return c.rawConn.In.SetErrorLocked(&net.OpError{Op: "remote error", Err: tls.AlertError(data[1])})
  98. }
  99. switch data[0] {
  100. case alertLevelWarning:
  101. // Drop the record on the floor and retry.
  102. return c.retryReadRecord( /*expectChangeCipherSpec*/ )
  103. case alertLevelError:
  104. return c.rawConn.In.SetErrorLocked(&net.OpError{Op: "remote error", Err: tls.AlertError(data[1])})
  105. default:
  106. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertUnexpectedMessage))
  107. }
  108. case recordTypeChangeCipherSpec:
  109. if len(data) != 1 || data[0] != 1 {
  110. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertDecodeError))
  111. }
  112. // Handshake messages are not allowed to fragment across the CCS.
  113. if c.rawConn.Hand.Len() > 0 {
  114. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertUnexpectedMessage))
  115. }
  116. // In TLS 1.3, change_cipher_spec records are ignored until the
  117. // Finished. See RFC 8446, Appendix D.4. Note that according to Section
  118. // 5, a server can send a ChangeCipherSpec before its ServerHello, when
  119. // c.vers is still unset. That's not useful though and suspicious if the
  120. // server then selects a lower protocol version, so don't allow that.
  121. if *c.rawConn.Vers == tls.VersionTLS13 {
  122. return c.retryReadRecord( /*expectChangeCipherSpec*/ )
  123. }
  124. // if !expectChangeCipherSpec {
  125. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertUnexpectedMessage))
  126. //}
  127. //if err := c.rawConn.In.changeCipherSpec(); err != nil {
  128. // return c.rawConn.In.setErrorLocked(c.sendAlert(err.(alert)))
  129. //}
  130. case recordTypeApplicationData:
  131. // Some OpenSSL servers send empty records in order to randomize the
  132. // CBC RawIV. Ignore a limited number of empty records.
  133. if len(data) == 0 {
  134. return c.retryReadRecord( /*expectChangeCipherSpec*/ )
  135. }
  136. // Note that data is owned by c.rawInput, following the Next call above,
  137. // to avoid copying the plaintext. This is safe because c.rawInput is
  138. // not read from or written to until c.input is drained.
  139. c.rawConn.Input.Reset(data)
  140. case recordTypeHandshake:
  141. if len(data) == 0 {
  142. return c.rawConn.In.SetErrorLocked(c.sendAlert(alertUnexpectedMessage))
  143. }
  144. c.rawConn.Hand.Write(data)
  145. }
  146. return nil
  147. }
  148. //nolint:staticcheck
  149. func (c *Conn) readRawRecord() (typ uint8, data []byte, err error) {
  150. // Read from kernel.
  151. if c.kernelRx {
  152. return c.readKernelRecord()
  153. }
  154. // Read header, payload.
  155. if err = c.readFromUntil(c.conn, recordHeaderLen); err != nil {
  156. // RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify
  157. // is an error, but popular web sites seem to do this, so we accept it
  158. // if and only if at the record boundary.
  159. if err == io.ErrUnexpectedEOF && c.rawConn.RawInput.Len() == 0 {
  160. err = io.EOF
  161. }
  162. if e, ok := err.(net.Error); !ok || !e.Temporary() {
  163. c.rawConn.In.SetErrorLocked(err)
  164. }
  165. return
  166. }
  167. hdr := c.rawConn.RawInput.Bytes()[:recordHeaderLen]
  168. typ = hdr[0]
  169. vers := uint16(hdr[1])<<8 | uint16(hdr[2])
  170. expectedVers := *c.rawConn.Vers
  171. if expectedVers == tls.VersionTLS13 {
  172. // All TLS 1.3 records are expected to have 0x0303 (1.2) after
  173. // the initial hello (RFC 8446 Section 5.1).
  174. expectedVers = tls.VersionTLS12
  175. }
  176. n := int(hdr[3])<<8 | int(hdr[4])
  177. if /*c.haveVers && */ vers != expectedVers {
  178. c.sendAlert(alertProtocolVersion)
  179. msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, expectedVers)
  180. err = c.rawConn.In.SetErrorLocked(c.newRecordHeaderError(nil, msg))
  181. return
  182. }
  183. //if !c.haveVers {
  184. // // First message, be extra suspicious: this might not be a TLS
  185. // // client. Bail out before reading a full 'body', if possible.
  186. // // The current max version is 3.3 so if the version is >= 16.0,
  187. // // it's probably not real.
  188. // if (typ != recordTypeAlert && typ != recordTypeHandshake) || vers >= 0x1000 {
  189. // err = c.rawConn.In.SetErrorLocked(c.newRecordHeaderError(c.conn, "first record does not look like a TLS handshake"))
  190. // return
  191. // }
  192. //}
  193. if *c.rawConn.Vers == tls.VersionTLS13 && n > maxCiphertextTLS13 || n > maxCiphertext {
  194. c.sendAlert(alertRecordOverflow)
  195. msg := fmt.Sprintf("oversized record received with length %d", n)
  196. err = c.rawConn.In.SetErrorLocked(c.newRecordHeaderError(nil, msg))
  197. return
  198. }
  199. if err = c.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
  200. if e, ok := err.(net.Error); !ok || !e.Temporary() {
  201. c.rawConn.In.SetErrorLocked(err)
  202. }
  203. return
  204. }
  205. // Process message.
  206. record := c.rawConn.RawInput.Next(recordHeaderLen + n)
  207. data, typ, err = c.rawConn.In.Decrypt(record)
  208. if err != nil {
  209. err = c.rawConn.In.SetErrorLocked(c.sendAlert(*(*uint8)((*[2]unsafe.Pointer)(unsafe.Pointer(&err))[1])))
  210. return
  211. }
  212. return
  213. }
  214. // retryReadRecord recurs into readRecordOrCCS to drop a non-advancing record, like
  215. // a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3.
  216. func (c *Conn) retryReadRecord( /*expectChangeCipherSpec bool*/ ) error {
  217. //c.retryCount++
  218. //if c.retryCount > maxUselessRecords {
  219. // c.sendAlert(alertUnexpectedMessage)
  220. // return c.in.setErrorLocked(errors.New("tls: too many ignored records"))
  221. //}
  222. return c.readRecord( /*expectChangeCipherSpec*/ )
  223. }
  224. // atLeastReader reads from R, stopping with EOF once at least N bytes have been
  225. // read. It is different from an io.LimitedReader in that it doesn't cut short
  226. // the last Read call, and in that it considers an early EOF an error.
  227. type atLeastReader struct {
  228. R io.Reader
  229. N int64
  230. }
  231. func (r *atLeastReader) Read(p []byte) (int, error) {
  232. if r.N <= 0 {
  233. return 0, io.EOF
  234. }
  235. n, err := r.R.Read(p)
  236. r.N -= int64(n) // won't underflow unless len(p) >= n > 9223372036854775809
  237. if r.N > 0 && err == io.EOF {
  238. return n, io.ErrUnexpectedEOF
  239. }
  240. if r.N <= 0 && err == nil {
  241. return n, io.EOF
  242. }
  243. return n, err
  244. }
  245. // readFromUntil reads from r into c.rawConn.RawInput until c.rawConn.RawInput contains
  246. // at least n bytes or else returns an error.
  247. func (c *Conn) readFromUntil(r io.Reader, n int) error {
  248. if c.rawConn.RawInput.Len() >= n {
  249. return nil
  250. }
  251. needs := n - c.rawConn.RawInput.Len()
  252. // There might be extra input waiting on the wire. Make a best effort
  253. // attempt to fetch it so that it can be used in (*Conn).Read to
  254. // "predict" closeNotify alerts.
  255. c.rawConn.RawInput.Grow(needs + bytes.MinRead)
  256. _, err := c.rawConn.RawInput.ReadFrom(&atLeastReader{r, int64(needs)})
  257. return err
  258. }
  259. func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err tls.RecordHeaderError) {
  260. err.Msg = msg
  261. err.Conn = conn
  262. copy(err.RecordHeader[:], c.rawConn.RawInput.Bytes())
  263. return err
  264. }