diff options
author | Matthew Wild <mwild1@gmail.com> | 2020-09-30 09:50:33 +0100 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2020-09-30 09:50:33 +0100 |
commit | 785c20f6ee7e61a5a91a8b6259623bc2a2bbffaa (patch) | |
tree | 3a37db7b805b1555d08cc61c7938cf512ff35ce0 /util/jwt.lua | |
parent | e55d037cdf89efac99c6144b381c9fa880f7fb93 (diff) | |
parent | b80ff2ae4f86aa26e055890a8284b55170ef2056 (diff) | |
download | prosody-785c20f6ee7e61a5a91a8b6259623bc2a2bbffaa.tar.gz prosody-785c20f6ee7e61a5a91a8b6259623bc2a2bbffaa.zip |
Merge 0.11->trunk
Diffstat (limited to 'util/jwt.lua')
-rw-r--r-- | util/jwt.lua | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/util/jwt.lua b/util/jwt.lua new file mode 100644 index 00000000..2b172d38 --- /dev/null +++ b/util/jwt.lua @@ -0,0 +1,50 @@ +local s_gsub = string.gsub; +local json = require "util.json"; +local hashes = require "util.hashes"; +local base64_encode = require "util.encodings".base64.encode; +local base64_decode = require "util.encodings".base64.decode; + +local b64url_rep = { ["+"] = "-", ["/"] = "_", ["="] = "", ["-"] = "+", ["_"] = "/" }; +local function b64url(data) + return (s_gsub(base64_encode(data), "[+/=]", b64url_rep)); +end +local function unb64url(data) + return base64_decode(s_gsub(data, "[-_]", b64url_rep).."=="); +end + +local static_header = b64url('{"alg":"HS256","typ":"JWT"}') .. '.'; + +local function sign(key, payload) + local encoded_payload = json.encode(payload); + local signed = static_header .. b64url(encoded_payload); + local signature = hashes.hmac_sha256(key, signed); + return signed .. "." .. b64url(signature); +end + +local jwt_pattern = "^(([A-Za-z0-9-_]+)%.([A-Za-z0-9-_]+))%.([A-Za-z0-9-_]+)$" +local function verify(key, blob) + local signed, bheader, bpayload, signature = string.match(blob, jwt_pattern); + if not signed then + return nil, "invalid-encoding"; + end + local header = json.decode(unb64url(bheader)); + if not header or type(header) ~= "table" then + return nil, "invalid-header"; + elseif header.alg ~= "HS256" then + return nil, "unsupported-algorithm"; + end + if b64url(hashes.hmac_sha256(key, signed)) ~= signature then + return false, "signature-mismatch"; + end + local payload, err = json.decode(unb64url(bpayload)); + if err ~= nil then + return nil, "json-decode-error"; + end + return true, payload; +end + +return { + sign = sign; + verify = verify; +}; + |