[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Wed Apr 26 15:51:37 UTC 2017


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 <matt at openssl.org>
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 <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit 5b3e5f00a63446a5de633277a33dc013c22e7231
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Apr 26 15:14:03 2017 +0100

    More SSL_SESSION documentation tweaks based on feedback
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit 35ea9edfb255aa3faab69afd4f2bd2fd64dafd4b
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Mar 23 11:56:46 2017 +0000

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

commit 150840b9443d371bfa26e2a33051aa137b5606fc
Author: Matt Caswell <matt at openssl.org>
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 <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit 6ff71494687cf9ed83ef20ea7d5f75b754c06525
Author: Matt Caswell <matt at openssl.org>
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 <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit e586eac8858c3ea1f6094f5a3ea489e8e7f1973a
Author: Matt Caswell <matt at openssl.org>
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 <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3008)

commit 3348fc7e8940b66ab4545a618ba87a63fb677a79
Author: Matt Caswell <matt at openssl.org>
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 <rsalz at openssl.org>
    (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:


More information about the openssl-commits mailing list