Software / code / prosody
Comparison
net/websocket/frames.lua @ 11164:4e5a2af9dd19 0.11
net.websocket.frames: Use C string XOR implementation
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Wed, 14 Oct 2020 19:41:42 +0200 |
| parent | 11157:413bd21ba449 |
| child | 11166:51e5149ed0ad |
comparison
equal
deleted
inserted
replaced
| 11163:37a6a535343e | 11164:4e5a2af9dd19 |
|---|---|
| 11 | 11 |
| 12 local bit = assert(softreq"bit" or softreq"bit32", | 12 local bit = assert(softreq"bit" or softreq"bit32", |
| 13 "No bit module found. See https://prosody.im/doc/depends#bitop"); | 13 "No bit module found. See https://prosody.im/doc/depends#bitop"); |
| 14 local band = bit.band; | 14 local band = bit.band; |
| 15 local bor = bit.bor; | 15 local bor = bit.bor; |
| 16 local bxor = bit.bxor; | |
| 17 local lshift = bit.lshift; | 16 local lshift = bit.lshift; |
| 18 local rshift = bit.rshift; | 17 local rshift = bit.rshift; |
| 19 local unpack = table.unpack or unpack; -- luacheck: ignore 113 | 18 local sbit = require "util.strbitop"; |
| 20 | 19 local sxor = sbit.sxor; |
| 21 local t_concat = table.concat; | 20 |
| 22 local s_char= string.char; | 21 local s_char= string.char; |
| 23 local s_pack = string.pack; -- luacheck: ignore 143 | 22 local s_pack = string.pack; -- luacheck: ignore 143 |
| 24 local s_unpack = string.unpack; -- luacheck: ignore 143 | 23 local s_unpack = string.unpack; -- luacheck: ignore 143 |
| 25 | 24 |
| 26 if not s_pack and softreq"struct" then | 25 if not s_pack and softreq"struct" then |
| 105 elseif length_bytes == 8 then | 104 elseif length_bytes == 8 then |
| 106 result.length = read_uint64be(frame, 3); | 105 result.length = read_uint64be(frame, 3); |
| 107 end | 106 end |
| 108 | 107 |
| 109 if result.MASK then | 108 if result.MASK then |
| 110 result.key = { frame:byte(length_bytes+3, length_bytes+6) }; | 109 result.key = frame:sub(length_bytes+3, length_bytes+6); |
| 111 end | 110 end |
| 112 | 111 |
| 113 return result, header_length; | 112 return result, header_length; |
| 114 end | 113 end |
| 115 | 114 |
| 116 -- XORs the string `str` with the array of bytes `key` | 115 -- XORs the string `str` with the array of bytes `key` |
| 117 -- TODO: optimize | 116 -- TODO: optimize |
| 118 local function apply_mask(str, key, from, to) | 117 local function apply_mask(str, key, from, to) |
| 119 from = from or 1 | 118 return sxor(str:sub(from or 1, to or -1), key); |
| 120 if from < 0 then from = #str + from + 1 end -- negative indices | |
| 121 to = to or #str | |
| 122 if to < 0 then to = #str + to + 1 end -- negative indices | |
| 123 local key_len = #key | |
| 124 local counter = 0; | |
| 125 local data = {}; | |
| 126 for i = from, to do | |
| 127 local key_index = counter%key_len + 1; | |
| 128 counter = counter + 1; | |
| 129 data[counter] = s_char(bxor(key[key_index], str:byte(i))); | |
| 130 end | |
| 131 return t_concat(data); | |
| 132 end | 119 end |
| 133 | 120 |
| 134 local function parse_frame_body(frame, header, pos) | 121 local function parse_frame_body(frame, header, pos) |
| 135 if header.MASK then | 122 if header.MASK then |
| 136 return apply_mask(frame, header.key, pos, pos + header.length - 1); | 123 return apply_mask(frame, header.key, pos, pos + header.length - 1); |
| 173 length_extra = pack_uint64be(#data); | 160 length_extra = pack_uint64be(#data); |
| 174 end | 161 end |
| 175 | 162 |
| 176 local key = "" | 163 local key = "" |
| 177 if desc.MASK then | 164 if desc.MASK then |
| 178 local key_a = desc.key | 165 key = desc.key |
| 179 if key_a then | 166 if not key then |
| 180 key = s_char(unpack(key_a, 1, 4)); | |
| 181 else | |
| 182 key = random_bytes(4); | 167 key = random_bytes(4); |
| 183 key_a = {key:byte(1,4)}; | |
| 184 end | 168 end |
| 185 b2 = bor(b2, 0x80); | 169 b2 = bor(b2, 0x80); |
| 186 data = apply_mask(data, key_a); | 170 data = apply_mask(data, key); |
| 187 end | 171 end |
| 188 | 172 |
| 189 return s_char(b1, b2) .. length_extra .. key .. data | 173 return s_char(b1, b2) .. length_extra .. key .. data |
| 190 end | 174 end |
| 191 | 175 |