Skip to content

Commit

Permalink
fix(oauth2): use new style KDF API to work better with FIPS mode
Browse files Browse the repository at this point in the history
  • Loading branch information
fffonion committed Dec 15, 2023
1 parent 7f93a92 commit 1c38342
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 14 deletions.
43 changes: 29 additions & 14 deletions kong/plugins/oauth2/secret.lua
Original file line number Diff line number Diff line change
Expand Up @@ -201,27 +201,42 @@ if ENABLED_ALGORITHMS.PBKDF2 then
local PBKDF2_PREFIX

local ok, crypt = pcall(function()
local kdf = require "resty.openssl.kdf"
local openssl_kdf = require "resty.openssl.kdf"

-- pbkdf2 settings
-- pbkdf2 default settings
local PBKDF2_DIGEST = "sha512"
local PBKDF2_ITERATIONS = 10000
local PBKDF2_HASH_LEN = 32
local PBKDF2_SALT_LEN = 16

local EMPTY = {}

local kdf

local function derive(secret, opts)
opts = opts or EMPTY
local err
if kdf then
local _, err = kdf:reset()
if err then
kdf = nil
end
end

if not kdf then
kdf, err = openssl_kdf.new("PBKDF2")
if err then
return nil, err
end
end

local salt = opts.salt or utils.get_rand_bytes(PBKDF2_SALT_LEN)
local hash, err = kdf.derive({
type = kdf.PBKDF2,
outlen = opts.outlen or PBKDF2_HASH_LEN,
local hash, err = kdf:derive(opts.outlen or PBKDF2_HASH_LEN, {
pass = secret,
salt = salt,
md = opts.md or PBKDF2_DIGEST,
pbkdf2_iter = opts.pbkdf2_iter or PBKDF2_ITERATIONS,
})
digest = opts.digest or PBKDF2_DIGEST,
iter = opts.iter or PBKDF2_ITERATIONS,
}, 4)
if not hash then
return nil, err
end
Expand All @@ -245,8 +260,8 @@ if ENABLED_ALGORITHMS.PBKDF2 then

local crypt = {}

function crypt.hash(secret)
return derive(secret)
function crypt.hash(secret, options)
return derive(secret, options)
end

function crypt.verify(secret, hash)
Expand All @@ -263,8 +278,8 @@ if ENABLED_ALGORITHMS.PBKDF2 then
local calculated_hash, err = derive(secret, {
outlen = outlen,
salt = phc.salt,
md = phc.digest,
pbkdf2_iter = phc.params.i
digest = phc.digest,
iter = phc.params.i
})
if not calculated_hash then
return nil, err
Expand All @@ -287,7 +302,7 @@ end
local crypt = {}


function crypt.hash(secret)
function crypt.hash(secret, options)
assert(type(secret) == "string", "secret needs to be a string")

if ARGON2 then
Expand All @@ -299,7 +314,7 @@ function crypt.hash(secret)
end

if PBKDF2 then
return PBKDF2.hash(secret)
return PBKDF2.hash(secret, options)
end

return nil, "no suitable password hashing algorithm found"
Expand Down
51 changes: 51 additions & 0 deletions spec/03-plugins/25-oauth2/05-kdf_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
-- This software is copyright Kong Inc. and its licensors.
-- Use of the software is subject to the agreement between your organization
-- and Kong Inc. If there is no such agreement, use is governed by and
-- subject to the terms of the Kong Master Software License Agreement found
-- at https://konghq.com/enterprisesoftwarelicense/.
-- [ END OF LICENSE 0867164ffc95e54f04670b5169c09574bdbd9bba ]

local secret_impl = require "kong.plugins.oauth2.secret"


describe("Plugin: oauth2 (secret)", function()
describe("PBKDF", function()

local static_key = "$pbkdf2-sha512$i=10000,l=32$YSBsaXR0ZSBiaXQsIGp1c3QgYSBsaXR0bGUgYml0$z6ysNworexAhDELywIDi0ba0B0T7F/MBZ6Ige9lWRYI"

it("sanity test", function()
-- Note: to pass test in FIPS mode, salt length has to be 16 bytes or more
local derived, err = secret_impl.hash("tofu", { salt = "a litte bit, just a little bit" })
assert.is_nil(err)
assert.same(static_key, derived)
end)

it("uses random salt by default", function()
local derived, err = secret_impl.hash("tofu")
assert.is_nil(err)
assert.not_same(static_key, derived)
end)

it("verifies correctly", function()
local derived, err = secret_impl.hash("tofu")
assert.is_nil(err)

local ok, err = secret_impl.verify("tofu", derived)
assert.is_nil(err)
assert.is_truthy(ok)

local ok, err = secret_impl.verify("tofu", static_key)
assert.is_nil(err)
assert.is_truthy(ok)


local derived2, err = secret_impl.hash("bun")
assert.is_nil(err)

local ok, err = secret_impl.verify("tofu", derived2)
assert.is_nil(err)
assert.is_falsy(ok)
end)

end)
end)

0 comments on commit 1c38342

Please sign in to comment.