diff options
author | Matthew Wild <mwild1@gmail.com> | 2022-07-02 12:26:43 +0100 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2022-07-02 12:26:43 +0100 |
commit | 0b0555c3390287d2416485b1549186a282c6d1b1 (patch) | |
tree | a576e7f2aff2da7d12af2c25b8f1af92350d9550 /util | |
parent | d7b32f1b71f4806081a99c37296f316942fc03ac (diff) | |
download | prosody-0b0555c3390287d2416485b1549186a282c6d1b1.tar.gz prosody-0b0555c3390287d2416485b1549186a282c6d1b1.zip |
util.jwt: Add support for RSA-based algorithms (RS256, PS256)
Diffstat (limited to 'util')
-rw-r--r-- | util/jwt.lua | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/util/jwt.lua b/util/jwt.lua index 58888b5d..433a69f6 100644 --- a/util/jwt.lua +++ b/util/jwt.lua @@ -66,8 +66,7 @@ local function new_hmac_algorithm(name, hmac) return { sign = sign, verify = verify, load_key = load_key }; end --- ES*** family -local function new_ecdsa_algorithm(name, c_sign, c_verify) +local function new_crypto_algorithm(name, key_type, c_sign, c_verify, sig_encode, sig_decode) local static_header = new_static_header(name); return { @@ -75,25 +74,27 @@ local function new_ecdsa_algorithm(name, c_sign, c_verify) local encoded_payload = json.encode(payload); local signed = static_header .. b64url(encoded_payload); - local der_sig = c_sign(private_key, signed); - - local r, s = crypto.parse_ecdsa_signature(der_sig); + local signature = c_sign(private_key, signed); + if sig_encode then + signature = sig_encode(signature); + end - return signed.."."..b64url(r..s); + return signed.."."..b64url(signature); end; - verify = function (public_key, blob) + verify = function (public_key, blob) local signed, signature, raw_payload = decode_jwt(blob, name); if not signed then return nil, signature; end -- nil, err - local raw_signature = unb64url(signature); - - local der_sig = crypto.build_ecdsa_signature(raw_signature:sub(1, 32), raw_signature:sub(33, 64)); - if not der_sig then + signature = unb64url(signature); + if sig_decode and signature then + signature = sig_decode(signature); + end + if not signature then return false, "signature-mismatch"; end - local verify_ok = c_verify(public_key, signed, der_sig); + local verify_ok = c_verify(public_key, signed, signature); if not verify_ok then return false, "signature-mismatch"; end @@ -108,21 +109,41 @@ local function new_ecdsa_algorithm(name, c_sign, c_verify) load_public_key = function (public_key_pem) local key = assert(crypto.import_public_pem(public_key_pem)); - assert(key:get_type() == "id-ecPublicKey", "incorrect key type"); + assert(key:get_type() == key_type, "incorrect key type"); return key; end; load_private_key = function (private_key_pem) local key = assert(crypto.import_private_pem(private_key_pem)); - assert(key:get_type() == "id-ecPublicKey", "incorrect key type"); + assert(key:get_type() == key_type, "incorrect key type"); return key; end; }; end +-- RS***, PS*** +local function new_rsa_algorithm(name, c_sign, c_verify) + return new_crypto_algorithm(name, "rsaEncryption", c_sign, c_verify); +end + +-- ES*** +local function new_ecdsa_algorithm(name, c_sign, c_verify) + local function encode_ecdsa_sig(der_sig) + local r, s = crypto.parse_ecdsa_signature(der_sig); + return r..s; + end + + local function decode_ecdsa_sig(jwk_sig) + return crypto.build_ecdsa_signature(jwk_sig:sub(1, 32), jwk_sig:sub(33, 64)); + end + return new_crypto_algorithm(name, "id-ecPublicKey", c_sign, c_verify, encode_ecdsa_sig, decode_ecdsa_sig); +end + local algorithms = { HS256 = new_hmac_algorithm("HS256", hashes.hmac_sha256); ES256 = new_ecdsa_algorithm("ES256", crypto.ecdsa_sha256_sign, crypto.ecdsa_sha256_verify); + RS256 = new_rsa_algorithm("RS256", crypto.rsassa_pkcs1_256_sign, crypto.rsassa_pkcs1_256_verify); + PS256 = new_rsa_algorithm("PS256", crypto.rsassa_pss_256_sign, crypto.rsassa_pss_256_verify); }; local function new_signer(algorithm, key_input) |