s2n_recv.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License").
  5. * You may not use this file except in compliance with the License.
  6. * A copy of the License is located at
  7. *
  8. * http://aws.amazon.com/apache2.0
  9. *
  10. * or in the "license" file accompanying this file. This file is distributed
  11. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  12. * express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. #include <sys/param.h>
  16. /* Use usleep */
  17. #define _XOPEN_SOURCE 500
  18. #include <errno.h>
  19. #include <unistd.h>
  20. #include "api/s2n.h"
  21. #include "error/s2n_errno.h"
  22. #include "stuffer/s2n_stuffer.h"
  23. #include "tls/s2n_alerts.h"
  24. #include "tls/s2n_connection.h"
  25. #include "tls/s2n_handshake.h"
  26. #include "tls/s2n_ktls.h"
  27. #include "tls/s2n_post_handshake.h"
  28. #include "tls/s2n_record.h"
  29. #include "tls/s2n_resume.h"
  30. #include "tls/s2n_tls.h"
  31. #include "utils/s2n_blob.h"
  32. #include "utils/s2n_io.h"
  33. #include "utils/s2n_safety.h"
  34. #include "utils/s2n_socket.h"
  35. S2N_RESULT s2n_read_in_bytes(struct s2n_connection *conn, struct s2n_stuffer *output, uint32_t length)
  36. {
  37. while (s2n_stuffer_data_available(output) < length) {
  38. uint32_t remaining = length - s2n_stuffer_data_available(output);
  39. errno = 0;
  40. int r = s2n_connection_recv_stuffer(output, conn, remaining);
  41. if (r == 0) {
  42. s2n_atomic_flag_set(&conn->read_closed);
  43. }
  44. RESULT_GUARD(s2n_io_check_read_result(r));
  45. conn->wire_bytes_in += r;
  46. }
  47. return S2N_RESULT_OK;
  48. }
  49. int s2n_read_full_record(struct s2n_connection *conn, uint8_t *record_type, int *isSSLv2)
  50. {
  51. *isSSLv2 = 0;
  52. if (conn->ktls_recv_enabled) {
  53. return s2n_ktls_read_full_record(conn, record_type);
  54. }
  55. /* If the record has already been decrypted, then leave it alone */
  56. if (conn->in_status == PLAINTEXT) {
  57. /* Only application data packets count as plaintext */
  58. *record_type = TLS_APPLICATION_DATA;
  59. return S2N_SUCCESS;
  60. }
  61. POSIX_GUARD(s2n_stuffer_resize_if_empty(&conn->in, S2N_LARGE_FRAGMENT_LENGTH));
  62. /* Read the record until we at least have a header */
  63. POSIX_GUARD_RESULT(s2n_read_in_bytes(conn, &conn->header_in, S2N_TLS_RECORD_HEADER_LENGTH));
  64. uint16_t fragment_length;
  65. /* If the first bit is set then this is an SSLv2 record */
  66. if (conn->header_in.blob.data[0] & 0x80) {
  67. conn->header_in.blob.data[0] &= 0x7f;
  68. *isSSLv2 = 1;
  69. WITH_ERROR_BLINDING(conn, POSIX_GUARD(s2n_sslv2_record_header_parse(conn, record_type, &conn->client_protocol_version, &fragment_length)));
  70. } else {
  71. WITH_ERROR_BLINDING(conn, POSIX_GUARD(s2n_record_header_parse(conn, record_type, &fragment_length)));
  72. }
  73. /* Read enough to have the whole record */
  74. POSIX_GUARD_RESULT(s2n_read_in_bytes(conn, &conn->in, fragment_length));
  75. if (*isSSLv2) {
  76. return 0;
  77. }
  78. /* Decrypt and parse the record */
  79. if (s2n_early_data_is_trial_decryption_allowed(conn, *record_type)) {
  80. POSIX_ENSURE(s2n_record_parse(conn) >= S2N_SUCCESS, S2N_ERR_EARLY_DATA_TRIAL_DECRYPT);
  81. } else {
  82. WITH_ERROR_BLINDING(conn, POSIX_GUARD(s2n_record_parse(conn)));
  83. }
  84. /* In TLS 1.3, encrypted handshake records would appear to be of record type
  85. * TLS_APPLICATION_DATA. The actual record content type is found after the encrypted
  86. * is decrypted.
  87. */
  88. if (conn->actual_protocol_version == S2N_TLS13 && *record_type == TLS_APPLICATION_DATA) {
  89. POSIX_GUARD(s2n_tls13_parse_record_type(&conn->in, record_type));
  90. }
  91. return 0;
  92. }
  93. ssize_t s2n_recv_impl(struct s2n_connection *conn, void *buf, ssize_t size_signed, s2n_blocked_status *blocked)
  94. {
  95. POSIX_ENSURE_GTE(size_signed, 0);
  96. size_t size = size_signed;
  97. ssize_t bytes_read = 0;
  98. struct s2n_blob out = { 0 };
  99. POSIX_GUARD(s2n_blob_init(&out, (uint8_t *) buf, 0));
  100. /*
  101. * Set the `blocked` status to BLOCKED_ON_READ by default
  102. *
  103. * The only case in which it should be updated is on a successful read into the provided buffer.
  104. *
  105. * Unfortunately, the current `blocked` behavior has become ossified by buggy applications that ignore
  106. * error types and only read `blocked`. As such, it's very important to avoid changing how this value is updated
  107. * as it could break applications.
  108. */
  109. *blocked = S2N_BLOCKED_ON_READ;
  110. if (!s2n_connection_check_io_status(conn, S2N_IO_READABLE)) {
  111. /*
  112. *= https://tools.ietf.org/rfc/rfc8446#6.1
  113. *# If a transport-level close
  114. *# is received prior to a "close_notify", the receiver cannot know that
  115. *# all the data that was sent has been received.
  116. *
  117. *= https://tools.ietf.org/rfc/rfc8446#6.1
  118. *# If the application protocol using TLS provides that any data may be
  119. *# carried over the underlying transport after the TLS connection is
  120. *# closed, the TLS implementation MUST receive a "close_notify" alert
  121. *# before indicating end-of-data to the application layer.
  122. */
  123. POSIX_ENSURE(s2n_atomic_flag_test(&conn->close_notify_received), S2N_ERR_CLOSED);
  124. *blocked = S2N_NOT_BLOCKED;
  125. return 0;
  126. }
  127. POSIX_ENSURE(!s2n_connection_is_quic_enabled(conn), S2N_ERR_UNSUPPORTED_WITH_QUIC);
  128. POSIX_GUARD_RESULT(s2n_early_data_validate_recv(conn));
  129. while (size && s2n_connection_check_io_status(conn, S2N_IO_READABLE)) {
  130. int isSSLv2 = 0;
  131. uint8_t record_type;
  132. int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
  133. if (r < 0) {
  134. /* Don't propagate the error if we already read some bytes. */
  135. if (bytes_read && (s2n_errno == S2N_ERR_CLOSED || s2n_errno == S2N_ERR_IO_BLOCKED)) {
  136. break;
  137. }
  138. /* If we get here, it's an error condition */
  139. if (s2n_errno != S2N_ERR_IO_BLOCKED && s2n_allowed_to_cache_connection(conn) && conn->session_id_len) {
  140. conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
  141. }
  142. S2N_ERROR_PRESERVE_ERRNO();
  143. }
  144. S2N_ERROR_IF(isSSLv2, S2N_ERR_BAD_MESSAGE);
  145. if (record_type != TLS_HANDSHAKE) {
  146. /*
  147. *= https://tools.ietf.org/rfc/rfc8446#section-5.1
  148. *# - Handshake messages MUST NOT be interleaved with other record
  149. *# types. That is, if a handshake message is split over two or more
  150. *# records, there MUST NOT be any other records between them.
  151. */
  152. POSIX_ENSURE(s2n_stuffer_is_wiped(&conn->post_handshake.in), S2N_ERR_BAD_MESSAGE);
  153. /* If not handling a handshake message, free the post-handshake memory.
  154. * Post-handshake messages are infrequent enough that we don't want to
  155. * keep a potentially large buffer around unnecessarily.
  156. */
  157. if (!s2n_stuffer_is_freed(&conn->post_handshake.in)) {
  158. POSIX_GUARD(s2n_stuffer_free(&conn->post_handshake.in));
  159. }
  160. }
  161. if (record_type != TLS_APPLICATION_DATA) {
  162. switch (record_type) {
  163. case TLS_ALERT:
  164. POSIX_GUARD(s2n_process_alert_fragment(conn));
  165. break;
  166. case TLS_HANDSHAKE: {
  167. s2n_result result = s2n_post_handshake_recv(conn);
  168. /* Ignore any errors due to insufficient input data from io.
  169. * The next iteration of this loop will attempt to read more input data.
  170. */
  171. if (s2n_result_is_error(result) && s2n_errno != S2N_ERR_IO_BLOCKED) {
  172. WITH_ERROR_BLINDING(conn, POSIX_GUARD_RESULT(result));
  173. }
  174. break;
  175. }
  176. }
  177. POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in));
  178. POSIX_GUARD(s2n_stuffer_wipe(&conn->in));
  179. conn->in_status = ENCRYPTED;
  180. continue;
  181. }
  182. out.size = MIN(size, s2n_stuffer_data_available(&conn->in));
  183. POSIX_GUARD(s2n_stuffer_erase_and_read(&conn->in, &out));
  184. bytes_read += out.size;
  185. out.data += out.size;
  186. size -= out.size;
  187. /* Are we ready for more encrypted data? */
  188. if (s2n_stuffer_data_available(&conn->in) == 0) {
  189. POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in));
  190. POSIX_GUARD(s2n_stuffer_wipe(&conn->in));
  191. conn->in_status = ENCRYPTED;
  192. }
  193. /* If we've read some data, return it in legacy mode */
  194. if (bytes_read && !conn->config->recv_multi_record) {
  195. break;
  196. }
  197. }
  198. /* Due to the history of this API, some applications depend on the blocked status to know if
  199. * the connection's `in` stuffer was completely cleared. This behavior needs to be preserved.
  200. *
  201. * Moving forward, applications should instead use `s2n_peek`, which accomplishes the same thing
  202. * without conflating being blocked on reading from the OS socket vs blocked on the application's
  203. * buffer size.
  204. */
  205. if (s2n_stuffer_data_available(&conn->in) == 0) {
  206. *blocked = S2N_NOT_BLOCKED;
  207. }
  208. return bytes_read;
  209. }
  210. ssize_t s2n_recv(struct s2n_connection *conn, void *buf, ssize_t size, s2n_blocked_status *blocked)
  211. {
  212. POSIX_ENSURE(!conn->recv_in_use, S2N_ERR_REENTRANCY);
  213. conn->recv_in_use = true;
  214. ssize_t result = s2n_recv_impl(conn, buf, size, blocked);
  215. POSIX_GUARD_RESULT(s2n_early_data_record_bytes(conn, result));
  216. /* finish the recv call */
  217. POSIX_GUARD_RESULT(s2n_connection_dynamic_free_in_buffer(conn));
  218. conn->recv_in_use = false;
  219. return result;
  220. }
  221. uint32_t s2n_peek(struct s2n_connection *conn)
  222. {
  223. if (conn == NULL) {
  224. return 0;
  225. }
  226. /* If we have partially buffered an encrypted record,
  227. * we should not report those bytes as available to read.
  228. */
  229. if (conn->in_status != PLAINTEXT) {
  230. return 0;
  231. }
  232. return s2n_stuffer_data_available(&conn->in);
  233. }