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 |