Software /
code /
prosody
File
util/jwt.lua @ 12630:781772c8b6d9
mod_mam: Store archives with sub-second precision timestamps
Changes sub-second part of example timestamp to .5 in order to avoid
floating point issues.
Some clients use timestamps when ordering messages which can lead to
messages having the same timestamp ending up in the wrong order.
It would be better to preserve the order messages are sent in, which is
the order they were stored in.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 14 Aug 2022 17:28:31 +0200 |
parent | 11561:d2f33b8fdc96 |
child | 12696:27a72982e331 |
line wrap: on
line source
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 secure_equals = require "util.hashes".equals; 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 not secure_equals(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; };