s2n_shutdown.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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 "api/s2n.h"
  16. #include "tls/s2n_alerts.h"
  17. #include "tls/s2n_connection.h"
  18. #include "tls/s2n_tls.h"
  19. #include "utils/s2n_atomic.h"
  20. #include "utils/s2n_safety.h"
  21. static bool s2n_shutdown_expect_close_notify(struct s2n_connection *conn)
  22. {
  23. /* No close_notify expected if we already received an error instead */
  24. if (s2n_atomic_flag_test(&conn->error_alert_received)) {
  25. return false;
  26. }
  27. /* No close_notify expected if we sent an error instead of a close_notify */
  28. if (conn->writer_alert_out || conn->reader_alert_out) {
  29. return false;
  30. }
  31. /* The purpose of the peer responding to our close_notify
  32. * with its own close_notify is to prevent application data truncation.
  33. * However, application data is not a concern during the handshake.
  34. *
  35. * Additionally, decrypting alerts sent during the handshake can be error prone
  36. * due to different encryption keys and may lead to unnecessary error reporting
  37. * and unnecessary blinding.
  38. */
  39. if (!s2n_handshake_is_complete(conn)) {
  40. return false;
  41. }
  42. /* QUIC does not use TLS alerts */
  43. if (conn->quic_enabled) {
  44. return false;
  45. }
  46. return true;
  47. }
  48. int s2n_shutdown_send(struct s2n_connection *conn, s2n_blocked_status *blocked)
  49. {
  50. POSIX_ENSURE_REF(conn);
  51. POSIX_ENSURE_REF(blocked);
  52. *blocked = S2N_NOT_BLOCKED;
  53. /* Treat this call as a no-op if already wiped.
  54. * This should probably be an error, but wasn't in the past so is left as-is
  55. * for backwards compatibility.
  56. */
  57. if (conn->send == NULL && conn->recv == NULL) {
  58. return S2N_SUCCESS;
  59. }
  60. /* Flush any outstanding data */
  61. s2n_atomic_flag_set(&conn->write_closed);
  62. POSIX_GUARD(s2n_flush(conn, blocked));
  63. /* For a connection closed due to receiving an alert, we don't send anything. */
  64. if (s2n_atomic_flag_test(&conn->error_alert_received)) {
  65. return S2N_SUCCESS;
  66. }
  67. /* If we've already sent an alert, don't send another. */
  68. if (conn->alert_sent) {
  69. return S2N_SUCCESS;
  70. }
  71. /* Enforce blinding.
  72. * If an application is using self-service blinding, ensure that they have
  73. * waited the required time before triggering any alerts.
  74. */
  75. uint64_t elapsed = 0;
  76. POSIX_GUARD_RESULT(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
  77. S2N_ERROR_IF(elapsed < conn->delay, S2N_ERR_SHUTDOWN_PAUSED);
  78. /**
  79. *= https://tools.ietf.org/rfc/rfc8446#section-6.1
  80. *# Each party MUST send a "close_notify" alert before closing its write
  81. *# side of the connection, unless it has already sent some error alert.
  82. */
  83. POSIX_GUARD_RESULT(s2n_alerts_write_error_or_close_notify(conn));
  84. POSIX_GUARD(s2n_flush(conn, blocked));
  85. return S2N_SUCCESS;
  86. }
  87. int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status *blocked)
  88. {
  89. POSIX_ENSURE_REF(conn);
  90. POSIX_ENSURE_REF(blocked);
  91. *blocked = S2N_NOT_BLOCKED;
  92. /* If necessary, send an alert to indicate shutdown. */
  93. POSIX_GUARD(s2n_shutdown_send(conn, blocked));
  94. /* If we don't expect a close_notify from our peer,
  95. * just ensure that the connection is marked closed.
  96. */
  97. if (!s2n_shutdown_expect_close_notify(conn)) {
  98. POSIX_GUARD_RESULT(s2n_connection_set_closed(conn));
  99. *blocked = S2N_NOT_BLOCKED;
  100. return S2N_SUCCESS;
  101. }
  102. /* Wait for the peer's close_notify. */
  103. uint8_t record_type = 0;
  104. int isSSLv2 = false;
  105. *blocked = S2N_BLOCKED_ON_READ;
  106. while (!s2n_atomic_flag_test(&conn->close_notify_received)) {
  107. POSIX_GUARD(s2n_read_full_record(conn, &record_type, &isSSLv2));
  108. POSIX_ENSURE(!isSSLv2, S2N_ERR_BAD_MESSAGE);
  109. if (record_type == TLS_ALERT) {
  110. POSIX_GUARD(s2n_process_alert_fragment(conn));
  111. }
  112. /* Wipe and keep trying */
  113. POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in));
  114. POSIX_GUARD(s2n_stuffer_wipe(&conn->in));
  115. conn->in_status = ENCRYPTED;
  116. }
  117. *blocked = S2N_NOT_BLOCKED;
  118. return S2N_SUCCESS;
  119. }