Comparison

util/jwt.lua @ 11200:bf8f2da84007

Merge 0.11->trunk
author Kim Alvefur <zash@zash.se>
date Thu, 05 Nov 2020 22:31:25 +0100
parent 10660:c4ded3be7cc0
child 11561:d2f33b8fdc96
comparison
equal deleted inserted replaced
11199:6c7c50a4de32 11200:bf8f2da84007
1 local s_gsub = string.gsub;
2 local json = require "util.json";
3 local hashes = require "util.hashes";
4 local base64_encode = require "util.encodings".base64.encode;
5 local base64_decode = require "util.encodings".base64.decode;
6
7 local b64url_rep = { ["+"] = "-", ["/"] = "_", ["="] = "", ["-"] = "+", ["_"] = "/" };
8 local function b64url(data)
9 return (s_gsub(base64_encode(data), "[+/=]", b64url_rep));
10 end
11 local function unb64url(data)
12 return base64_decode(s_gsub(data, "[-_]", b64url_rep).."==");
13 end
14
15 local static_header = b64url('{"alg":"HS256","typ":"JWT"}') .. '.';
16
17 local function sign(key, payload)
18 local encoded_payload = json.encode(payload);
19 local signed = static_header .. b64url(encoded_payload);
20 local signature = hashes.hmac_sha256(key, signed);
21 return signed .. "." .. b64url(signature);
22 end
23
24 local jwt_pattern = "^(([A-Za-z0-9-_]+)%.([A-Za-z0-9-_]+))%.([A-Za-z0-9-_]+)$"
25 local function verify(key, blob)
26 local signed, bheader, bpayload, signature = string.match(blob, jwt_pattern);
27 if not signed then
28 return nil, "invalid-encoding";
29 end
30 local header = json.decode(unb64url(bheader));
31 if not header or type(header) ~= "table" then
32 return nil, "invalid-header";
33 elseif header.alg ~= "HS256" then
34 return nil, "unsupported-algorithm";
35 end
36 if b64url(hashes.hmac_sha256(key, signed)) ~= signature then
37 return false, "signature-mismatch";
38 end
39 local payload, err = json.decode(unb64url(bpayload));
40 if err ~= nil then
41 return nil, "json-decode-error";
42 end
43 return true, payload;
44 end
45
46 return {
47 sign = sign;
48 verify = verify;
49 };
50