tls: Check for minimal TLS record length before each record iteration
authorMartin Willi <martin@revosec.ch>
Fri, 21 Mar 2014 08:29:44 +0000 (09:29 +0100)
committerMartin Willi <martin@revosec.ch>
Mon, 31 Mar 2014 13:56:12 +0000 (15:56 +0200)
Fixes fragment reassembling if a buffer contains more than one record, but
the last record contains a partial TLS record header. Thanks to Nick Saunders
and Jamil Nimeh for identifying this issue and providing a fix for it.

src/libtls/tls.c

index 6b51e75..7314602 100644 (file)
@@ -218,14 +218,7 @@ METHOD(tls_t, process, status_t,
        {
                if (this->input.len == 0)
                {
        {
                if (this->input.len == 0)
                {
-                       if (buflen < sizeof(tls_record_t))
-                       {
-                               DBG2(DBG_TLS, "received incomplete TLS record header");
-                               memcpy(&this->head, buf, buflen);
-                               this->headpos = buflen;
-                               break;
-                       }
-                       while (TRUE)
+                       while (buflen >= sizeof(tls_record_t))
                        {
                                /* try to process records inline */
                                record = buf;
                        {
                                /* try to process records inline */
                                record = buf;
@@ -252,6 +245,13 @@ METHOD(tls_t, process, status_t,
                                        return NEED_MORE;
                                }
                        }
                                        return NEED_MORE;
                                }
                        }
+                       if (buflen < sizeof(tls_record_t))
+                       {
+                               DBG2(DBG_TLS, "received incomplete TLS record header");
+                               memcpy(&this->head, buf, buflen);
+                               this->headpos = buflen;
+                               break;
+                       }
                }
                len = min(buflen, this->input.len - this->inpos);
                memcpy(this->input.ptr + this->inpos, buf, len);
                }
                len = min(buflen, this->input.len - this->inpos);
                memcpy(this->input.ptr + this->inpos, buf, len);