The branch master has been updated
       via  7a301f08bc102179248173426ea15e00fa9211d1 (commit)
       via  07927bedf3667f9a9148fb5670fb06124ae8fa59 (commit)
      from  402f26e6ee56ec295e053d1f6455e910ac398149 (commit)


- Log -----------------------------------------------------------------
commit 7a301f08bc102179248173426ea15e00fa9211d1
Author: Matt Caswell <m...@openssl.org>
Date:   Wed Aug 2 12:19:15 2017 +0100

    Test server side session caching
    
    In particular this covers the scenario mentioned in #4014
    
    Reviewed-by: Paul Dale <paul.d...@oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/4072)

commit 07927bedf3667f9a9148fb5670fb06124ae8fa59
Author: Matt Caswell <m...@openssl.org>
Date:   Wed Aug 2 13:32:56 2017 +0100

    Add an SSL_SESSION_dup() function
    
    Reviewed-by: Paul Dale <paul.d...@oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/4072)

-----------------------------------------------------------------------

Summary of changes:
 doc/man3/SSL_SESSION_free.pod |   9 +++
 include/openssl/ssl.h         |   1 +
 ssl/ssl_sess.c                |   5 ++
 test/sslapitest.c             | 181 +++++++++++++++++++++++++++++++++++-------
 util/libssl.num               |   1 +
 5 files changed, 169 insertions(+), 28 deletions(-)

diff --git a/doc/man3/SSL_SESSION_free.pod b/doc/man3/SSL_SESSION_free.pod
index b288baf..87a1cab 100644
--- a/doc/man3/SSL_SESSION_free.pod
+++ b/doc/man3/SSL_SESSION_free.pod
@@ -3,6 +3,7 @@
 =head1 NAME
 
 SSL_SESSION_new,
+SSL_SESSION_dup,
 SSL_SESSION_up_ref,
 SSL_SESSION_free - create, free and manage SSL_SESSION structures
 
@@ -11,6 +12,7 @@ SSL_SESSION_free - create, free and manage SSL_SESSION 
structures
  #include <openssl/ssl.h>
 
  SSL_SESSION *SSL_SESSION_new(void);
+ SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src);
  int SSL_SESSION_up_ref(SSL_SESSION *ses);
  void SSL_SESSION_free(SSL_SESSION *session);
 
@@ -19,6 +21,9 @@ SSL_SESSION_free - create, free and manage SSL_SESSION 
structures
 SSL_SESSION_new() creates a new SSL_SESSION structure and returns a pointer to
 it.
 
+SSL_SESSION_dup() copies the contents of the SSL_SESSION structure in B<src>
+and returns a pointer to it.
+
 SSL_SESSION_up_ref() increments the reference count on the given SSL_SESSION
 structure.
 
@@ -66,6 +71,10 @@ L<SSL_CTX_set_session_cache_mode(3)>,
 L<SSL_CTX_flush_sessions(3)>,
 L<d2i_SSL_SESSION(3)>
 
+=head1 HISTORY
+
+SSL_SESSION_dup() was added in OpenSSL 1.1.1.
+
 =head1 COPYRIGHT
 
 Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index a2d13bf..b4c6644 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1545,6 +1545,7 @@ __owur int SSL_SESSION_set1_id(SSL_SESSION *s, const 
unsigned char *sid,
 __owur int SSL_SESSION_is_resumable(const SSL_SESSION *s);
 
 __owur SSL_SESSION *SSL_SESSION_new(void);
+__owur SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src);
 const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
                                         unsigned int *len);
 const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s,
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index 8cd4355..7336251 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -93,6 +93,11 @@ SSL_SESSION *SSL_SESSION_new(void)
     return ss;
 }
 
+SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src)
+{
+    return ssl_session_dup(src, 1);
+}
+
 /*
  * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
  * ticket == 0 then no ticket information is duplicated, otherwise it is.
diff --git a/test/sslapitest.c b/test/sslapitest.c
index afb119d..e44e9c1 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -775,7 +775,18 @@ static void remove_session_cb(SSL_CTX *ctx, SSL_SESSION 
*sess)
     remove_called++;
 }
 
-static int execute_test_session(int use_int_cache, int use_ext_cache)
+static SSL_SESSION *get_sess_val = NULL;
+
+static SSL_SESSION *get_session_cb(SSL *ssl, const unsigned char *id, int len,
+                                   int *copy)
+{
+    *copy = 1;
+    return get_sess_val;
+}
+
+
+static int execute_test_session(int maxprot, int use_int_cache,
+                                int use_ext_cache)
 {
     SSL_CTX *sctx = NULL, *cctx = NULL;
     SSL *serverssl1 = NULL, *clientssl1 = NULL;
@@ -793,10 +804,12 @@ static int execute_test_session(int use_int_cache, int 
use_ext_cache)
                                        &cctx, cert, privkey)))
         return 0;
 
-#ifndef OPENSSL_NO_TLS1_2
-    /* Only allow TLS1.2 so we can force a connection failure later */
-    SSL_CTX_set_min_proto_version(cctx, TLS1_2_VERSION);
-#endif
+    /*
+     * Only allow the max protocol version so we can force a connection failure
+     * later
+     */
+    SSL_CTX_set_min_proto_version(cctx, maxprot);
+    SSL_CTX_set_max_proto_version(cctx, maxprot);
 
     /* Set up session cache */
     if (use_ext_cache) {
@@ -822,11 +835,10 @@ static int execute_test_session(int use_int_cache, int 
use_ext_cache)
     /* Should fail because it should already be in the cache */
     if (use_int_cache && !TEST_false(SSL_CTX_add_session(cctx, sess1)))
         goto end;
-    if (use_ext_cache && !TEST_int_eq(new_called, 1)
-            && !TEST_int_eq(remove_called, 0))
+    if (use_ext_cache
+            && (!TEST_int_eq(new_called, 1) || !TEST_int_eq(remove_called, 0)))
         goto end;
 
-#if !defined(OPENSSL_NO_TLS1_3)
     new_called = remove_called = 0;
     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl2,
                                       &clientssl2, NULL, NULL))
@@ -836,20 +848,31 @@ static int execute_test_session(int use_int_cache, int 
use_ext_cache)
             || !TEST_true(SSL_session_reused(clientssl2)))
         goto end;
 
-    /*
-     * In TLSv1.3 we should have created a new session even though we have
-     * resumed. The original session should also have been removed.
-     */
-    if (use_ext_cache && !TEST_int_eq(new_called, 1)
-            && !TEST_int_eq(remove_called, 1))
-        goto end;
+    if (maxprot == TLS1_3_VERSION) {
+        /*
+         * In TLSv1.3 we should have created a new session even though we have
+         * resumed. The original session should also have been removed.
+         */
+        if (use_ext_cache
+                && (!TEST_int_eq(new_called, 1)
+                    || !TEST_int_eq(remove_called, 1)))
+            goto end;
+    } else {
+        /*
+         * In TLSv1.2 we expect to have resumed so no sessions added or
+         * removed.
+         */
+        if (use_ext_cache
+                && (!TEST_int_eq(new_called, 0)
+                    || !TEST_int_eq(remove_called, 0)))
+            goto end;
+    }
 
     SSL_SESSION_free(sess1);
     if (!TEST_ptr(sess1 = SSL_get1_session(clientssl2)))
         goto end;
     shutdown_ssl_connection(serverssl2, clientssl2);
     serverssl2 = clientssl2 = NULL;
-#endif
 
     new_called = remove_called = 0;
     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl2,
@@ -861,8 +884,8 @@ static int execute_test_session(int use_int_cache, int 
use_ext_cache)
     if (!TEST_ptr(sess2 = SSL_get1_session(clientssl2)))
         goto end;
 
-    if (use_ext_cache && !TEST_int_eq(new_called, 1)
-            && !TEST_int_eq(remove_called, 0))
+    if (use_ext_cache
+            && (!TEST_int_eq(new_called, 1) || !TEST_int_eq(remove_called, 0)))
         goto end;
 
     new_called = remove_called = 0;
@@ -872,8 +895,8 @@ static int execute_test_session(int use_int_cache, int 
use_ext_cache)
      */
     if (!TEST_true(SSL_set_session(clientssl2, sess1)))
         goto end;
-    if (use_ext_cache && !TEST_int_eq(new_called, 0)
-            && !TEST_int_eq(remove_called, 1))
+    if (use_ext_cache
+            && (!TEST_int_eq(new_called, 0) || !TEST_int_eq(remove_called, 1)))
         goto end;
     if (!TEST_ptr_eq(SSL_get_session(clientssl2), sess1))
         goto end;
@@ -890,11 +913,11 @@ static int execute_test_session(int use_int_cache, int 
use_ext_cache)
     if (!TEST_false(SSL_CTX_remove_session(cctx, sess2)))
         goto end;
 
-    if (use_ext_cache && !TEST_int_eq(new_called, 0)
-            && !TEST_int_eq(remove_called, 1))
+    if (use_ext_cache
+            && (!TEST_int_eq(new_called, 0) || !TEST_int_eq(remove_called, 1)))
         goto end;
 
-#if !defined(OPENSSL_NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_2)
+#if !defined(OPENSSL_NO_TLS1_1)
     new_called = remove_called = 0;
     /* Force a connection failure */
     SSL_CTX_set_max_proto_version(sctx, TLS1_1_VERSION);
@@ -907,8 +930,8 @@ static int execute_test_session(int use_int_cache, int 
use_ext_cache)
         goto end;
 
     /* We should have automatically removed the session from the cache */
-    if (use_ext_cache && !TEST_int_eq(new_called, 0)
-            && !TEST_int_eq(remove_called, 1))
+    if (use_ext_cache
+            && (!TEST_int_eq(new_called, 0) || !TEST_int_eq(remove_called, 1)))
         goto end;
 
     /* Should succeed because it should not already be in the cache */
@@ -916,6 +939,81 @@ static int execute_test_session(int use_int_cache, int 
use_ext_cache)
         goto end;
 #endif
 
