Software / code / prosody
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 |