annotate mod_auth_token/test_token_auth.lua @ 5616:59d5fc50f602

mod_http_oauth2: Implement refresh token rotation Makes refresh tokens one-time-use, handing out a new refresh token with each access token. Thus if a refresh token is stolen and used by an attacker, the next time the legitimate client tries to use the previous refresh token, it will not work and the attack will be noticed. If the attacker does not use the refresh token, it becomes invalid after the legitimate client uses it. This behavior is recommended by draft-ietf-oauth-security-topics
author Kim Alvefur <zash@zash.se>
date Sun, 23 Jul 2023 02:56:08 +0200
parents d0ca211e1b0e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
1 local base64 = require "util.encodings".base64;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
2 local hmac = require "openssl.hmac";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
3 local luatz = require "luatz";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
4 local luaunit = require "luaunit";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
5 local uuid = require "uuid";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
6 local otp = require "otp";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
7 local mock = require "mock";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
8 local pkey = require "openssl.pkey";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
9 local token_utils = dofile("token_auth_utils.lib.lua");
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
10
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
11 math.randomseed(os.time())
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
12
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
13 local OTP_SEED = 'E3W374VRSFO4NVKE';
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
14
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
15
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
16 function generate_token(jid, key)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
17 local nonce = '';
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
18 for i=1,32 do
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
19 nonce = nonce..math.random(9);
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
20 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
21 local utc_time_table = luatz.gmtime(luatz.time());
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
22 local totp = otp.new_totp_from_key(
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
23 OTP_SEED,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
24 token_utils.OTP_DIGITS,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
25 token_utils.OTP_INTERVAL
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
26 ):generate(0, utc_time_table);
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
27
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
28 local hmac_ctx = hmac.new(key, token_utils.DIGEST_TYPE)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
29 local signature = hmac_ctx:final(totp..nonce..jid)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
30 return totp..nonce..' '..base64.encode(signature)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
31 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
32
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
33
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
34 function test_token_verification()
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
35 -- Test verification of a valid token
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
36 local key = uuid();
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
37 local result = token_utils.verify_token(
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
38 'root',
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
39 generate_token('root@localhost', key),
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
40 'localhost',
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
41 OTP_SEED,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
42 key
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
43 )
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
44 luaunit.assert_is(result, true)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
45 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
46
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
47
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
48 function test_token_is_valid_only_once()
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
49 local key = uuid();
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
50 local token = generate_token('root@localhost', key);
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
51 local result = token_utils.verify_token(
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
52 'root',
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
53 token,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
54 'localhost',
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
55 OTP_SEED,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
56 key
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
57 )
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
58 luaunit.assert_is(result, true)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
59
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
60 result = token_utils.verify_token(
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
61 'root',
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
62 token,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
63 'localhost',
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
64 OTP_SEED,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
65 key
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
66 )
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
67 luaunit.assert_is(result, false)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
68 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
69
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
70
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
71 function test_token_expiration()
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
72 -- Test that a token expires after (at most) the configured interval plus
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
73 -- any amount of deviations.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
74 local key = uuid();
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
75 local token = generate_token('root@localhost', key);
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
76 -- Wait two ticks of the interval window and then check that the token is
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
77 -- no longer valid.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
78 mock.mock(os);
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
79 os.time.replace(function ()
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
80 return os.time.original() +
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
81 (token_utils.OTP_INTERVAL +
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
82 (token_utils.OTP_DEVIATION * token_utils.OTP_INTERVAL));
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
83 end)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
84 result = token_utils.verify_token(
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
85 'root',
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
86 token,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
87 'localhost',
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
88 OTP_SEED,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
89 key
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
90 )
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
91 mock.unmock(os);
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
92 luaunit.assert_is(result, false)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
93 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
94
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
95 os.exit(luaunit.LuaUnit.run())