The branch master has been updated
       via  b89646684d920d3014979f8a73b96aecb61c7b1f (commit)
       via  5b3e5f00a63446a5de633277a33dc013c22e7231 (commit)
       via  35ea9edfb255aa3faab69afd4f2bd2fd64dafd4b (commit)
       via  150840b9443d371bfa26e2a33051aa137b5606fc (commit)
       via  6ff71494687cf9ed83ef20ea7d5f75b754c06525 (commit)
       via  e586eac8858c3ea1f6094f5a3ea489e8e7f1973a (commit)
       via  3348fc7e8940b66ab4545a618ba87a63fb677a79 (commit)
      from  b6e3250671654e0344127be9dd49b3fb4a82f94b (commit)


- Log -----------------------------------------------------------------
commit b89646684d920d3014979f8a73b96aecb61c7b1f
Author: Matt Caswell <[email protected]>
Date:   Wed Apr 26 15:16:18 2017 +0100

    Clarify that SSL_CTX_remove_session() marks a session as non-resumable
    
    Reviewed-by: Rich Salz <[email protected]>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit 5b3e5f00a63446a5de633277a33dc013c22e7231
Author: Matt Caswell <[email protected]>
Date:   Wed Apr 26 15:14:03 2017 +0100

    More SSL_SESSION documentation tweaks based on feedback
    
    Reviewed-by: Rich Salz <[email protected]>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit 35ea9edfb255aa3faab69afd4f2bd2fd64dafd4b
Author: Matt Caswell <[email protected]>
Date:   Thu Mar 23 11:56:46 2017 +0000

    Tweak SSL_get_session.pod wording
    
    Based on feedback received.
    
    Reviewed-by: Rich Salz <[email protected]>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit 150840b9443d371bfa26e2a33051aa137b5606fc
Author: Matt Caswell <[email protected]>
Date:   Thu Mar 23 11:22:26 2017 +0000

    Always duplicate the session on NewSessionTicket in TLSv1.3
    
    Because NST messages arrive post-handshake, the session may have already
    gone into the cache. Once in the cache a session must be immutable -
    otherwise you could get multi-thread issues.
    
    Reviewed-by: Rich Salz <[email protected]>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit 6ff71494687cf9ed83ef20ea7d5f75b754c06525
Author: Matt Caswell <[email protected]>
Date:   Tue Mar 21 13:51:03 2017 +0000

    Documentation updates for TLSv1.3 sessions
    
    Add documentation for SSL_SESSION_is_resumable(). Also describe the 
interaction
    of the various session functions and TLSv1.3 post-handshake sessions.
    
    Reviewed-by: Rich Salz <[email protected]>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit e586eac8858c3ea1f6094f5a3ea489e8e7f1973a
Author: Matt Caswell <[email protected]>
Date:   Tue Mar 21 13:50:31 2017 +0000

    Add support for SSL_SESSION_is_resumable()
    
    Provide a way to test whether the SSL_SESSION object can be used to resume a
    sesion or not.
    
    Reviewed-by: Rich Salz <[email protected]>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit 3348fc7e8940b66ab4545a618ba87a63fb677a79
Author: Matt Caswell <[email protected]>
Date:   Tue Mar 21 13:48:52 2017 +0000

    Remove TLS1.3 TODO around testing for session id length
    
    TLSv1.3 will do the same thing as TLSv1.2 with tickets with regards to 
session
    ids, i.e. it will create a synthetic session id when the session is 
