TLSv1.3 alerts cannot be fragmented and only one per record
authorMatt Caswell <matt@openssl.org>
Thu, 11 May 2017 09:16:34 +0000 (10:16 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 11 May 2017 12:13:04 +0000 (13:13 +0100)
We should be validating that.

Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3436)

include/openssl/ssl.h
ssl/record/rec_layer_s3.c
ssl/ssl_err.c

index 54028f66c9d346643cfcd4691279b7433e4a93a5..23dde118086d8134de9c1897496b1851293df623 100644 (file)
@@ -2650,6 +2650,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_R_INAPPROPRIATE_FALLBACK                     373
 # define SSL_R_INCONSISTENT_COMPRESSION                   340
 # define SSL_R_INCONSISTENT_EXTMS                         104
 # define SSL_R_INAPPROPRIATE_FALLBACK                     373
 # define SSL_R_INCONSISTENT_COMPRESSION                   340
 # define SSL_R_INCONSISTENT_EXTMS                         104
+# define SSL_R_INVALID_ALERT                              205
 # define SSL_R_INVALID_COMMAND                            280
 # define SSL_R_INVALID_COMPRESSION_ALGORITHM              341
 # define SSL_R_INVALID_CONFIGURATION_NAME                 113
 # define SSL_R_INVALID_COMMAND                            280
 # define SSL_R_INVALID_COMPRESSION_ALGORITHM              341
 # define SSL_R_INVALID_CONFIGURATION_NAME                 113
index 8d0a97be98b0fd58a60d582fb4b512e5672ed20a..de112cc806fb38cc78d5c361256a70dcb84ad485 100644 (file)
@@ -1422,6 +1422,20 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
             if (SSL3_RECORD_get_length(rr) == 0)
                 SSL3_RECORD_set_read(rr);
 
             if (SSL3_RECORD_get_length(rr) == 0)
                 SSL3_RECORD_set_read(rr);
 
+            if (SSL_IS_TLS13(s)
+                    && SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
+                if (*dest_len < dest_maxlen
+                        || SSL3_RECORD_get_length(rr) != 0) {
+                    /*
+                     * TLSv1.3 forbids fragmented alerts, and only one alert
+                     * may be present in a record
+                     */
+                    al = SSL_AD_UNEXPECTED_MESSAGE;
+                    SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_INVALID_ALERT);
+                    goto f_err;
+                }
+            }
+
             if (*dest_len < dest_maxlen)
                 goto start;     /* fragment was too small */
         }
             if (*dest_len < dest_maxlen)
                 goto start;     /* fragment was too small */
         }
index 06cd8521e54d988e29a27f721482f53e646ff035..42bd6aa67896e801ca6975ae42ead2131555643e 100644 (file)
@@ -609,6 +609,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
     {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"},
     {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"},
     {ERR_REASON(SSL_R_INCONSISTENT_EXTMS), "inconsistent extms"},
     {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"},
     {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"},
     {ERR_REASON(SSL_R_INCONSISTENT_EXTMS), "inconsistent extms"},
+    {ERR_REASON(SSL_R_INVALID_ALERT), "invalid alert"},
     {ERR_REASON(SSL_R_INVALID_COMMAND), "invalid command"},
     {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),
      "invalid compression algorithm"},
     {ERR_REASON(SSL_R_INVALID_COMMAND), "invalid command"},
     {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),
      "invalid compression algorithm"},