[openssl-commits] [openssl] OpenSSL_1_1_0-stable update

Matt Caswell matt at openssl.org
Fri May 11 12:57:49 UTC 2018


The branch OpenSSL_1_1_0-stable has been updated
       via  c47d1d7130c8cd3f601fc9648c6a26eb666edb44 (commit)
       via  eb49905e605241dd1369d54df264976f8ea7f823 (commit)
       via  960e7bfb32af0ff3586ae2b4953d1228fa43ea16 (commit)
       via  4771f23e28eb5d11460d72dc35c6ac2fd30f9093 (commit)
      from  2ddfe60be50bfeebd64e01b123fd7176e7226c87 (commit)


- Log -----------------------------------------------------------------
commit c47d1d7130c8cd3f601fc9648c6a26eb666edb44
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 3 16:00:51 2018 +0100

    Keep the DTLS timer running after the end of the handshake if appropriate
    
    During a full handshake the server is the last one to "speak". The timer
    should continue to run until we know that the client has received our last
    flight (e.g. because we receive some application data).
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6196)

commit eb49905e605241dd1369d54df264976f8ea7f823
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 3 16:00:05 2018 +0100

    Only auto-retry for DTLS if configured to do so
    
    Otherwise we may end up in a hang when using blocking sockets
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6196)

commit 960e7bfb32af0ff3586ae2b4953d1228fa43ea16
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 3 15:59:31 2018 +0100

    Fix s_client and s_server so that they correctly handle the DTLS timer
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6196)

commit 4771f23e28eb5d11460d72dc35c6ac2fd30f9093
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 3 12:07:47 2018 +0100

    Don't fail on an out-of-order CCS in DTLS
    
    Fixes #4929
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6196)

-----------------------------------------------------------------------

Summary of changes:
 apps/s_client.c           |  7 ++-----
 apps/s_server.c           |  7 ++-----
 ssl/record/rec_layer_d1.c | 25 +++++++++++++++++++++++++
 ssl/statem/statem.c       |  4 +---
 ssl/statem/statem_clnt.c  | 15 +++++++++++++++
 ssl/statem/statem_lib.c   | 18 ++++++++++++++++++
 ssl/statem/statem_srvr.c  | 15 +++++++++++++++
 7 files changed, 78 insertions(+), 13 deletions(-)

diff --git a/apps/s_client.c b/apps/s_client.c
index 81669d0..3c0c73e 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -2115,8 +2115,7 @@ int s_client_main(int argc, char **argv)
         FD_ZERO(&readfds);
         FD_ZERO(&writefds);
 
-        if ((SSL_version(con) == DTLS1_VERSION) &&
-            DTLSv1_get_timeout(con, &timeout))
+        if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout))
             timeoutp = &timeout;
         else
             timeoutp = NULL;
@@ -2236,10 +2235,8 @@ int s_client_main(int argc, char **argv)
             }
         }
 
-        if ((SSL_version(con) == DTLS1_VERSION)
-            && DTLSv1_handle_timeout(con) > 0) {
+        if (SSL_is_dtls(con) && DTLSv1_handle_timeout(con) > 0)
             BIO_printf(bio_err, "TIMEOUT occurred\n");
-        }
 
         if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) {
             k = SSL_write(con, &(cbuf[cbuf_off]), (unsigned int)cbuf_len);
diff --git a/apps/s_server.c b/apps/s_server.c
index 96a74c4..e8aa323 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -2155,18 +2155,15 @@ static int sv_body(int s, int stype, unsigned char *context)
             if ((i < 0) || (!i && !read_from_terminal))
                 continue;
 #else
-            if ((SSL_version(con) == DTLS1_VERSION) &&
-                DTLSv1_get_timeout(con, &timeout))
+            if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout))
                 timeoutp = &timeout;
             else
                 timeoutp = NULL;
 
             i = select(width, (void *)&readfds, NULL, NULL, timeoutp);
 
-            if ((SSL_version(con) == DTLS1_VERSION)
-                && DTLSv1_handle_timeout(con) > 0) {
+            if ((SSL_is_dtls(con)) && DTLSv1_handle_timeout(con) > 0)
                 BIO_printf(bio_err, "TIMEOUT occurred\n");
-            }
 
             if (i <= 0)
                 continue;
diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c
index c753a54..0eeed4f 100644
--- a/ssl/record/rec_layer_d1.c
+++ b/ssl/record/rec_layer_d1.c
@@ -444,6 +444,19 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
             && SSL3_RECORD_get_length(rr) != 0)
         s->rlayer.alert_count = 0;
 
+    if (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE
+            && SSL3_RECORD_get_type(rr) != SSL3_RT_CHANGE_CIPHER_SPEC
+            && !SSL_in_init(s)
+            && (s->d1->next_timeout.tv_sec != 0
+                || s->d1->next_timeout.tv_usec != 0)) {
+        /*
+         * The timer is still running but we've received something that isn't
+         * handshake data - so the peer must have finished processing our
+         * last handshake flight. Stop the timer.
+         */
+        dtls1_stop_timer(s);
+    }
+
     /* we now have a packet which can be read and processed */
 
     if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -849,6 +862,18 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
 
             dtls1_retransmit_buffered_messages(s);
             SSL3_RECORD_set_length(rr, 0);
+            if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+                if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
+                    /* no read-ahead left? */
+                    BIO *bio;
+
+                    s->rwstate = SSL_READING;
+                    bio = SSL_get_rbio(s);
+                    BIO_clear_retry_flags(bio);
+                    BIO_set_retry_read(bio);
+                    return -1;
+                }
+            }
             goto start;
         }
 
diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c
index b91ec0a..69bb40f 100644
--- a/ssl/statem/statem.c
+++ b/ssl/statem/statem.c
@@ -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);
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 6fa3f1d..7ffc634 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -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;
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index c4d4f26..eba4c6f 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -299,6 +299,15 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
 
             s->ctx->stats.sess_accept_good++;
             s->handshake_func = ossl_statem_accept;
+
+            if (SSL_IS_DTLS(s) && !s->hit) {
+                /*
+                 * We are finishing after the client. We start the timer going
+                 * in case there are any retransmits of our final flight
+                 * required.
+                 */
+                dtls1_start_timer(s);
+            }
         } else {
             ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
             if (s->hit)
@@ -306,6 +315,15 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
 
             s->handshake_func = ossl_statem_connect;
             s->ctx->stats.sess_connect_good++;
+
+            if (SSL_IS_DTLS(s) && s->hit) {
+                /*
+                 * We are finishing after the server. We start the timer going
+                 * in case there are any retransmits of our final flight
+                 * required.
+                 */
+                dtls1_start_timer(s);
+            }
         }
 
         if (s->info_callback != NULL)
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index f216db7..5591e1e 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -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;


More information about the openssl-commits mailing list