Only allow SSL_set_session before the handshake.
Otherwise things break horribly. Explicitly abort to help catch bugs.
Change-Id: I66e2bf8808199b3331b3adde68d73758a601eb8c
Reviewed-on: https://boringssl-review.googlesource.com/10761
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index ce2ba41..4ff25ce 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1683,7 +1683,9 @@
/* SSL_set_session, for a client, configures |ssl| to offer to resume |session|
* in the initial handshake and returns one. The caller retains ownership of
- * |session|. */
+ * |session|.
+ *
+ * It is an error to call this function after the handshake has begun. */
OPENSSL_EXPORT int SSL_set_session(SSL *ssl, SSL_SESSION *session);
/* SSL_get_session returns a non-owning pointer to |ssl|'s session. For
diff --git a/ssl/handshake_client.c b/ssl/handshake_client.c
index 9a5cd02..c8177b4 100644
--- a/ssl/handshake_client.c
+++ b/ssl/handshake_client.c
@@ -728,7 +728,7 @@
ssl->session->not_resumable ||
!ssl_session_is_time_valid(ssl, ssl->session) ||
session_version < min_version || session_version > max_version) {
- SSL_set_session(ssl, NULL);
+ ssl_set_session(ssl, NULL);
}
}
@@ -896,7 +896,7 @@
} else {
/* The session wasn't resumed. Create a fresh SSL_SESSION to
* fill out. */
- SSL_set_session(ssl, NULL);
+ ssl_set_session(ssl, NULL);
if (!ssl_get_new_session(ssl, 0 /* client */)) {
goto f_err;
}
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index c5bd4be..f7c127d 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -719,7 +719,7 @@
session = NULL;
ssl->s3->session_reused = 1;
} else {
- SSL_set_session(ssl, NULL);
+ ssl_set_session(ssl, NULL);
if (!ssl_get_new_session(ssl, 1 /* server */)) {
goto err;
}
diff --git a/ssl/internal.h b/ssl/internal.h
index 660ba79..f285682 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1262,6 +1262,8 @@
* it has expired. */
int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session);
+void ssl_set_session(SSL *ssl, SSL_SESSION *session);
+
enum ssl_session_result_t {
ssl_session_success,
ssl_session_error,
diff --git a/ssl/ssl_session.c b/ssl/ssl_session.c
index 3a56dcd..78dfeab 100644
--- a/ssl/ssl_session.c
+++ b/ssl/ssl_session.c
@@ -136,6 +136,7 @@
#include <openssl/ssl.h>
#include <assert.h>
+#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
@@ -482,7 +483,7 @@
SSL_SESSION_free(ssl->s3->new_session);
ssl->s3->new_session = session;
- SSL_set_session(ssl, NULL);
+ ssl_set_session(ssl, NULL);
return 1;
err:
@@ -792,8 +793,18 @@
}
int SSL_set_session(SSL *ssl, SSL_SESSION *session) {
+ /* SSL_set_session may only be called before the handshake has started. */
+ if (ssl->state != SSL_ST_INIT || ssl->s3->initial_handshake_complete) {
+ abort();
+ }
+
+ ssl_set_session(ssl, session);
+ return 1;
+}
+
+void ssl_set_session(SSL *ssl, SSL_SESSION *session) {
if (ssl->session == session) {
- return 1;
+ return;
}
SSL_SESSION_free(ssl->session);
@@ -801,8 +812,6 @@
if (session != NULL) {
SSL_SESSION_up_ref(session);
}
-
- return 1;
}
long SSL_CTX_set_timeout(SSL_CTX *ctx, long timeout) {
diff --git a/ssl/tls13_client.c b/ssl/tls13_client.c
index d2d99a7..8dfb5da 100644
--- a/ssl/tls13_client.c
+++ b/ssl/tls13_client.c
@@ -228,7 +228,7 @@
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
- SSL_set_session(ssl, NULL);
+ ssl_set_session(ssl, NULL);
} else {
if (!ssl_get_new_session(ssl, 0)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);