Software / code / prosody
Comparison
spec/util_paseto_spec.lua @ 12712:719a72f14e90
util.paseto: Add tests based on official PASETO test vectors
Unfortunately there are only a few relevant ones, but they did help catch some
bugs.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Mon, 11 Jul 2022 14:10:07 +0100 |
| child | 12713:52eead170bb8 |
comparison
equal
deleted
inserted
replaced
| 12711:9e9f158d6699 | 12712:719a72f14e90 |
|---|---|
| 1 -- Ignore long lines in this file | |
| 2 --luacheck: ignore 631 | |
| 3 | |
| 4 describe("util.paseto", function () | |
| 5 local paseto = require "util.paseto"; | |
| 6 local json = require "util.json"; | |
| 7 | |
| 8 local function parse_test_cases(json_test_cases) | |
| 9 local input_cases = json.decode(json_test_cases); | |
| 10 local output_cases = {}; | |
| 11 for _, case in ipairs(input_cases) do | |
| 12 assert.is_string(case.name, "Bad test case: expected name"); | |
| 13 assert.is_nil(output_cases[case.name], "Bad test case: duplicate name"); | |
| 14 output_cases[case.name] = function () | |
| 15 local verify_key = paseto.v4_public.import_public_key(case["public-key-pem"]); | |
| 16 local payload, err = paseto.v4_public.verify(case.token, verify_key, case.footer, case["implicit-assertion"]); | |
| 17 if case["expect-fail"] then | |
| 18 assert.is_nil(payload); | |
| 19 else | |
| 20 assert.is_nil(err); | |
| 21 assert.same(json.decode(case.payload), payload); | |
| 22 end | |
| 23 end; | |
| 24 end | |
| 25 return output_cases; | |
| 26 end | |
| 27 | |
| 28 describe("v4.public", function () | |
| 29 local test_cases = parse_test_cases [=[[ | |
| 30 { | |
| 31 "name": "4-S-1", | |
| 32 "expect-fail": false, | |
| 33 "public-key": "1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2", | |
| 34 "secret-key": "b4cbfb43df4ce210727d953e4a713307fa19bb7d9f85041438d9e11b942a37741eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2", | |
| 35 "secret-key-seed": "b4cbfb43df4ce210727d953e4a713307fa19bb7d9f85041438d9e11b942a3774", | |
| 36 "secret-key-pem": "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILTL+0PfTOIQcn2VPkpxMwf6Gbt9n4UEFDjZ4RuUKjd0\n-----END PRIVATE KEY-----", | |
| 37 "public-key-pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAHrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI=\n-----END PUBLIC KEY-----", | |
| 38 "token": "v4.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwIjoiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9bg_XBBzds8lTZShVlwwKSgeKpLT3yukTw6JUz3W4h_ExsQV-P0V54zemZDcAxFaSeef1QlXEFtkqxT1ciiQEDA", | |
| 39 "payload": "{\"data\":\"this is a signed message\",\"exp\":\"2022-01-01T00:00:00+00:00\"}", | |
| 40 "footer": "", | |
| 41 "implicit-assertion": "" | |
| 42 }, | |
| 43 { | |
| 44 "name": "4-S-2", | |
| 45 "expect-fail": false, | |
| 46 "public-key": "1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2", | |
| 47 "secret-key": "b4cbfb43df4ce210727d953e4a713307fa19bb7d9f85041438d9e11b942a37741eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2", | |
| 48 "secret-key-seed": "b4cbfb43df4ce210727d953e4a713307fa19bb7d9f85041438d9e11b942a3774", | |
| 49 "secret-key-pem": "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILTL+0PfTOIQcn2VPkpxMwf6Gbt9n4UEFDjZ4RuUKjd0\n-----END PRIVATE KEY-----", | |
| 50 "public-key-pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAHrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI=\n-----END PUBLIC KEY-----", | |
| 51 "token": "v4.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwIjoiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9v3Jt8mx_TdM2ceTGoqwrh4yDFn0XsHvvV_D0DtwQxVrJEBMl0F2caAdgnpKlt4p7xBnx1HcO-SPo8FPp214HDw.eyJraWQiOiJ6VmhNaVBCUDlmUmYyc25FY1Q3Z0ZUaW9lQTlDT2NOeTlEZmdMMVc2MGhhTiJ9", | |
| 52 "payload": "{\"data\":\"this is a signed message\",\"exp\":\"2022-01-01T00:00:00+00:00\"}", | |
| 53 "footer": "{\"kid\":\"zVhMiPBP9fRf2snEcT7gFTioeA9COcNy9DfgL1W60haN\"}", | |
| 54 "implicit-assertion": "" | |
| 55 }, | |
| 56 { | |
| 57 "name": "4-S-3", | |
| 58 "expect-fail": false, | |
| 59 "public-key": "1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2", | |
| 60 "secret-key": "b4cbfb43df4ce210727d953e4a713307fa19bb7d9f85041438d9e11b942a37741eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2", | |
| 61 "secret-key-seed": "b4cbfb43df4ce210727d953e4a713307fa19bb7d9f85041438d9e11b942a3774", | |
| 62 "secret-key-pem": "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILTL+0PfTOIQcn2VPkpxMwf6Gbt9n4UEFDjZ4RuUKjd0\n-----END PRIVATE KEY-----", | |
| 63 "public-key-pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAHrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI=\n-----END PUBLIC KEY-----", | |
| 64 "token": "v4.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwIjoiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9NPWciuD3d0o5eXJXG5pJy-DiVEoyPYWs1YSTwWHNJq6DZD3je5gf-0M4JR9ipdUSJbIovzmBECeaWmaqcaP0DQ.eyJraWQiOiJ6VmhNaVBCUDlmUmYyc25FY1Q3Z0ZUaW9lQTlDT2NOeTlEZmdMMVc2MGhhTiJ9", | |
| 65 "payload": "{\"data\":\"this is a signed message\",\"exp\":\"2022-01-01T00:00:00+00:00\"}", | |
| 66 "footer": "{\"kid\":\"zVhMiPBP9fRf2snEcT7gFTioeA9COcNy9DfgL1W60haN\"}", | |
| 67 "implicit-assertion": "{\"test-vector\":\"4-S-3\"}" | |
| 68 }]]=]; | |
| 69 for name, test in pairs(test_cases) do | |
| 70 it("test case "..name, test); | |
| 71 end | |
| 72 | |
| 73 describe("basic sign/verify", function () | |
| 74 local function new_keypair() | |
| 75 local kp = paseto.v4_public.new_keypair(); | |
| 76 return kp.private_key:export(), kp.public_key:export(); | |
| 77 end | |
| 78 | |
| 79 local privkey1, pubkey1 = new_keypair(); | |
| 80 local privkey2, pubkey2 = new_keypair(); | |
| 81 local sign1, verify1 = paseto.v4_public.init(privkey1, pubkey1); | |
| 82 local sign2, verify2 = paseto.v4_public.init(privkey2, pubkey2); | |
| 83 | |
| 84 it("works", function () | |
| 85 local payload = { foo = "hello world", b = { 1, 2, 3 } }; | |
| 86 | |
| 87 local tok1 = sign1(payload); | |
| 88 assert.same(payload, verify1(tok1)); | |
| 89 assert.is_nil(verify2(tok1)); | |
| 90 | |
| 91 local tok2 = sign2(payload); | |
| 92 assert.same(payload, verify2(tok2)); | |
| 93 assert.is_nil(verify1(tok2)); | |
| 94 end); | |
| 95 | |
| 96 it("rejects tokens if implicit assertion fails", function () | |
| 97 local payload = { foo = "hello world", b = { 1, 2, 3 } }; | |
| 98 local tok = sign1(payload, nil, "my-custom-assertion"); | |
| 99 assert.is_nil(verify1(tok, nil, "my-incorrect-assertion")); | |
| 100 assert.is_nil(verify1(tok, nil, nil)); | |
| 101 assert.same(payload, verify1(tok, nil, "my-custom-assertion")); | |
| 102 end); | |
| 103 end); | |
| 104 end); | |
| 105 | |
| 106 describe("pae", function () | |
| 107 it("encodes correctly", function () | |
| 108 -- These test cases are taken from the PASETO docs | |
| 109 -- https://github.com/paseto-standard/paseto-spec/blob/master/docs/01-Protocol-Versions/Common.md | |
| 110 assert.equal("\x00\x00\x00\x00\x00\x00\x00\x00", paseto.pae{}); | |
| 111 assert.equal("\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", paseto.pae{''}); | |
| 112 assert.equal("\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00test", paseto.pae{'test'}); | |
| 113 assert.has_errors(function () | |
| 114 paseto.pae("test"); | |
| 115 end); | |
| 116 end); | |
| 117 end); | |
| 118 end); |