author | Kim Alvefur <zash@zash.se> |
Sat, 07 Nov 2020 21:39:36 +0100 | |
changeset 11643 | ad39528e647d |
parent 11565 | d2f33b8fdc96 |
child 12700 | 27a72982e331 |
permissions | -rw-r--r-- |
10664
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; |
11565
d2f33b8fdc96
util.jwt: Use constant-time comparison with expected signature
Matthew Wild <mwild1@gmail.com>
parents:
10664
diff
changeset
|
6 |
local secure_equals = require "util.hashes".equals; |
10664
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 |
11565
d2f33b8fdc96
util.jwt: Use constant-time comparison with expected signature
Matthew Wild <mwild1@gmail.com>
parents:
10664
diff
changeset
|
37 |
if not secure_equals(b64url(hashes.hmac_sha256(key, signed)), signature) then |
10664
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 |