1 |
1 |
2 local base64, unbase64 = require "mime".b64, require"mime".unb64; |
2 local base64, unbase64 = require "mime".b64, require"mime".unb64; |
3 local crypto = require"crypto"; |
3 local hashes = require"util.hashes"; |
4 local bit = require"bit"; |
4 local bit = require"bit"; |
|
5 local random = require"util.random"; |
5 |
6 |
6 local tonumber = tonumber; |
7 local tonumber = tonumber; |
7 local char, byte = string.char, string.byte; |
8 local char, byte = string.char, string.byte; |
8 local gsub = string.gsub; |
9 local gsub = string.gsub; |
9 local xor = bit.bxor; |
10 local xor = bit.bxor; |
12 return (gsub(a, "()(.)", function(i, c) |
13 return (gsub(a, "()(.)", function(i, c) |
13 return char(xor(byte(c), byte(b, i))) |
14 return char(xor(byte(c), byte(b, i))) |
14 end)); |
15 end)); |
15 end |
16 end |
16 |
17 |
17 local function H(str) |
18 local H, HMAC = hashes.sha1, hashes.hmac_sha1; |
18 return crypto.digest("sha1", str, true); |
|
19 end |
|
20 |
|
21 local _hmac_digest = crypto.hmac.digest; |
|
22 local function HMAC(key, str) |
|
23 return _hmac_digest("sha1", str, key, true); |
|
24 end |
|
25 |
19 |
26 local function Hi(str, salt, i) |
20 local function Hi(str, salt, i) |
27 local U = HMAC(str, salt .. "\0\0\0\1"); |
21 local U = HMAC(str, salt .. "\0\0\0\1"); |
28 local ret = U; |
22 local ret = U; |
29 for _ = 2, i do |
23 for _ = 2, i do |
41 return (gsub(str, "[,=]", { [","] = "=2C", ["="] = "=3D" })); |
35 return (gsub(str, "[,=]", { [","] = "=2C", ["="] = "=3D" })); |
42 end |
36 end |
43 |
37 |
44 local function scram(stream, name) |
38 local function scram(stream, name) |
45 local username = "n=" .. value_safe(stream.username); |
39 local username = "n=" .. value_safe(stream.username); |
46 local c_nonce = base64(crypto.rand.bytes(15)); |
40 local c_nonce = base64(random.bytes(15)); |
47 local our_nonce = "r=" .. c_nonce; |
41 local our_nonce = "r=" .. c_nonce; |
48 local client_first_message_bare = username .. "," .. our_nonce; |
42 local client_first_message_bare = username .. "," .. our_nonce; |
49 local cbind_data = ""; |
43 local cbind_data = ""; |
50 local gs2_cbind_flag = stream.conn:ssl() and "y" or "n"; |
44 local gs2_cbind_flag = stream.conn:ssl() and "y" or "n"; |
51 if name == "SCRAM-SHA-1-PLUS" then |
45 if name == "SCRAM-SHA-1-PLUS" then |