Allow delay on renego on client

Currently unbounded: will be fixed later
diff --git a/include/polarssl/error.h b/include/polarssl/error.h
index cdee952..7ce2828 100644
--- a/include/polarssl/error.h
+++ b/include/polarssl/error.h
@@ -91,7 +91,7 @@
  * ECP       4   8 (Started from top)
  * MD        5   4
  * CIPHER    6   6
- * SSL       6   9 (Started from top)
+ * SSL       6   10 (Started from top)
  * SSL       7   31
  *
  * Module dependent error code (5 bits 0x.00.-0x.F8.)
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index bee86a6..6c6cb21 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -145,6 +145,7 @@
 #define POLARSSL_ERR_SSL_UNKNOWN_IDENTITY                  -0x6C80  /**< Unknown identity received (eg, PSK identity) */
 #define POLARSSL_ERR_SSL_INTERNAL_ERROR                    -0x6C00  /**< Internal error (eg, unexpected failure in lower-level module) */
 #define POLARSSL_ERR_SSL_COUNTER_WRAPPING                  -0x6B80  /**< A counter would wrap (eg, too many messages exchanged). */
+#define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO       -0x6B00  /**< Unexpected message at ServerHello in renegotiation. */
 
 /*
  * Various constants
diff --git a/library/error.c b/library/error.c
index 22234cf..73504d4 100644
--- a/library/error.c
+++ b/library/error.c
@@ -450,6 +450,8 @@
             snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" );
         if( use_ret == -(POLARSSL_ERR_SSL_COUNTER_WRAPPING) )
             snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
+        if( use_ret == -(POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
+            snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
 #endif /* POLARSSL_SSL_TLS_C */
 
 #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index d38d769..089b7c9 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -902,6 +902,12 @@
 
     if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
     {
+        if( ssl->renegotiation == SSL_RENEGOTIATION )
+        {
+            SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
+            return( POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
+        }
+
         SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
     }
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 1d68d96..e6c4efd 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4260,14 +4260,19 @@
  */
 int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
 {
-    int ret;
+    int ret, record_read = 0;
     size_t n;
 
     SSL_DEBUG_MSG( 2, ( "=> read" ) );
 
     if( ssl->state != SSL_HANDSHAKE_OVER )
     {
-        if( ( ret = ssl_handshake( ssl ) ) != 0 )
+        ret = ssl_handshake( ssl );
+        if( ret == POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO )
+        {
+            record_read = 1;
+        }
+        else if( ret != 0 )
         {
             SSL_DEBUG_RET( 1, "ssl_handshake", ret );
             return( ret );
@@ -4276,13 +4281,16 @@
 
     if( ssl->in_offt == NULL )
     {
-        if( ( ret = ssl_read_record( ssl ) ) != 0 )
+        if( ! record_read )
         {
-            if( ret == POLARSSL_ERR_SSL_CONN_EOF )
-                return( 0 );
+            if( ( ret = ssl_read_record( ssl ) ) != 0 )
+            {
+                if( ret == POLARSSL_ERR_SSL_CONN_EOF )
+                    return( 0 );
 
-            SSL_DEBUG_RET( 1, "ssl_read_record", ret );
-            return( ret );
+                SSL_DEBUG_RET( 1, "ssl_read_record", ret );
+                return( ret );
+            }
         }
 
         if( ssl->in_msglen  == 0 &&
@@ -4352,15 +4360,22 @@
             }
             else
             {
-                if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
+                ret = ssl_start_renegotiation( ssl );
+                if( ret == POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO )
+                {
+                    record_read = 1;
+                }
+                else if( ret != 0 )
                 {
                     SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
                     return( ret );
                 }
             }
 
-            /* Tell the user to call ssl_read() again */
-            return( POLARSSL_ERR_NET_WANT_READ );
+            /* If a non-handshake record was read during renego, fallthrough,
+             * else tell the user they should call ssl_read() again */
+            if( ! record_read )
+                return( POLARSSL_ERR_NET_WANT_READ );
         }
         else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING )
         {
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index b6924a7..63258cc 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -627,7 +627,7 @@
             -c "=> renegotiate" \
             -S "=> renegotiate" \
             -S "write hello request" \
-            -c "SSL - An unexpected message was received from our peer" \
+            -c "SSL - Unexpected message at ServerHello in renegotiation" \
             -c "failed"
 
 run_test    "Renegotiation #5 (server-initiated, client-rejected, default)" \