Tidy up shutdown state.
The existing logic gets confused in a number of cases around close_notify vs.
fatal alert. SSL_shutdown, while still pushing to the error queue, will fail to
notice alerts. We also get confused if we try to send a fatal alert when we've
already sent something else.
Change-Id: I9b1d217fbf1ee8a9c59efbebba60165b7de9689e
Reviewed-on: https://boringssl-review.googlesource.com/7952
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 7d4fe4a..d3bf83a 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -3879,8 +3879,6 @@
* handshake_func is == 0 until then, we use this test instead of an "init"
* member. */
- int shutdown; /* we have shut things down, 0x01 sent, 0x02
- * for received */
int state; /* where we are */
BUF_MEM *init_buf; /* buffer used during init */
@@ -4041,6 +4039,14 @@
uint16_t cap;
} SSL3_BUFFER;
+/* An ssl_shutdown_t describes the shutdown state of one end of the connection,
+ * whether it is alive or has been shutdown via close_notify or fatal alert. */
+enum ssl_shutdown_t {
+ ssl_shutdown_none = 0,
+ ssl_shutdown_close_notify = 1,
+ ssl_shutdown_fatal_alert = 2,
+};
+
typedef struct ssl3_state_st {
uint8_t read_sequence[8];
uint8_t write_sequence[8];
@@ -4083,9 +4089,12 @@
* the handshake hash for TLS 1.1 and below. */
EVP_MD_CTX handshake_md5;
- /* clean_shutdown is one if the connection was cleanly shutdown with a
- * close_notify and zero otherwise. */
- char clean_shutdown;
+ /* recv_shutdown is the shutdown state for the receive half of the
+ * connection. */
+ enum ssl_shutdown_t recv_shutdown : 2;
+
+ /* recv_shutdown is the shutdown state for the send half of the connection. */
+ enum ssl_shutdown_t send_shutdown : 2;
int alert_dispatch;
uint8_t send_alert[2];