util/jwt.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 02 Jul 2022 12:26:43 +0100
changeset 12703 b3d0c1457584
parent 12700 27a72982e331
child 12706 f63176781940
permissions -rw-r--r--
util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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;
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
     2
local crypto = require "util.crypto";
10664
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
local json = require "util.json";
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
local hashes = require "util.hashes";
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
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
     6
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
     7
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
     8
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
local b64url_rep = { ["+"] = "-", ["/"] = "_", ["="] = "", ["-"] = "+", ["_"] = "/" };
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
local function b64url(data)
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
	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
    12
end
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
local function unb64url(data)
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
	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
    15
end
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
local jwt_pattern = "^(([A-Za-z0-9-_]+)%.([A-Za-z0-9-_]+))%.([A-Za-z0-9-_]+)$"
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    18
local function decode_jwt(blob, expected_alg)
10664
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
	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
    20
	if not signed then
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
		return nil, "invalid-encoding";
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
	end
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
	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
    24
	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
    25
		return nil, "invalid-header";
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    26
	elseif header.alg ~= expected_alg then
10664
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
		return nil, "unsupported-algorithm";
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
	end
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    29
	return signed, signature, bpayload;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    30
end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    31
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    32
local function new_static_header(algorithm_name)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    33
	return b64url('{"alg":"'..algorithm_name..'","typ":"JWT"}') .. '.';
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    34
end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    35
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    36
-- HS*** family
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    37
local function new_hmac_algorithm(name, hmac)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    38
	local static_header = new_static_header(name);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    39
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    40
	local function sign(key, payload)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    41
		local encoded_payload = json.encode(payload);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    42
		local signed = static_header .. b64url(encoded_payload);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    43
		local signature = hmac(key, signed);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    44
		return signed .. "." .. b64url(signature);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    45
	end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    46
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    47
	local function verify(key, blob)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    48
		local signed, signature, raw_payload = decode_jwt(blob, name);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    49
		if not signed then return nil, signature; end -- nil, err
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    50
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    51
		if not secure_equals(b64url(hmac(key, signed)), signature) then
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    52
			return false, "signature-mismatch";
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    53
		end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    54
		local payload, err = json.decode(unb64url(raw_payload));
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    55
		if err ~= nil then
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    56
			return nil, "json-decode-error";
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    57
		end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    58
		return true, payload;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    59
	end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    60
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    61
	local function load_key(key)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    62
		assert(type(key) == "string", "key must be string (long, random, secure)");
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    63
		return key;
10664
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
	end
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    65
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    66
	return { sign = sign, verify = verify, load_key = load_key };
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    67
end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    68
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    69
local function new_crypto_algorithm(name, key_type, c_sign, c_verify, sig_encode, sig_decode)
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    70
	local static_header = new_static_header(name);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    71
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    72
	return {
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    73
		sign = function (private_key, payload)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    74
			local encoded_payload = json.encode(payload);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    75
			local signed = static_header .. b64url(encoded_payload);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    76
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    77
			local signature = c_sign(private_key, signed);
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    78
			if sig_encode then
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    79
				signature = sig_encode(signature);
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    80
			end
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    81
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    82
			return signed.."."..b64url(signature);
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    83
		end;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    84
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    85
		verify = function (public_key, blob)
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    86
			local signed, signature, raw_payload = decode_jwt(blob, name);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    87
			if not signed then return nil, signature; end -- nil, err
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    88
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    89
			signature = unb64url(signature);
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    90
			if sig_decode and signature then
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    91
				signature = sig_decode(signature);
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    92
			end
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    93
			if not signature then
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    94
				return false, "signature-mismatch";
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    95
			end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    96
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
    97
			local verify_ok = c_verify(public_key, signed, signature);
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    98
			if not verify_ok then
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
    99
				return false, "signature-mismatch";
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   100
			end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   101
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   102
			local payload, err = json.decode(unb64url(raw_payload));
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   103
			if err ~= nil then
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   104
				return nil, "json-decode-error";
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   105
			end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   106
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   107
			return true, payload;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   108
		end;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   109
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   110
		load_public_key = function (public_key_pem)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   111
			local key = assert(crypto.import_public_pem(public_key_pem));
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   112
			assert(key:get_type() == key_type, "incorrect key type");
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   113
			return key;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   114
		end;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   115
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   116
		load_private_key = function (private_key_pem)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   117
			local key = assert(crypto.import_private_pem(private_key_pem));
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   118
			assert(key:get_type() == key_type, "incorrect key type");
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   119
			return key;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   120
		end;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   121
	};
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   122
end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   123
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   124
-- RS***, PS***
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   125
local function new_rsa_algorithm(name, c_sign, c_verify)
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   126
	return new_crypto_algorithm(name, "rsaEncryption", c_sign, c_verify);
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   127
end
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   128
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   129
-- ES***
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   130
local function new_ecdsa_algorithm(name, c_sign, c_verify)
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   131
	local function encode_ecdsa_sig(der_sig)
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   132
		local r, s = crypto.parse_ecdsa_signature(der_sig);
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   133
		return r..s;
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   134
	end
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   135
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   136
	local function decode_ecdsa_sig(jwk_sig)
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   137
		return crypto.build_ecdsa_signature(jwk_sig:sub(1, 32), jwk_sig:sub(33, 64));
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   138
	end
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   139
	return new_crypto_algorithm(name, "id-ecPublicKey", c_sign, c_verify, encode_ecdsa_sig, decode_ecdsa_sig);
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   140
end
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   141
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   142
local algorithms = {
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   143
	HS256 = new_hmac_algorithm("HS256", hashes.hmac_sha256);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   144
	ES256 = new_ecdsa_algorithm("ES256", crypto.ecdsa_sha256_sign, crypto.ecdsa_sha256_verify);
12703
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   145
	RS256 = new_rsa_algorithm("RS256", crypto.rsassa_pkcs1_256_sign, crypto.rsassa_pkcs1_256_verify);
b3d0c1457584 util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Matthew Wild <mwild1@gmail.com>
parents: 12700
diff changeset
   146
	PS256 = new_rsa_algorithm("PS256", crypto.rsassa_pss_256_sign, crypto.rsassa_pss_256_verify);
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   147
};
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   148
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   149
local function new_signer(algorithm, key_input)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   150
	local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   151
	local key = (impl.load_private_key or impl.load_key)(key_input);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   152
	local sign = impl.sign;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   153
	return function (payload)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   154
		return sign(key, payload);
10664
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
	end
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   156
end
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   157
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   158
local function new_verifier(algorithm, key_input)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   159
	local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   160
	local key = (impl.load_public_key or impl.load_key)(key_input);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   161
	local verify = impl.verify;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   162
	return function (token)
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   163
		return verify(key, token);
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   164
	end
10664
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   165
end
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   166
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   167
return {
12700
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   168
	new_signer = new_signer;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   169
	new_verifier = new_verifier;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   170
	-- Deprecated
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   171
	sign = algorithms.HS256.sign;
27a72982e331 util.jwt: Add support/tests for ES256 via improved API and using util.crypto
Matthew Wild <mwild1@gmail.com>
parents: 11565
diff changeset
   172
	verify = algorithms.HS256.verify;
10664
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   173
};
c4ded3be7cc0 util.jwt: Basic JSON Web Token library supporting HS256 tokens
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   174