established,
    so it is reasonable to check the session id length, even in TLSv1.3.
    
    Reviewed-by: Rich Salz <[email protected]>
    (Merged from https://github.com/openssl/openssl/pull/3008)

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

Summary of changes:
 doc/man3/SSL_CTX_add_session.pod      |  4 ++--
 doc/man3/SSL_CTX_sess_set_get_cb.pod  | 13 +++++++++++-
 doc/man3/SSL_SESSION_is_resumable.pod | 40 +++++++++++++++++++++++++++++++++++
 doc/man3/SSL_get_session.pod          | 25 +++++++++++++++++++++-
 include/openssl/ssl.h                 |  1 +
 ssl/ssl_sess.c                        | 22 +++++++++++++------
 ssl/statem/statem_clnt.c              | 21 ++++++++++--------
 util/libssl.num                       |  1 +
 8 files changed, 108 insertions(+), 19 deletions(-)
 create mode 100644 doc/man3/SSL_SESSION_is_resumable.pod

diff --git a/doc/man3/SSL_CTX_add_session.pod b/doc/man3/SSL_CTX_add_session.pod
index dd92c3a..02d93b8 100644
--- a/doc/man3/SSL_CTX_add_session.pod
+++ b/doc/man3/SSL_CTX_add_session.pod
@@ -21,8 +21,8 @@ reference count for session B<c> is incremented by 1. If a 
session with
 the same session id already exists, the old session is removed by calling
 L<SSL_SESSION_free(3)>.
 
-SSL_CTX_remove_session() removes the session B<c> from the context B<ctx>.
-L<SSL_SESSION_free(3)> is called once for B<c>.
+SSL_CTX_remove_session() removes the session B<c> from the context B<ctx> and
+marks it as non-resumable. L<SSL_SESSION_free(3)> is called once for B<c>.
 
 SSL_add_session() and SSL_remove_session() are synonyms for their
 SSL_CTX_*() counterparts.
diff --git a/doc/man3/SSL_CTX_sess_set_get_cb.pod 
b/doc/man3/SSL_CTX_sess_set_get_cb.pod
index ebea4c5..65f1e4e 100644
--- a/doc/man3/SSL_CTX_sess_set_get_cb.pod
+++ b/doc/man3/SSL_CTX_sess_set_get_cb.pod
@@ -57,7 +57,18 @@ and session caching is enabled (see
 L<SSL_CTX_set_session_cache_mode(3)>).
 The new_session_cb() is passed the B<ssl> connection and the ssl session
 B<sess>. If the callback returns B<0>, the session will be immediately
-removed again.
+removed again. Note that in TLSv1.3, sessions are established after the main
+handshake has completed. The server decides when to send the client the session
+information and this may occur some time after the end of the handshake (or not
+at all). This means that applications should expect the new_session_cb()
+function to be invoked during the handshake (for <= TLSv1.2) or after the
+handshake (for TLSv1.3). It is also possible in TLSv1.3 for multiple sessions 
to
+be established with a single connection. In these case the new_session_cb()
+function will be invoked multiple times.
+
+In TLSv1.3 it is recommended that each SSL_SESSION object is only used for
+resumption once. One way of enforcing that is for applications to call
+L<SSL_CTX_remove_session(3)> after a session has been used.
 
 The remove_session_cb() is called, whenever the SSL engine removes a session
 from the internal cache. This happens when the session is removed because
diff --git a/doc/man3/SSL_SESSION_is_resumable.pod 
b/doc/man3/SSL_SESSION_is_resumable.pod
new file mode 100644
index 0000000..f0c8bab
--- /dev/null
+++ b/doc/man3/SSL_SESSION_is_resumable.pod
@@ -0,0 +1,40 @@
+=pod
+
+=head1 NAME
+
+SSL_SESSION_is_resumable
+- determine whether an SSL_SESSION object can be used for resumption
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ const SSL_CIPHER *SSL_SESSION_is_resumable(const SSL_SESSSION *s);
+
+=head1 DESCRIPTION
+
+SSL_SESSION_is_resumable() determines whether an SSL_SESSION object can be used
+to resume a session or not. Returns 1 if it can or 0 if not. Note that
+attempting to resume with a non-resumable session will result in a full
+handshake.
+
+=head1 SEE ALSO
+
+L<ssl(7)>,
+L<SSL_get_session(3)>,
+L<SSL_CTX_sess_set_new_cb(3)>
+
+=head1 HISTORY
+
+SSL_SESSION_is_resumable() was first added to OpenSSL 1.1.1
+
+=head1 COPYRIGHT
+
+Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the OpenSSL license (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/SSL_get_session.pod b/doc/man3/SSL_get_session.pod
index d753b27..b2e92af 100644
--- a/doc/man3/SSL_get_session.pod
+++ b/doc/man3/SSL_get_session.pod
@@ -26,7 +26,30 @@ count of the B<SSL_SESSION> is incremented by one.
 =head1 NOTES
 
 The ssl session contains all information required to re-establish the
-connection without a new handshake.
+connection without a full handshake for SSL versions up to and including
+TLSv1.2. In TLSv1.3 the same is true, but sessions are established after the
+main handshake has occurred. The server will send the session information to 
the
+client at a time of its choosing, which may be some while after the initial
+connection is established (or never). Calling these functions on the client 
side
+in TLSv1.3 before the session has been established will still return an
+SSL_SESSION object but that object cannot be used for resuming the session. See
+L<SSL_SESSION_is_resumable(3)> for information on how to determine whether an
+SSL_SESSION object can be used for resumption or not.
+
+Additionally, in TLSv1.3, a server can send multiple messages that establish a
+session for a single connection. In that case the above functions will only
+return information on the last session that was received.
+
+The preferred way for applications to obtain a resumable SSL_SESSION object is
+to use a new session callback as described in L<SSL_CTX_sess_set_new_cb(3)>.
+The new session callback is only invoked when a session is actually 
established,
+so this avoids the problem described above where an application obtains an
+SSL_SESSION object that cannot be used for resumption in TLSv1.3. It also
+enables applications to obtain information about all sessions sent by the
+server.
+
+In TLSv1.3 it is recommended that each SSL_SESSION object is only used for
+resumption once.
 
 SSL_get0_session() returns a pointer to the actual session. As the
 reference counter is not incremented, the pointer is only valid while
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index c14859f..317451e 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1502,6 +1502,7 @@ __owur int SSL_SESSION_set1_id_context(SSL_SESSION *s, 
const unsigned char *sid_
                                 unsigned int sid_ctx_len);
 __owur int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid,
                                unsigned int sid_len);
+__owur int SSL_SESSION_is_resumable(const SSL_SESSION *s);
 
 __owur SSL_SESSION *SSL_SESSION_new(void);
 const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index d1a4014..7a3d858 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -46,12 +46,12 @@ static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION 
*s);
 static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
 
 /*
- * TODO(TLS1.3): SSL_get_session() and SSL_get1_session() are problematic in
- * TLS1.3 because, unlike in earlier protocol versions, the session ticket
- * may not have been sent yet even though a handshake has finished. The session
- * ticket data could come in sometime later...or even change if multiple 
session
- * ticket messages are sent from the server. We need to work out how to deal
- * with this.
+ * SSL_get_session() and SSL_get1_session() are problematic in TLS1.3 because,
+ * unlike in earlier protocol versions, the session ticket may not have been
+ * sent yet even though a handshake has finished. The session ticket data could
+ * come in sometime later...or even change if multiple session ticket messages
+ * are sent from the server. The preferred way for applications to obtain
+ * a resumable session is to use SSL_CTX_sess_set_new_cb().
  */
 
 SSL_SESSION *SSL_get_session(const SSL *ssl)
@@ -929,6 +929,16 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s, const 
unsigned char *sid_ctx,
     return 1;
 }
 
+int SSL_SESSION_is_resumable(const SSL_SESSION *s)
+{
+    /*
+     * In the case of EAP-FAST, we can have a pre-shared "ticket" without a
+     * session ID.
+     */
+    return !s->not_resumable
+           && (s->session_id_length > 0 || s->ext.ticklen > 0);
+}
+
 long SSL_CTX_set_timeout(SSL_CTX *s, long t)
 {
     long l;
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 8c4c839..ab77ba0 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1049,13 +1049,9 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt)
         return 0;
     }
 
-    if ((sess == NULL) || !ssl_version_supported(s, sess->ssl_version) ||
-        /*
-         * In the case of EAP-FAST, we can have a pre-shared
-         * "ticket" without a session ID.
-         */
-        (!sess->session_id_length && !sess->ext.tick) ||
-        (sess->not_resumable)) {
+    if (sess == NULL
+            || !ssl_version_supported(s, sess->ssl_version)
+            || !SSL_SESSION_is_resumable(sess)) {
         if (!ssl_get_new_session(s, 0))
             return 0;
     }
@@ -2442,8 +2438,15 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL 
*s, PACKET *pkt)
     if (ticklen == 0)
         return MSG_PROCESS_CONTINUE_READING;
 
-    /* TODO(TLS1.3): Is this a suitable test for TLS1.3? */
-    if (s->session->session_id_length > 0) {
+    /*
+     * Sessions must be immutable once they go into the session cache. 
Otherwise
+     * we can get multi-thread problems. Therefore we don't "update" sessions,
+     * we replace them with a duplicate. In TLSv1.3 we need to do this every
+     * time a NewSessionTicket arrives because those messages arrive
+     * post-handshake and the session may have already gone into the session
+     * cache.
+     */
+    if (SSL_IS_TLS13(s) || s->session->session_id_length > 0) {
         int i = s->session_ctx->session_cache_mode;
         SSL_SESSION *new_sess;
         /*
diff --git a/util/libssl.num b/util/libssl.num
index 49974c9..ccaf4bc 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -440,3 +440,4 @@ SSL_get0_peer_CA_list                   440 1_1_1   
EXIST::FUNCTION:
 SSL_CTX_add1_CA_list                    441    1_1_1   EXIST::FUNCTION:
 SSL_CTX_get0_CA_list                    442    1_1_1   EXIST::FUNCTION:
 SSL_CTX_add_custom_ext                  443    1_1_1   EXIST::FUNCTION:
+SSL_SESSION_is_resumable                444    1_1_1   EXIST::FUNCTION:
_____
openssl-commits mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-commits

Reply via email to