Tighten sanity checks when calling early data functions
authorMatt Caswell <matt@openssl.org>
Fri, 24 Feb 2017 16:11:03 +0000 (16:11 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 2 Mar 2017 17:44:16 +0000 (17:44 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2737)

apps/s_client.c
ssl/ssl_lib.c

index 3ecc60188344268943d134e48b1a303fba09473a..c11a634ac91f55014c81b30e65008abdc1546cf8 100644 (file)
@@ -2359,7 +2359,9 @@ int s_client_main(int argc, char **argv)
         break;
     }
 
-    if (early_data_file != NULL) {
+    if (early_data_file != NULL
+            && SSL_get0_session(con) != NULL
+            && SSL_SESSION_get_max_early_data(SSL_get0_session(con)) > 0) {
         BIO *edfile = BIO_new_file(early_data_file, "r");
         size_t readbytes, writtenbytes;
         int finish = 0;
index b36e4a7eafddbf809681ac4eb2454e9099510f4c..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;
@@ -1737,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;
@@ -1801,7 +1813,9 @@ int SSL_write_early(SSL *s, const void *buf, size_t num, size_t *written)
 
     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;
         }