Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hmac) multiple HMAC algorithms support and enforce_headers option #2644

Merged
merged 2 commits into from
Jun 23, 2017

Conversation

shashiranjan84
Copy link
Contributor

@shashiranjan84 shashiranjan84 commented Jun 21, 2017

SUMMARY

  • Support for HMAC-SHA256, HMAC-SHA384, HMAC-SHA512.
  • User can enforce which headers must at least be used for
    http signature creation using config.enforce_headers.

Full changelog

  • config.alogorithms and config.enforce_headers added to schema
  • Logic updated to support multiple algorithms and enforce headers
  • Tests cases added to test new logic

@shashiranjan84 shashiranjan84 added this to the 0.11.0 milestone Jun 21, 2017
@shashiranjan84 shashiranjan84 requested a review from p0pr0ck5 June 21, 2017 21:58
@shashiranjan84 shashiranjan84 force-pushed the feat/hmac-header-algo branch from 92492ab to 8d55afa Compare June 21, 2017 22:21
local matched = false
for _, algo in ipairs(conf.algorithms) do
if algo == params.algorithm then
matched = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets just return true, no need to keep running through this loop once we have a match? also means we dont need matched:

for _, algo in ipairs(conf.algorithms) do
  if algo == params.algorithm then
    return true
  end
end

return nil, fmt("algorithm %s not supported", params.algorithm)

end

-- check enforced headers are present
local enfoprced_header_set = list_as_set(conf.enforce_headers)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo, 'enfoprced_header_set'.

also, how hard would it be to cache the enforce_headers table, so we dont have to constantly call list_as_set?

local function list_as_set(list)
local set = {}
for _, v in ipairs(list) do
set[v] = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

semicolon?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java memory :)

for _, row in ipairs(rows) do
row.config.validate_request_body = false
row.config.enforce_headers = {}
row.config.algorithms = {"hmac-sha1"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not quite sure i agree with this default assignment, as the schema default is to support all 4 algorithms.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional, older version only has support for hmac-sha1, so after migration I defaulted it to {"hmac-sha1"}. If user want to support all 4, he would need to patch the plugin.

}

local function list_as_set(list)
local set = {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we know the size of this table, a minor optimization here would be to use table.new to create the appropriately-sized table.

@p0pr0ck5 p0pr0ck5 added pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done. and removed pr/status/please review labels Jun 21, 2017
@shashiranjan84 shashiranjan84 force-pushed the feat/hmac-header-algo branch from 8d55afa to cbf0cfe Compare June 22, 2017 02:06
@shashiranjan84 shashiranjan84 added pr/status/please review and removed pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done. labels Jun 22, 2017
Copy link
Contributor

@p0pr0ck5 p0pr0ck5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! couple minor things then i think looks good!

local resty_sha256 = require "resty.sha256"
local new_table = require "table.new"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

end

-- check supported alorithm used
local matched = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dont need this matched var. and after this for loop we can just return nil, fmt(...)

@p0pr0ck5 p0pr0ck5 added pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done. and removed pr/status/please review labels Jun 22, 2017
@shashiranjan84 shashiranjan84 force-pushed the feat/hmac-header-algo branch from cbf0cfe to e52b7d5 Compare June 22, 2017 16:17
@shashiranjan84 shashiranjan84 added pr/status/please review and removed pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done. labels Jun 22, 2017
@shashiranjan84
Copy link
Contributor Author

shashiranjan84 commented Jun 22, 2017

@p0pr0ck5 makes sense, thanks. Updated code as you advised.

p0pr0ck5
p0pr0ck5 previously approved these changes Jun 22, 2017
Copy link
Contributor

@p0pr0ck5 p0pr0ck5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor things to cleanup, but LGTM overall.

for _, row in ipairs(rows) do
row.config.validate_request_body = false
row.config.enforce_headers = {}
row.config.algorithms = {"hmac-sha1"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space in between brackets and quotes

it("errors with wrong algorithm", function()
local ok, err = validate_entity({algorithms = {"sha1024"}}, hmac_auth_schema)
assert.equal('"sha1024" is not allowed. Allowed values are: "hmac-sha1", "hmac-sha256", "hmac-sha384", "hmac-sha512"', err.algorithms)
assert.False(ok)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer lowercase is_false to False, i believe

p0pr0ck5
p0pr0ck5 previously approved these changes Jun 22, 2017
@p0pr0ck5 p0pr0ck5 added the pr/ready This PR is considered ready and can be merged at anytime (given it received no subsequent changes) label Jun 22, 2017
@thibaultcha thibaultcha modified the milestones: 0.11.0, 0.11.0rc1 Jun 23, 2017
}

local function list_as_set(list)
local set = new_tab(#list, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_tab(narr, nrec), this should be: new_tab(0, #list)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure @thibaultcha, because in following code, 1st argument is length?

https://github.com/Mashape/kong/blob/master/kong/plugins/ip-restriction/handler.lua#L26

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because this code you pointed is using the array part of the table, but your use-case concerns the hash part.


local function validate_params(params, conf)
-- check username and signature are present
if not (params.username and params.signature) then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No parenthesis is the preferred style and also reads better: if not params.username or not params.signature

for _, header in ipairs(params.hmac_headers) do
enforced_header_set[header] = nil
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one too many blank line it seems?

return true
end
end
return nil, fmt("algorithm %s not supported", params.algorithm)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should jump a line before the return statement

local _M = {}

local hmac = {
["hmac-sha1"] = function(secret, data)
return crypto.hmac.digest("sha1", data, secret, true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should keep using ngx.sha1 when possible? This way we reduce the risk and we take advantage of using the FFI over the crypto lib?

@@ -183,6 +248,7 @@ local function set_consumer(consumer, credential)
end

local function do_authentication(conf)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems this is an undesired change too?

return false, {status = 403, message = SIGNATURE_NOT_VALID}
end

-- validate signature
local credential = load_credential(hmac_params.username)
if not credential then
ngx_log(ngx.DEBUG, "failed to retrieve credential for " .. hmac_params.username)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid string concatenation operators and use variadic arguments when possible. Here:

ngx_log(ngx.DEBUG, "failed to retrieve credential for ", hmac_params.username)

@thibaultcha thibaultcha added pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done. and removed pr/ready This PR is considered ready and can be merged at anytime (given it received no subsequent changes) labels Jun 23, 2017
@thibaultcha thibaultcha modified the milestones: 0.11.0rc1, 0.11.0 Jun 23, 2017
- Support for HMAC-SHA256, HMAC-SHA384, HMAC-SHA512.
- User can enforce which headers must at least be used for
  http signature creation using `config.enforce_headers`.
@shashiranjan84 shashiranjan84 force-pushed the feat/hmac-header-algo branch from 046bd3e to 4b18109 Compare June 23, 2017 02:30
@shashiranjan84 shashiranjan84 added pr/status/please review and removed pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done. labels Jun 23, 2017
@shashiranjan84
Copy link
Contributor Author

@thibaultcha update PR as you suggested.

@Tieske Tieske merged commit 0da9be8 into next Jun 23, 2017
@Tieske Tieske deleted the feat/hmac-header-algo branch June 23, 2017 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants