diff --git a/lib/resty/evp.lua b/lib/resty/evp.lua index cd46c0a..c70139f 100644 --- a/lib/resty/evp.lua +++ b/lib/resty/evp.lua @@ -281,7 +281,7 @@ local function _new_key(self, opts) ffi_gc(key, _C.EC_KEY_free) end - if not key then + if key == nil then return _err() end @@ -553,7 +553,13 @@ function ECVerifier.get_der_sig(self, signature) end -- inspired from https://bit.ly/2yZxzxJ local ec = _C.EVP_PKEY_get0_EC_KEY(self.evp_pkey) + if ec == nil then + return nil, "key is not an EC key" + end local ecgroup = _C.EC_KEY_get0_group(ec) + if ecgroup == nil then + return nil, "EC key has no group" + end local order = _C.BN_new() ffi_gc(order, _C.BN_free) diff --git a/t/sign-verify.t b/t/sign-verify.t index 2610972..5f5c581 100644 --- a/t/sign-verify.t +++ b/t/sign-verify.t @@ -873,4 +873,64 @@ true everything is awesome~ :p bar --- no_error_log -[error] \ No newline at end of file +[error] + +=== TEST 27: RS256 malformed private key returns error not crash +--- http_config eval: $::HttpConfig +--- config + location /t { + content_by_lua_block { + local jwt = require "resty.jwt" + local ok, ret = pcall(function() + return jwt:sign( + "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAgarbage\n-----END RSA PRIVATE KEY-----\n", + { header = { typ = "JWT", alg = "RS256" }, payload = { foo = "bar" } } + ) + end) + if ok then + ngx.say("FAIL: expected error, got token") + else + ngx.say("OK: " .. tostring(ret.reason or ret)) + end + } + } +--- request +GET /t +--- response_body_like: ^OK: .* +--- no_error_log +[error] + + +=== TEST 28: ES256 JWT verified with RSA public key returns error not crash +--- http_config eval: $::HttpConfig +--- config + location /t { + content_by_lua_block { + local jwt = require "resty.jwt" + local function get_testcert(name) + local f = io.open("/lua-resty-jwt/testcerts/" .. name) + local contents = f:read("*all") + f:close() + return contents + end + -- craft a minimal ES256 token (signature bytes do not matter; + -- the crash happens before signature verification) + local function b64url(s) + return ngx.encode_base64(s):gsub('+','-'):gsub('/','_'):gsub('=','') + end + local token = b64url('{"typ":"JWT","alg":"ES256"}') .. + "." .. b64url('{"sub":"test"}') .. + "." .. b64url(string.rep("A", 64)) + local jwt_obj = jwt:verify(get_testcert("pubkey.pem"), token) + if jwt_obj.verified then + ngx.say("FAIL: should not be verified") + else + ngx.say("OK: " .. jwt_obj.reason) + end + } + } +--- request +GET /t +--- response_body_like: ^OK: .* +--- no_error_log +[error]