Software /
code /
prosody
Annotate
util/jwt.lua @ 12206:77ac0d96ac24
mod_s2s: Enable outgoing Direct TLS connections
Makes it faster by cutting out the roundtrips involved in <starttls/>,
at the cost of making an additional SRV lookup.
Since we already ignore a missing <starttls/> offer and try anyway there
is not much difference in security. The fact that XMPP is used and the
hostnames involved might still be visible until the future Encrypted
ClientHello extension allows hiding those too.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 21 Jan 2022 17:59:19 +0100 |
parent | 11561:d2f33b8fdc96 |
child | 12696:27a72982e331 |
rev | line source |
---|---|
10660
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
1 local s_gsub = string.gsub; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
2 local json = require "util.json"; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
3 local hashes = require "util.hashes"; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
4 local base64_encode = require "util.encodings".base64.encode; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
5 local base64_decode = require "util.encodings".base64.decode; |
11561
d2f33b8fdc96
util.jwt: Use constant-time comparison with expected signature
Matthew Wild <mwild1@gmail.com>
parents:
10660
diff
changeset
|
6 local secure_equals = require "util.hashes".equals; |
10660
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
7 |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
8 local b64url_rep = { ["+"] = "-", ["/"] = "_", ["="] = "", ["-"] = "+", ["_"] = "/" }; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 local function b64url(data) |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
10 return (s_gsub(base64_encode(data), "[+/=]", b64url_rep)); |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
11 end |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
12 local function unb64url(data) |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
13 return base64_decode(s_gsub(data, "[-_]", b64url_rep).."=="); |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
14 end |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
15 |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
16 local static_header = b64url('{"alg":"HS256","typ":"JWT"}') .. '.'; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
17 |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
18 local function sign(key, payload) |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
19 local encoded_payload = json.encode(payload); |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
20 local signed = static_header .. b64url(encoded_payload); |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
21 local signature = hashes.hmac_sha256(key, signed); |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
22 return signed .. "." .. b64url(signature); |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
23 end |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
24 |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
25 local jwt_pattern = "^(([A-Za-z0-9-_]+)%.([A-Za-z0-9-_]+))%.([A-Za-z0-9-_]+)$" |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
26 local function verify(key, blob) |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
27 local signed, bheader, bpayload, signature = string.match(blob, jwt_pattern); |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
28 if not signed then |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
29 return nil, "invalid-encoding"; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
30 end |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
31 local header = json.decode(unb64url(bheader)); |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
32 if not header or type(header) ~= "table" then |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
33 return nil, "invalid-header"; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
34 elseif header.alg ~= "HS256" then |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
35 return nil, "unsupported-algorithm"; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
36 end |
11561
d2f33b8fdc96
util.jwt: Use constant-time comparison with expected signature
Matthew Wild <mwild1@gmail.com>
parents:
10660
diff
changeset
|
37 if not secure_equals(b64url(hashes.hmac_sha256(key, signed)), signature) then |
10660
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
38 return false, "signature-mismatch"; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
39 end |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
40 local payload, err = json.decode(unb64url(bpayload)); |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
41 if err ~= nil then |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
42 return nil, "json-decode-error"; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
43 end |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
44 return true, payload; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
45 end |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
46 |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
47 return { |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
48 sign = sign; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
49 verify = verify; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
50 }; |
c4ded3be7cc0
util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
51 |