Don't fail on an out-of-order CCS in DTLS
Fixes #4929
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6170)
diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c
index 1f221e7..e836769 100644
--- a/ssl/statem/statem.c
+++ b/ssl/statem/statem.c
@@ -589,10 +589,8 @@
* Validate that we are allowed to move to the new state and move
* to that state if so
*/
- if (!transition(s, mt)) {
- check_fatal(s, SSL_F_READ_STATE_MACHINE);
+ if (!transition(s, mt))
return SUB_STATE_ERROR;
- }
if (s->s3->tmp.message_size > max_message_size(s)) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_READ_STATE_MACHINE,
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 91b986f..60e987a 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -375,6 +375,20 @@
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;
+ }
SSLfatal(s, SSL3_AD_UNEXPECTED_MESSAGE,
SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION,
SSL_R_UNEXPECTED_MESSAGE);
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index aa38fad..018daaa 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -277,6 +277,20 @@
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;
+ }
SSLfatal(s, SSL3_AD_UNEXPECTED_MESSAGE,
SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION,
SSL_R_UNEXPECTED_MESSAGE);