Mercurial > prosody-hg
view util/jwt.lua @ 12526:252ed01896dd 0.12 0.12.1
mod_smacks: Bounce unhandled stanzas from local origin (fix #1759)
Sending stanzas with a remote session as origin when the stanzas have a
local JID in the from attribute trips validation in core.stanza_router,
leading to warnings:
> Received a stanza claiming to be from remote.example, over a stream authed for localhost.example
Using module:send() uses the local host as origin, which is fine here.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Fri, 27 May 2022 14:45:35 +0200 |
| parents | d2f33b8fdc96 |
| children | 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; };
