Software /
code /
prosody
Annotate
util/paseto.lua @ 12812:b2d422b88cd6
Revert unintentionally committed parts of 12bd40b8e105
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 21 Dec 2022 21:34:07 +0100 |
parent | 12716:0b68b021ce46 |
child | 12838:2e71b76ac299 |
rev | line source |
---|---|
12694
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 local crypto = require "util.crypto"; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 local json = require "util.json"; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 local base64_encode = require "util.encodings".base64.encode; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 local base64_decode = require "util.encodings".base64.decode; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 local secure_equals = require "util.hashes".equals; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 local bit = require "util.bitcompat"; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 local s_pack = require "util.struct".pack; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 local s_gsub = string.gsub; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 local v4_public = {}; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 local b64url_rep = { ["+"] = "-", ["/"] = "_", ["="] = "", ["-"] = "+", ["_"] = "/" }; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 local function b64url(data) |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 return (s_gsub(base64_encode(data), "[+/=]", b64url_rep)); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 local function unb64url(data) |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 return base64_decode(s_gsub(data, "[-_]", b64url_rep).."=="); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 local function le64(n) |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 return s_pack("<I8", bit.band(n, 0x7F)); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 local function pae(parts) |
12716
0b68b021ce46
util.paseto: Do strict type check in pae() function
Kim Alvefur <zash@zash.se>
parents:
12713
diff
changeset
|
26 if type(parts) ~= "table" then |
0b68b021ce46
util.paseto: Do strict type check in pae() function
Kim Alvefur <zash@zash.se>
parents:
12713
diff
changeset
|
27 error("bad argument #1 to 'pae' (table expected, got "..type(parts)..")"); |
0b68b021ce46
util.paseto: Do strict type check in pae() function
Kim Alvefur <zash@zash.se>
parents:
12713
diff
changeset
|
28 end |
12694
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 local o = { le64(#parts) }; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 for _, part in ipairs(parts) do |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 table.insert(o, le64(#part)..part); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 return table.concat(o); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 function v4_public.sign(m, sk, f, i) |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 if type(m) ~= "table" then |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 return nil, "PASETO payloads must be a table"; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 m = json.encode(m); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 local h = "v4.public."; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 local m2 = pae({ h, m, f or "", i or "" }); |
12713
52eead170bb8
util.paseto: Drop custom wrappers around key objects
Matthew Wild <mwild1@gmail.com>
parents:
12711
diff
changeset
|
43 local sig = crypto.ed25519_sign(sk, m2); |
12694
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 if not f or f == "" then |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 return h..b64url(m..sig); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 else |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 return h..b64url(m..sig).."."..b64url(f); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 function v4_public.verify(tok, pk, expected_f, i) |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 local h, sm, f = tok:match("^(v4%.public%.)([^%.]+)%.?(.*)$"); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 if not h then |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 return nil, "invalid-token-format"; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 end |
12709
b3f7c77c1f08
util.paseto: Fix to decode footer before comparison
Matthew Wild <mwild1@gmail.com>
parents:
12694
diff
changeset
|
56 f = f and unb64url(f) or nil; |
12694
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 if expected_f then |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 if not f or not secure_equals(expected_f, f) then |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 return nil, "invalid-footer"; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 local raw_sm = unb64url(sm); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 if not raw_sm or #raw_sm <= 64 then |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 return nil, "invalid-token-format"; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 local s, m = raw_sm:sub(-64), raw_sm:sub(1, -65); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 local m2 = pae({ h, m, f or "", i or "" }); |
12713
52eead170bb8
util.paseto: Drop custom wrappers around key objects
Matthew Wild <mwild1@gmail.com>
parents:
12711
diff
changeset
|
68 local ok = crypto.ed25519_verify(pk, m2, s); |
12694
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 if not ok then |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 return nil, "invalid-token"; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 local payload, err = json.decode(m); |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 if err ~= nil or type(payload) ~= "table" then |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 return nil, "json-decode-error"; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 return payload; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 |
12713
52eead170bb8
util.paseto: Drop custom wrappers around key objects
Matthew Wild <mwild1@gmail.com>
parents:
12711
diff
changeset
|
79 v4_public.import_private_key = crypto.import_private_pem; |
52eead170bb8
util.paseto: Drop custom wrappers around key objects
Matthew Wild <mwild1@gmail.com>
parents:
12711
diff
changeset
|
80 v4_public.import_public_key = crypto.import_public_pem; |
12694
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 function v4_public.new_keypair() |
12713
52eead170bb8
util.paseto: Drop custom wrappers around key objects
Matthew Wild <mwild1@gmail.com>
parents:
12711
diff
changeset
|
82 return crypto.generate_ed25519_keypair(); |
12694
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 end |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 |
12711
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
85 function v4_public.init(private_key_pem, public_key_pem, options) |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
86 local sign, verify = v4_public.sign, v4_public.verify; |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
87 local public_key = public_key_pem and v4_public.import_public_key(public_key_pem); |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
88 local private_key = private_key_pem and v4_public.import_private_key(private_key_pem); |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
89 local default_footer = options and options.default_footer; |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
90 local default_assertion = options and options.default_implicit_assertion; |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
91 return private_key and function (token, token_footer, token_assertion) |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
92 return sign(token, private_key, token_footer or default_footer, token_assertion or default_assertion); |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
93 end, public_key and function (token, expected_footer, token_assertion) |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
94 return verify(token, public_key, expected_footer or default_footer, token_assertion or default_assertion); |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
95 end; |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
96 end |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
97 |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
98 function v4_public.new_signer(private_key_pem, options) |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
99 return (v4_public.init(private_key_pem, nil, options)); |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
100 end |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
101 |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
102 function v4_public.new_verifier(public_key_pem, options) |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
103 return (select(2, v4_public.init(public_key_pem, options))); |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
104 end |
9e9f158d6699
util.paseto: Export similar API to new util.jwt for ease and consistency
Matthew Wild <mwild1@gmail.com>
parents:
12710
diff
changeset
|
105 |
12694
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
106 return { |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
107 pae = pae; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
108 v4_public = v4_public; |
26a004c96ef8
util.paseto: Implementation of PASETO v4.public tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
109 }; |