From a88399c0918c79251429db39b9eb8fc55fe570f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?=
 <manuel.pegourie-gonnard@arm.com>
Date: Fri, 12 Jul 2019 10:41:55 +0200
Subject: [PATCH] Improve demo/testing code in client/server2

Previously it was missing reset in case 1, and in case 2 the code was never
executed as the option value was reset to 0.

Tighten checking of return values of save(NULL, 0) now that it works.

Also, improve the printed output as well as the comments.

I checked manually that everything now works and fail in the expected way:
save, reset-or-reinit and load all succeed, but the subsequent read or write
fails.
---
 programs/ssl/ssl_client2.c | 40 +++++++++++++++++++--------
 programs/ssl/ssl_server2.c | 55 ++++++++++++++++++++++++++++++++------
 2 files changed, 76 insertions(+), 19 deletions(-)

diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index a9ab07fe41..37b047cc41 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2924,14 +2924,10 @@ send_request:
         size_t buf_len;
         unsigned char *context_buf = NULL;
 
-        opt.serialize = 0;
-        mbedtls_printf( " Serializing live connection..." );
+        mbedtls_printf( "  . Serializing live connection..." );
 
         ret = mbedtls_ssl_context_save( &ssl, NULL, 0, &buf_len );
-
-        /* Allow stub implementation returning 0 for now */
-        if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL &&
-            ret != 0 )
+        if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_context_save returned "
                             "-0x%x\n\n", -ret );
@@ -2950,14 +2946,32 @@ send_request:
         if( ( ret = mbedtls_ssl_context_save( &ssl, context_buf,
                                               buf_len, &buf_len ) ) != 0 )
         {
-            mbedtls_printf( "failed\n  ! mbedtls_ssl_context_save returned "
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_context_save returned "
                             "-0x%x\n\n", -ret );
 
             goto exit;
         }
 
+        mbedtls_printf( " ok\n" );
+
+        if( opt.serialize == 1 )
+        {
+            mbedtls_printf( "  . Reseting context..." );
+
+            if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
+            {
+                mbedtls_printf( " failed\n  ! mbedtls_ssl_session_reset returned "
+                                "-0x%x\n\n", -ret );
+                goto exit;
+            }
+
+            mbedtls_printf( " ok\n" );
+        }
+
         if( opt.serialize == 2 )
         {
+            mbedtls_printf( "  . Freeing and reinitializing context..." );
+
             mbedtls_ssl_free( &ssl );
 
             mbedtls_ssl_init( &ssl );
@@ -2965,7 +2979,7 @@ send_request:
             if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
             {
                 mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned "
-                                " -0x%x\n\n", -ret );
+                                "-0x%x\n\n", -ret );
                 goto exit;
             }
 
@@ -2973,8 +2987,8 @@ send_request:
                 mbedtls_ssl_set_bio( &ssl, &server_fd, delayed_send,
                                      delayed_recv, NULL );
             else
-                mbedtls_ssl_set_bio( &ssl, &server_fd,
-                            mbedtls_net_send, mbedtls_net_recv,
+                mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send,
+                            mbedtls_net_recv,
                             opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
 
 #if defined(MBEDTLS_TIMING_C)
@@ -2983,9 +2997,11 @@ send_request:
                                           mbedtls_timing_set_delay,
                                           mbedtls_timing_get_delay );
 #endif /* MBEDTLS_TIMING_C */
+
+            mbedtls_printf( " ok\n" );
         }
 
-        mbedtls_printf( " Deserializing connection..." );
+        mbedtls_printf( "  . Deserializing connection..." );
 
         if( ( ret = mbedtls_ssl_context_load( &ssl, context_buf,
                                               buf_len ) ) != 0 )
@@ -2995,6 +3011,8 @@ send_request:
 
             goto exit;
         }
+
+        mbedtls_printf( " ok\n" );
     }
 #endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
 
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 6f6f4dd7ec..5b7d17379a 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -3935,14 +3935,10 @@ data_exchange:
         size_t buf_len;
         unsigned char *context_buf = NULL;
 
-        opt.serialize = 0;
-        mbedtls_printf( " Serializing live connection..." );
+        mbedtls_printf( "  . Serializing live connection..." );
 
         ret = mbedtls_ssl_context_save( &ssl, NULL, 0, &buf_len );
-
-        /* Allow stub implementation returning 0 for now */
-        if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL &&
-            ret != 0 )
+        if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_context_save returned "
                             "-0x%x\n\n", -ret );
@@ -3961,14 +3957,47 @@ data_exchange:
         if( ( ret = mbedtls_ssl_context_save( &ssl, context_buf,
                                               buf_len, &buf_len ) ) != 0 )
         {
-            mbedtls_printf( "failed\n  ! mbedtls_ssl_context_save returned "
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_context_save returned "
                             "-0x%x\n\n", -ret );
 
             goto exit;
         }
 
+        mbedtls_printf( " ok\n" );
+
+        /*
+         * This simulates a workflow where you have a long-lived server
+         * instance, potentially with a pool of ssl_context objects, and you
+         * just want to re-use one while the connection is inactive: in that
+         * case you can just reset() it, and then it's ready to receive
+         * serialized data from another connection (or the same here).
+         */
+        if( opt.serialize == 1 )
+        {
+            mbedtls_printf( "  . Reseting context..." );
+
+            if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
+            {
+                mbedtls_printf( " failed\n  ! mbedtls_ssl_session_reset returned "
+                                "-0x%x\n\n", -ret );
+                goto exit;
+            }
+
+            mbedtls_printf( " ok\n" );
+        }
+
+        /*
+         * This simulates a workflow where you have one server instance per
+         * connection, and want to release it entire when the connection is
+         * inactive, and spawn it again when needed again - this would happen
+         * between ssl_free() and ssl_init() below, together with any other
+         * teardown/startup code needed - for example, preparing the
+         * ssl_config again (see section 3 "setup stuff" in this file).
+         */
         if( opt.serialize == 2 )
         {
+            mbedtls_printf( "  . Freeing and reinitializing context..." );
+
             mbedtls_ssl_free( &ssl );
 
             mbedtls_ssl_init( &ssl );
@@ -3980,6 +4009,12 @@ data_exchange:
                 goto exit;
             }
 
+            /*
+             * This illustrates the minimum amount of things you need to set
+             * up, however you could set up much more if desired, for example
+             * if you want to share your set up code between the case of
+             * establishing a new connection and this case.
+             */
             if( opt.nbio == 2 )
                 mbedtls_ssl_set_bio( &ssl, &client_fd, delayed_send,
                                      delayed_recv, NULL );
@@ -3994,9 +4029,11 @@ data_exchange:
                                           mbedtls_timing_set_delay,
                                           mbedtls_timing_get_delay );
 #endif /* MBEDTLS_TIMING_C */
+
+            mbedtls_printf( " ok\n" );
         }
 
-        mbedtls_printf( " Deserializing connection..." );
+        mbedtls_printf( "  . Deserializing connection..." );
 
         if( ( ret = mbedtls_ssl_context_load( &ssl, context_buf,
                                               buf_len ) ) != 0 )
@@ -4006,6 +4043,8 @@ data_exchange:
 
             goto exit;
         }
+
+        mbedtls_printf( " ok\n" );
     }
 #endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */