Keep the DTLS timer running after the end of the handshake if appropriate
authorMatt Caswell <matt@openssl.org>
Thu, 3 May 2018 15:00:51 +0000 (16:00 +0100)
committerMatt Caswell <matt@openssl.org>
Tue, 8 May 2018 08:40:17 +0000 (09:40 +0100)
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@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6170)

ssl/record/rec_layer_d1.c
ssl/statem/statem_lib.c

index f1e35f407c5e3aed8878bb14572d2f9da406e036..37a2eb145ec4775a02e9772e3a5cef9e94519210 100644 (file)
@@ -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,
index 49b44433f936eb0c9bb68adb7a2b3196b44771c3..74ad6e804a30746690f16317f34e4b1097b3a72b 100644 (file)
@@ -1057,6 +1057,15 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
             CRYPTO_atomic_add(&s->ctx->stats.sess_accept_good, 1, &discard,
                               s->ctx->lock);
             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 {
             /*
              * In TLSv1.3 we update the cache as part of processing the
@@ -1071,6 +1080,15 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
             s->handshake_func = ossl_statem_connect;
             CRYPTO_atomic_add(&s->session_ctx->stats.sess_connect_good, 1,
                               &discard, s->session_ctx->lock);
+
+            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 (SSL_IS_DTLS(s)) {