Don't fail on an out-of-order CCS in DTLS
authorMatt Caswell <matt@openssl.org>
Thu, 3 May 2018 11:07:47 +0000 (12:07 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 11 May 2018 12:54:56 +0000 (13:54 +0100)
Fixes #4929

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6196)

ssl/statem/statem.c
ssl/statem/statem_clnt.c
ssl/statem/statem_srvr.c

index b91ec0a360a339f1fe9905f727c9a95c54f6d3b8..69bb40f00e114f984a99c1dfae5c0e2feb819fd4 100644 (file)
@@ -556,10 +556,8 @@ static SUB_STATE_RETURN read_state_machine(SSL *s)
              * Validate that we are allowed to move to the new state and move
              * to that state if so
              */
-            if (!transition(s, mt)) {
-                ossl_statem_set_error(s);
+            if (!transition(s, mt))
                 return SUB_STATE_ERROR;
-            }
 
             if (s->s3->tmp.message_size > max_message_size(s)) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
index 6fa3f1db67028c28520662cc258d7277b590339a..7ffc63458fa3b20f30c376907ef5975a1e728bf5 100644 (file)
@@ -265,6 +265,21 @@ int ossl_statem_client_read_transition(SSL *s, int mt)
 
  err:
     /* No valid transition found */
+    if (SSL_IS_DTLS(s) && mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+        BIO *rbio;
+
+        /*
+         * CCS messages don't have a message sequence number so this is probably
+         * because of an out-of-order CCS. We'll just drop it.
+         */
+        s->init_num = 0;
+        s->rwstate = SSL_READING;
+        rbio = SSL_get_rbio(s);
+        BIO_clear_retry_flags(rbio);
+        BIO_set_retry_read(rbio);
+        return 0;
+    }
+    ossl_statem_set_error(s);
     ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
     SSLerr(SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION, SSL_R_UNEXPECTED_MESSAGE);
     return 0;
index f216db76c60b8df19c24627280b9b12dbe50b293..5591e1e584280d9988c8359af930f1c2d5e7b034 100644 (file)
@@ -213,6 +213,21 @@ int ossl_statem_server_read_transition(SSL *s, int mt)
     }
 
     /* No valid transition found */
+    if (SSL_IS_DTLS(s) && mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+        BIO *rbio;
+
+        /*
+         * CCS messages don't have a message sequence number so this is probably
+         * because of an out-of-order CCS. We'll just drop it.
+         */
+        s->init_num = 0;
+        s->rwstate = SSL_READING;
+        rbio = SSL_get_rbio(s);
+        BIO_clear_retry_flags(rbio);
+        BIO_set_retry_read(rbio);
+        return 0;
+    }
+    ossl_statem_set_error(s);
     ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
     SSLerr(SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, SSL_R_UNEXPECTED_MESSAGE);
     return 0;