# HG changeset patch # User Kim Alvefur # Date 1606005129 -3600 # Node ID d3af5f94d6df8bee1c861e8c8e76b3032cf4b38a # Parent 6d7fb22c0440040303909992c06c90498260298f mod_http_oauth2: Improve storage of client secret Note well: This is still a thing for developers, do not panic! diff -r 6d7fb22c0440 -r d3af5f94d6df mod_adhoc_oauth2_client/mod_adhoc_oauth2_client.lua --- a/mod_adhoc_oauth2_client/mod_adhoc_oauth2_client.lua Sun Nov 22 01:31:27 2020 +0100 +++ b/mod_adhoc_oauth2_client/mod_adhoc_oauth2_client.lua Sun Nov 22 01:32:09 2020 +0100 @@ -1,11 +1,16 @@ local adhoc = require "util.adhoc"; local dataforms = require "util.dataforms"; local errors = require "util.error"; +local hashes = require "util.hashes"; local id = require "util.id"; local jid = require "util.jid"; +local base64 = require"util.encodings".base64; local clients = module:open_store("oauth2_clients", "map"); +local iteration_count = module:get_option_number("oauth2_client_iteration_count", 10000); +local pepper = module:get_option_string("oauth2_client_pepper", ""); + local new_client = dataforms.new({ title = "Create OAuth2 client"; {var = "FORM_TYPE"; type = "hidden"; value = "urn:uuid:ff0d55ed-2187-4ee0-820a-ab633a911c14#create"}; @@ -32,15 +37,19 @@ local creator = jid.split(data.from); local client_id = id.short(); + local client_secret = id.long(); + local salt = id.medium(); + local i = iteration_count; - client.client_id = jid.join(creator, module.host, client_id); - client.client_secret = id.long(); + client.secret_hash = base64.encode(hashes.pbkdf2_hmac_sha256(client_secret, salt .. pepper, i)); + client.iteration_count = i; + client.salt = salt; local ok, err = errors.coerce(clients:set(creator, client_id, client)); module:log("info", "OAuth2 client %q created by %s", client_id, data.from); if not ok then return {status = "error"; error = {message = err}}; end - return {status = "completed"; result = {layout = client_created; values = client}}; + return {status = "completed"; result = {layout = client_created; values = {client_id = client.client_id; client_secret = client_secret}}}; end local handler = adhoc.new_simple_form(new_client, create_client); diff -r 6d7fb22c0440 -r d3af5f94d6df mod_http_oauth2/mod_http_oauth2.lua --- a/mod_http_oauth2/mod_http_oauth2.lua Sun Nov 22 01:31:27 2020 +0100 +++ b/mod_http_oauth2/mod_http_oauth2.lua Sun Nov 22 01:32:09 2020 +0100 @@ -1,3 +1,4 @@ +local hashes = require "util.hashes"; local http = require "util.http"; local jid = require "util.jid"; local json = require "util.json"; @@ -90,6 +91,12 @@ } end +local pepper = module:get_option_string("oauth2_client_pepper", ""); + +local function verify_secret(stored, salt, i, secret) + return base64.decode(stored) == hashes.pbkdf2_hmac_sha256(secret, salt .. pepper, i); +end + function grant_type_handlers.authorization_code(params) if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end if not params.client_secret then return oauth_error("invalid_request", "missing 'client_secret'"); end @@ -105,7 +112,7 @@ end local client, err = clients:get(client_owner, client_id); if err then error(err); end - if not client or client.client_secret ~= params.client_secret then + if not client or not verify_secret(client.secret_hash, client.salt, client.iteration_count, params.client_secret) then module:log("debug", "client_secret mismatch"); return oauth_error("invalid_client", "incorrect credentials"); end