+    /* Now do some tests for server side caching */
+    if (use_ext_cache) {
+        SSL_CTX_sess_set_new_cb(cctx, NULL);
+        SSL_CTX_sess_set_remove_cb(cctx, NULL);
+        SSL_CTX_sess_set_new_cb(sctx, new_session_cb);
+        SSL_CTX_sess_set_remove_cb(sctx, remove_session_cb);
+        SSL_CTX_sess_set_get_cb(sctx, get_session_cb);
+        get_sess_val = NULL;
+    }
+
+    SSL_CTX_set_session_cache_mode(cctx, 0);
+    /* Internal caching is the default on the server side */
+    if (!use_int_cache)
+        SSL_CTX_set_session_cache_mode(sctx,
+                                       SSL_SESS_CACHE_SERVER
+                                       | SSL_SESS_CACHE_NO_INTERNAL_STORE);
+
+    SSL_free(serverssl1);
+    SSL_free(clientssl1);
+    serverssl1 = clientssl1 = NULL;
+    SSL_free(serverssl2);
+    SSL_free(clientssl2);
+    serverssl2 = clientssl2 = NULL;
+    SSL_SESSION_free(sess1);
+    sess1 = NULL;
+    SSL_SESSION_free(sess2);
+    sess2 = NULL;
+
+    SSL_CTX_set_max_proto_version(sctx, maxprot);
+    SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
+    new_called = remove_called = 0;
+    if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1,
+                                      NULL, NULL))
+            || !TEST_true(create_ssl_connection(serverssl1, clientssl1,
+                                                SSL_ERROR_NONE))
+            || !TEST_ptr(sess1 = SSL_get1_session(clientssl1))
+            || !TEST_ptr(sess2 = SSL_get1_session(serverssl1)))
+        goto end;
+
+    /* Should fail because it should already be in the cache */
+    if (use_int_cache && !TEST_false(SSL_CTX_add_session(sctx, sess2)))
+        goto end;
+
+    if (use_ext_cache) {
+        SSL_SESSION *tmp = sess2;
+
+        if (!TEST_int_eq(new_called, 1) || !TEST_int_eq(remove_called, 0))
+            goto end;
+        /*
+         * Delete the session from the internal cache to force a lookup from
+         * the external cache. We take a copy first because
+         * SSL_CTX_remove_session() also marks the session as non-resumable.
+         */
+        if (use_int_cache
+                && (!TEST_ptr(tmp = SSL_SESSION_dup(sess2))
+                    || !TEST_true(SSL_CTX_remove_session(sctx, sess2))))
+            goto end;
+        sess2 = tmp;
+    }
+
+    new_called = remove_called = 0;
+    get_sess_val = sess2;
+    if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl2,
+                                      &clientssl2, NULL, NULL))
+            || !TEST_true(SSL_set_session(clientssl2, sess1))
+            || !TEST_true(create_ssl_connection(serverssl2, clientssl2,
+                                                SSL_ERROR_NONE))
+            || !TEST_true(SSL_session_reused(clientssl2)))
+        goto end;
+
+    if (use_ext_cache
+            && (!TEST_int_eq(new_called, 0)
+                || !TEST_int_eq(remove_called, 0)))
+        goto end;
+
     testresult = 1;
 
  end:
@@ -937,17 +1035,44 @@ static int execute_test_session(int use_int_cache, int 
use_ext_cache)
 
 static int test_session_with_only_int_cache(void)
 {
-    return execute_test_session(1, 0);
+#ifndef OPENSSL_NO_TLS1_3
+    if (!execute_test_session(TLS1_3_VERSION, 1, 0))
+        return 0;
+#endif
+
+#ifndef OPENSSL_NO_TLS1_2
+    return execute_test_session(TLS1_2_VERSION, 1, 0);
+#else
+    return 1;
+#endif
 }
 
 static int test_session_with_only_ext_cache(void)
 {
-    return execute_test_session(0, 1);
+#ifndef OPENSSL_NO_TLS1_3
+    if (!execute_test_session(TLS1_3_VERSION, 0, 1))
+        return 0;
+#endif
+
+#ifndef OPENSSL_NO_TLS1_2
+    return execute_test_session(TLS1_2_VERSION, 0, 1);
+#else
+    return 1;
+#endif
 }
 
 static int test_session_with_both_cache(void)
 {
-    return execute_test_session(1, 1);
+#ifndef OPENSSL_NO_TLS1_3
+    if (!execute_test_session(TLS1_3_VERSION, 1, 1))
+        return 0;
+#endif
+
+#ifndef OPENSSL_NO_TLS1_2
+    return execute_test_session(TLS1_2_VERSION, 1, 1);
+#else
+    return 1;
+#endif
 }
 
 #define USE_NULL    0
diff --git a/util/libssl.num b/util/libssl.num
index 6a93ecb..78fb65a 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -462,3 +462,4 @@ SSL_SESSION_set_protocol_version        462 1_1_1   
EXIST::FUNCTION:
 OPENSSL_cipher_name                     463    1_1_1   EXIST::FUNCTION:
 SSL_alloc_buffers                       464    1_1_1   EXIST::FUNCTION:
 SSL_free_buffers                        465    1_1_1   EXIST::FUNCTION:
+SSL_SESSION_dup                         466    1_1_1   EXIST::FUNCTION:
_____
openssl-commits mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-commits

Reply via email to