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)
* - Both for new and resumed sessions, s->ext.ticket_expected is set to 1
* if the server should issue a new session ticket (to 0 otherwise).
*/
-int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)
+int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello, int *al)
{
/* This is used only by servers. */
SSL_SESSION *ret = NULL;
int fatal = 0;
int try_session_cache = 0;
- int r;
+ TICKET_RETURN r;
if (SSL_IS_TLS13(s)) {
- int al;
-
- if (!tls_parse_extension(s, TLSEXT_IDX_psk, EXT_CLIENT_HELLO,
- hello->pre_proc_exts, NULL, 0, &al))
+ 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;
ret = s->session;
/* sets s->ext.ticket_expected */
r = tls_get_ticket_from_client(s, hello, &ret);
switch (r) {
- case -1: /* Error during processing */
+ case TICKET_FATAL_ERR_MALLOC:
+ case TICKET_FATAL_ERR_OTHER:
fatal = 1;
goto err;
- case 0: /* No ticket found */
- case 1: /* Zero length ticket found */
+ case TICKET_NONE:
+ case TICKET_EMPTY:
try_session_cache = 1;
- break; /* Ok to carry on processing session id. */
- case 2: /* Ticket found but not decrypted. */
- case 3: /* Ticket decrypted, *ret has been set. */
break;
- default:
- abort();
+ case TICKET_NO_DECRYPT:
+ case TICKET_SUCCESS:
+ case TICKET_SUCCESS_RENEW:
+ break;
}
}
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;
/* 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;
}
s->session_ctx->stats.sess_hit++;
s->verify_result = s->session->verify_result;
-
return 1;
err:
if (ret != NULL) {
SSL_SESSION_free(ret);
- /* In TLSv1.3 we already set s->session, so better NULL it out */
+ /* In TLSv1.3 s->session was already set to ret, so we NULL it out */
if (SSL_IS_TLS13(s))
s->session = NULL;
s->ext.ticket_expected = 1;
}
}
- if (fatal)
+ 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)
#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));
}
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;
}
*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;
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;