Handle SSL_shutdown while in init more appropriately
Calling SSL_shutdown while in init previously gave a "1" response,
meaning everything was successfully closed down (even though it
wasn't). Better is to send our close_notify, but fail when trying to
receive one.
The problem with doing a shutdown while in the middle of a handshake
is that once our close_notify is sent we shouldn't really do anything
else (including process handshake/CCS messages) until we've received a
close_notify back from the peer. However the peer might send a CCS
before acting on our close_notify - so we won't be able to read it
because we're not acting on CCS messages!
(Imported from upstream's f73c737c7ac908c5d6407c419769123392a3b0a9)
Change-Id: Iaad5c5e38983456d3697c955522a89919628024b
Reviewed-on: https://boringssl-review.googlesource.com/7207
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/err/ssl.errordata b/crypto/err/ssl.errordata
index 3766bb9..dfe4ac8 100644
--- a/crypto/err/ssl.errordata
+++ b/crypto/err/ssl.errordata
@@ -108,6 +108,7 @@
SSL,207,SERVERHELLO_TLSEXT
SSL,208,SESSION_ID_CONTEXT_UNINITIALIZED
SSL,209,SESSION_MAY_NOT_BE_CREATED
+SSL,250,SHUTDOWN_WHILE_IN_INIT
SSL,210,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
SSL,211,SRTP_COULD_NOT_ALLOCATE_PROFILES
SSL,212,SRTP_UNKNOWN_PROTECTION_PROFILE
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 41813b2..a2fbbb2 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -4506,6 +4506,7 @@
#define SSL_R_WRONG_VERSION_NUMBER 247
#define SSL_R_X509_LIB 248
#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 249
+#define SSL_R_SHUTDOWN_WHILE_IN_INIT 250
#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index b726011..fbe2bca 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -646,10 +646,6 @@
return -1;
}
- if (SSL_in_init(ssl)) {
- return 1;
- }
-
/* Do nothing if configured not to send a close_notify. */
if (ssl->quiet_shutdown) {
ssl->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
@@ -675,6 +671,11 @@
return ret;
}
} else if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+ if (SSL_in_init(ssl)) {
+ /* We can't shutdown properly if we are in the middle of a handshake. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT);
+ return -1;
+ }
/* If we are waiting for a close from our peer, we are closed */
ssl->method->ssl_read_close_notify(ssl);
if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {