Convert existing usage of assert() to ossl_assert() in libssl
[openssl.git] / ssl / ssl_sess.c
index 686d18a384279610881eabcd0929eeced53e9431..5bef168abd3276b45df1d49bd4b187dad0a8abb5 100644 (file)
@@ -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)
@@ -468,9 +468,10 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello, int *al)
     TICKET_RETURN r;
 
     if (SSL_IS_TLS13(s)) {
-        if (!tls_parse_extension(s, TLSEXT_IDX_psk_kex_modes, EXT_CLIENT_HELLO,
-                                 hello->pre_proc_exts, NULL, 0, al)
-                || !tls_parse_extension(s, TLSEXT_IDX_psk, EXT_CLIENT_HELLO,
+        if (!tls_parse_extension(s, TLSEXT_IDX_psk_kex_modes,
+                                 SSL_EXT_CLIENT_HELLO, hello->pre_proc_exts,
+                                 NULL, 0, al)
+                || !tls_parse_extension(s, TLSEXT_IDX_psk, SSL_EXT_CLIENT_HELLO,
                                         hello->pre_proc_exts, NULL, 0, al))
             return -1;
 
@@ -480,15 +481,15 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello, int *al)
         r = tls_get_ticket_from_client(s, hello, &ret);
         switch (r) {
         case TICKET_FATAL_ERR_MALLOC:
-        case TICKET_FATAL_ERR_OTHER: /* Error during processing */
+        case TICKET_FATAL_ERR_OTHER:
             fatal = 1;
             goto err;
-        case TICKET_NONE:            /* No ticket found */
-        case TICKET_EMPTY:           /* Zero length ticket found */
+        case TICKET_NONE:
+        case TICKET_EMPTY:
             try_session_cache = 1;
-            break;                   /* Ok to carry on processing session id. */
-        case TICKET_NO_DECRYPT:      /* Ticket found but not decrypted. */
-        case TICKET_SUCCESS:         /* Ticket decrypted, *ret has been set. */
+            break;
+        case TICKET_NO_DECRYPT:
+        case TICKET_SUCCESS:
         case TICKET_SUCCESS_RENEW:
             break;
         }
@@ -501,7 +502,6 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello, int *al)
         SSL_SESSION data;
 
         data.ssl_version = s->version;
-        memset(data.session_id, 0, sizeof(data.session_id));
         memcpy(data.session_id, hello->session_id, hello->session_id_len);
         data.session_id_length = hello->session_id_len;
 
@@ -603,7 +603,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello, int *al)
         /* If old session includes extms, but new does not: abort handshake */
         if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS)) {
             SSLerr(SSL_F_SSL_GET_PREV_SESSION, SSL_R_INCONSISTENT_EXTMS);
-            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
             fatal = 1;
             goto err;
         }
@@ -640,9 +640,9 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello, int *al)
     if (fatal) {
         *al = SSL_AD_INTERNAL_ERROR;
         return -1;
-    } else {
-        return 0;
     }
+
+    return 0;
 }
 
 int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
@@ -792,6 +792,7 @@ void SSL_SESSION_free(SSL_SESSION *ss)
 #ifndef OPENSSL_NO_SRP
     OPENSSL_free(ss->srp_username);
 #endif
+    OPENSSL_free(ss->ext.alpn_selected);
     CRYPTO_THREAD_lock_free(ss->lock);
     OPENSSL_clear_free(ss, sizeof(*ss));
 }
@@ -835,7 +836,8 @@ int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid,
       return 0;
     }
     s->session_id_length = sid_len;
-    memcpy(s->session_id, sid, sid_len);
+    if (sid != s->session_id)
+        memcpy(s->session_id, sid, sid_len);
     return 1;
 }
 
@@ -902,6 +904,11 @@ void SSL_SESSION_get0_ticket(const SSL_SESSION *s, const unsigned char **tick,
         *tick = s->ext.tick;
 }
 
+uint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *s)
+{
+    return s->ext.max_early_data;
+}
+
 X509 *SSL_SESSION_get0_peer(SSL_SESSION *s)
 {
     return s->peer;
@@ -916,11 +923,22 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
         return 0;
     }
     s->sid_ctx_length = sid_ctx_len;
-    memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
+    if (sid_ctx != s->sid_ctx)
+        memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
 
     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;