summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/openssl/ssl.h4
-rw-r--r--ssl/record/ssl3_record.c11
-rw-r--r--ssl/ssl_lib.c35
-rw-r--r--ssl/ssl_locl.h22
-rw-r--r--util/libssl.num4
5 files changed, 71 insertions, 5 deletions
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index bbcfb3c0b3..2376828e70 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -919,6 +919,10 @@ int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data);
uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx);
int SSL_set_max_early_data(SSL *s, uint32_t max_early_data);
uint32_t SSL_get_max_early_data(const SSL *s);
+int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data);
+uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx);
+int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data);
+uint32_t SSL_get_recv_max_early_data(const SSL *s);
#ifdef __cplusplus
}
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index ae510b2ec9..ad478bf375 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -103,7 +103,7 @@ static int ssl3_record_app_data_waiting(SSL *s)
int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send)
{
- uint32_t max_early_data = s->max_early_data;
+ uint32_t max_early_data;
SSL_SESSION *sess = s->session;
/*
@@ -120,9 +120,14 @@ int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send)
}
sess = s->psksession;
}
- if (!s->server
- || (s->hit && sess->ext.max_early_data < s->max_early_data))
+
+ if (!s->server)
max_early_data = sess->ext.max_early_data;
+ else if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED)
+ max_early_data = s->recv_max_early_data;
+ else
+ max_early_data = s->recv_max_early_data < sess->ext.max_early_data
+ ? s->recv_max_early_data : sess->ext.max_early_data;
if (max_early_data == 0) {
SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE,
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 1387067b30..38391fd2c0 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -700,6 +700,7 @@ SSL *SSL_new(SSL_CTX *ctx)
s->mode = ctx->mode;
s->max_cert_list = ctx->max_cert_list;
s->max_early_data = ctx->max_early_data;
+ s->recv_max_early_data = ctx->recv_max_early_data;
s->num_tickets = ctx->num_tickets;
/* Shallow copy of the ciphersuites stack */
@@ -3039,6 +3040,16 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
*/
ret->max_early_data = 0;
+ /*
+ * Default recv_max_early_data is a fully loaded single record. Could be
+ * split across multiple records in practice. We set this differently to
+ * max_early_data so that, in the default case, we do not advertise any
+ * support for early_data, but if a client were to send us some (e.g.
+ * because of an old, stale ticket) then we will tolerate it and skip over
+ * it.
+ */
+ ret->recv_max_early_data = SSL3_RT_MAX_PLAIN_LENGTH;
+
/* By default we send two session tickets automatically in TLSv1.3 */
ret->num_tickets = 2;
@@ -5376,6 +5387,30 @@ uint32_t SSL_get_max_early_data(const SSL *s)
return s->max_early_data;
}
+int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data)
+{
+ ctx->recv_max_early_data = recv_max_early_data;
+
+ return 1;
+}
+
+uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx)
+{
+ return ctx->recv_max_early_data;
+}
+
+int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data)
+{
+ s->recv_max_early_data = recv_max_early_data;
+
+ return 1;
+}
+
+uint32_t SSL_get_recv_max_early_data(const SSL *s)
+{
+ return s->recv_max_early_data;
+}
+
__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl)
{
/* Return any active Max Fragment Len extension */
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 6a2edeb190..0bf3f16f35 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1032,9 +1032,18 @@ struct ssl_ctx_st {
*/
SSL_CTX_keylog_cb_func keylog_callback;
- /* The maximum number of bytes that can be sent as early data */
+ /*
+ * The maximum number of bytes advertised in session tickets that can be
+ * sent as early data.
+ */
uint32_t max_early_data;
+ /*
+ * The maximum number of bytes of early data that a server will tolerate
+ * (which should be at least as much as max_early_data).
+ */
+ uint32_t recv_max_early_data;
+
/* TLS1.3 padding callback */
size_t (*record_padding_cb)(SSL *s, int type, size_t len, void *arg);
void *record_padding_arg;
@@ -1406,9 +1415,18 @@ struct ssl_st {
ASYNC_WAIT_CTX *waitctx;
size_t asyncrw;
- /* The maximum number of plaintext bytes that can be sent as early data */
+ /*
+ * The maximum number of bytes advertised in session tickets that can be
+ * sent as early data.
+ */
uint32_t max_early_data;
/*
+ * The maximum number of bytes of early data that a server will tolerate
+ * (which should be at least as much as max_early_data).
+ */
+ uint32_t recv_max_early_data;
+
+ /*
* The number of bytes of early data received so far. If we accepted early
* data then this is a count of the plaintext bytes. If we rejected it then
* this is a count of the ciphertext bytes.
diff --git a/util/libssl.num b/util/libssl.num
index df6a71e1b5..9b6d266144 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -492,3 +492,7 @@ SSL_get_num_tickets 492 1_1_1 EXIST::FUNCTION:
SSL_CTX_set_num_tickets 493 1_1_1 EXIST::FUNCTION:
SSL_CTX_set_allow_early_data_cb 494 1_1_1 EXIST::FUNCTION:
SSL_set_allow_early_data_cb 495 1_1_1 EXIST::FUNCTION:
+SSL_set_recv_max_early_data 496 1_1_1 EXIST::FUNCTION:
+SSL_get_recv_max_early_data 497 1_1_1 EXIST::FUNCTION:
+SSL_CTX_get_recv_max_early_data 498 1_1_1 EXIST::FUNCTION:
+SSL_CTX_set_recv_max_early_data 499 1_1_1 EXIST::FUNCTION: