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)) {