Tighten sanity checks when calling early data functions
[openssl.git] / ssl / ssl_lib.c
index 2f62f4b0e1bfa24854e54b1b1d5edc7d6e31d6ff..b675c2eeadca335093234bbfa76509ae79c45082 100644 (file)
@@ -1545,6 +1545,14 @@ int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
         return 0;
     }
 
+    if (s->early_data_state != SSL_EARLY_DATA_NONE
+            && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING
+            && s->early_data_state != SSL_EARLY_DATA_FINISHED_READING
+            && s->early_data_state != SSL_EARLY_DATA_READING) {
+        SSLerr(SSL_F_SSL_READ_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
     if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
         struct ssl_async_args args;
         int ret;
@@ -1603,11 +1611,6 @@ int SSL_read_early(SSL *s, void *buf, size_t num, size_t *readbytes)
         return SSL_READ_EARLY_ERROR;
     }
 
-    /*
-     * TODO(TLS1.3): Somehow we need to check that we're not receiving too much
-     * data
-     */
-
     switch (s->early_data_state) {
     case SSL_EARLY_DATA_NONE:
         if (!SSL_in_before(s)) {
@@ -1664,7 +1667,7 @@ int ssl_end_of_early_data_seen(SSL *s)
     return 0;
 }
 
-int SSL_get_early_data_status(SSL *s)
+int SSL_get_early_data_status(const SSL *s)
 {
     return s->ext.early_data;
 }
@@ -1742,9 +1745,13 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written)
         return -1;
     }
 
-    if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
-            || s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY)
+    if (s->early_data_state != SSL_EARLY_DATA_NONE
+            && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING
+            && s->early_data_state != SSL_EARLY_DATA_FINISHED_READING
+            && s->early_data_state != SSL_EARLY_DATA_WRITING) {
+        SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
         return 0;
+    }
 
     if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
         int ret;
@@ -1804,14 +1811,11 @@ int SSL_write_early(SSL *s, const void *buf, size_t num, size_t *written)
         return 0;
     }
 
-    /*
-     * TODO(TLS1.3): Somehow we need to check that we're not sending too much
-     * data
-     */
-
     switch (s->early_data_state) {
     case SSL_EARLY_DATA_NONE:
-        if (!SSL_in_before(s)) {
+        if (!SSL_in_before(s)
+                || s->session == NULL
+                || s->session->ext.max_early_data == 0) {
             SSLerr(SSL_F_SSL_WRITE_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return 0;
         }
@@ -2772,6 +2776,12 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
 
     ret->ext.status_type = TLSEXT_STATUSTYPE_nothing;
 
+    /*
+     * Default max early data is a fully loaded single record. Could be split
+     * across multiple records in practice
+     */
+    ret->max_early_data = SSL3_RT_MAX_PLAIN_LENGTH;
+
     return ret;
  err:
     SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
@@ -4819,7 +4829,7 @@ int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data)
     return 1;
 }
 
-uint32_t SSL_CTX_get_max_early_data(SSL_CTX *ctx)
+uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx)
 {
     return ctx->max_early_data;
 }
@@ -4831,7 +4841,7 @@ int SSL_set_max_early_data(SSL *s, uint32_t max_early_data)
     return 1;
 }
 
-uint32_t SSL_get_max_early_data(SSL_CTX *s)
+uint32_t SSL_get_max_early_data(const SSL_CTX *s)
 {
     return s->max_early_data;
 }