mirror of
https://github.com/nmap/nmap.git
synced 2026-01-05 22:19:03 +00:00
Support fragmented TLS records. Closes #194
This commit is contained in:
@@ -1108,12 +1108,14 @@ end
|
||||
|
||||
---
|
||||
-- Read a SSL/TLS record
|
||||
-- @param buffer The read buffer
|
||||
-- @param i The position in the buffer to start reading
|
||||
-- @param buffer The read buffer
|
||||
-- @param i The position in the buffer to start reading
|
||||
-- @param fragment Message fragment left over from previous record (nil if none)
|
||||
-- @return The current position in the buffer
|
||||
-- @return The record that was read, as a table
|
||||
function record_read(buffer, i)
|
||||
function record_read(buffer, i, fragment)
|
||||
local b, h, len
|
||||
local add = 0
|
||||
|
||||
------------
|
||||
-- Header --
|
||||
@@ -1148,6 +1150,14 @@ function record_read(buffer, i)
|
||||
return i, nil
|
||||
end
|
||||
|
||||
-- Adjust buffer and length to account for message fragment left over
|
||||
-- from last record.
|
||||
if fragment then
|
||||
add = #fragment
|
||||
len = len + add
|
||||
buffer = buffer:sub(1, j - 1) .. fragment .. buffer:sub(j, -1)
|
||||
end
|
||||
|
||||
-- Convert to human-readable form.
|
||||
|
||||
----------
|
||||
@@ -1155,12 +1165,11 @@ function record_read(buffer, i)
|
||||
----------
|
||||
|
||||
h["body"] = {}
|
||||
while j < len do
|
||||
|
||||
while j <= len do
|
||||
-- RFC 2246, 6.2.1 "multiple client messages of the same ContentType may
|
||||
-- be coalesced into a single TLSPlaintext record"
|
||||
-- TODO: implement reading of fragmented records
|
||||
b = {}
|
||||
table.insert(h["body"], b)
|
||||
if h["type"] == "alert" then
|
||||
-- Parse body.
|
||||
j, b["level"] = bin.unpack("C", buffer, j)
|
||||
@@ -1169,7 +1178,16 @@ function record_read(buffer, i)
|
||||
-- Convert to human-readable form.
|
||||
b["level"] = find_key(TLS_ALERT_LEVELS, b["level"])
|
||||
b["description"] = find_key(TLS_ALERT_REGISTRY, b["description"])
|
||||
|
||||
table.insert(h["body"], b)
|
||||
elseif h["type"] == "handshake" then
|
||||
|
||||
-- Check for message fragmentation.
|
||||
if len - j < 3 then
|
||||
h.fragment = buffer:sub(j, len)
|
||||
return len + 1 - add, h
|
||||
end
|
||||
|
||||
-- Parse body.
|
||||
j, b["type"] = bin.unpack("C", buffer, j)
|
||||
local msg_end
|
||||
@@ -1179,6 +1197,12 @@ function record_read(buffer, i)
|
||||
-- Convert to human-readable form.
|
||||
b["type"] = find_key(TLS_HANDSHAKETYPE_REGISTRY, b["type"])
|
||||
|
||||
-- Check for message fragmentation.
|
||||
if msg_end > len + 1 then
|
||||
h.fragment = buffer:sub(j - 4, len)
|
||||
return len + 1 - add, h
|
||||
end
|
||||
|
||||
if b["type"] == "server_hello" then
|
||||
-- Parse body.
|
||||
j, b["protocol"] = bin.unpack(">S", buffer, j)
|
||||
@@ -1226,18 +1250,21 @@ function record_read(buffer, i)
|
||||
stdnse.debug2("Unknown handshake message type: %s", b["type"])
|
||||
j, b["data"] = bin.unpack("A" .. msg_end - j, buffer, j)
|
||||
end
|
||||
|
||||
table.insert(h["body"], b)
|
||||
elseif h["type"] == "heartbeat" then
|
||||
j, b["type"], b["payload_length"] = bin.unpack("C>S", buffer, j)
|
||||
j, b["payload"], b["padding"] = bin.unpack("PP", buffer, j)
|
||||
table.insert(h["body"], b)
|
||||
else
|
||||
stdnse.debug1("Unknown message type: %s", h["type"])
|
||||
end
|
||||
end
|
||||
|
||||
-- Ignore unparsed bytes.
|
||||
j = len+1
|
||||
j = len + 1
|
||||
|
||||
return j, h
|
||||
return j - add, h
|
||||
end
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user