Don't attempt to write more early_data than we know the server will accept
authorMatt Caswell <matt@openssl.org>
Fri, 24 Feb 2017 13:51:04 +0000 (13:51 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 2 Mar 2017 17:44:15 +0000 (17:44 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2737)

ssl/record/rec_layer_s3.c
ssl/record/ssl3_record.c

index 1dc2956..2cdc62d 100644 (file)
@@ -348,6 +348,10 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len,
         return -1;
     }
 
+    if (s->early_data_state == SSL_EARLY_DATA_WRITING
+            && !early_data_count_ok(s, len, 0, NULL))
+        return -1;
+
     s->rlayer.wnum = 0;
 
     if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s)) {
index 50582d1..4149969 100644 (file)
@@ -106,14 +106,17 @@ int early_data_count_ok(SSL *s, size_t length, size_t overhead, int *al)
     uint32_t max_early_data = s->max_early_data;
 
     /*
-     * We go with the lowest out of the max early data set in the session
-     * and the configured max_early_data.
+     * If we are a client then we always use the max_early_data from the
+     * session. Otherwise we go with the lowest out of the max early data set in
+     * the session and the configured max_early_data.
      */
-    if (s->hit && s->session->ext.max_early_data < s->max_early_data)
+    if (!s->server || (s->hit
+                       && s->session->ext.max_early_data < s->max_early_data))
         max_early_data = s->session->ext.max_early_data;
 
     if (max_early_data == 0) {
-        *al = SSL_AD_UNEXPECTED_MESSAGE;
+        if (al != NULL)
+            *al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_EARLY_DATA_COUNT_OK, SSL_R_TOO_MUCH_EARLY_DATA);
         return 0;
     }
@@ -121,12 +124,13 @@ int early_data_count_ok(SSL *s, size_t length, size_t overhead, int *al)
     /* If we are dealing with ciphertext we need to allow for the overhead */
     max_early_data += overhead;
 
-    s->early_data_count += length;
-    if (s->early_data_count > max_early_data) {
-        *al = SSL_AD_UNEXPECTED_MESSAGE;
+    if (s->early_data_count + length > max_early_data) {
+        if (al != NULL)
+            *al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_EARLY_DATA_COUNT_OK, SSL_R_TOO_MUCH_EARLY_DATA);
         return 0;
     }
+    s->early_data_count += length;
 
     return 1;
 }