Files
2026-07-13 12:32:21 +08:00

254 lines
7.7 KiB
Lua

local helpers = require "spec.helpers"
local cjson = require "cjson"
local merge = kong.table.merge
local fmt = string.format
for _, strategy in helpers.all_strategies() do
describe("db.keys #" .. strategy, function()
local init_key_set, init_pem_key, pem_pub, pem_priv, jwk
local bp, db
lazy_setup(function()
helpers.setenv("JWK_SECRET", "wowsuchsecret")
bp, db = helpers.get_db_utils(strategy ~= "off" and strategy or nil, {
"vaults",
"keys",
"key_sets"
})
init_key_set = assert(bp.key_sets:insert {
name = "testset",
})
local jwk_pub, jwk_priv = helpers.generate_keys("JWK")
pem_pub, pem_priv = helpers.generate_keys("PEM")
jwk = merge(cjson.decode(jwk_pub), cjson.decode(jwk_priv))
end)
after_each(function()
db:truncate("keys")
end)
lazy_teardown(function()
db:truncate("key_sets")
end)
it(":select returns an item [jwk]", function()
local key, err = assert(bp.keys:insert {
name = "testjwk",
set = init_key_set,
kid = jwk.kid,
jwk = cjson.encode(jwk)
})
assert(key)
assert.is_nil(err)
local key_o, s_err = db.keys:select(key)
assert.is_nil(s_err)
assert.same("string", type(key_o.jwk))
end)
it(":select returns an item [pem]", function()
init_pem_key = assert(bp.keys:insert {
name = "testpem",
set = init_key_set,
kid = "456",
pem = {
public_key = pem_pub,
private_key = pem_priv
}
})
local key_o, err = db.keys:select(init_pem_key)
assert.is_nil(err)
assert.same('456', key_o.kid)
assert.same(pem_priv, key_o.pem.private_key)
assert.same(pem_pub, key_o.pem.public_key)
end)
it(":cache_key", function()
local cache_key, err = db.keys:cache_key({kid = "456", set = {id = init_key_set.id}})
assert.is_nil(err)
assert.equal(fmt("keys:456:%s", init_key_set.id), cache_key)
end)
it(":cache_key no set present", function()
local cache_key, err = db.keys:cache_key({kid = "123"})
assert.is_nil(err)
assert.equal("keys:123:", cache_key)
end)
it(":cache_key invalid set type", function()
local cache_key, err = db.keys:cache_key({kid = "123", set = ""})
assert.is_nil(err)
assert.equal("keys:123:", cache_key)
end)
it(":cache_key must handle missing id field", function()
local cache_key, err = db.keys:cache_key({kid = "123", set = { }})
assert.is_nil(err)
assert.equal("keys:123:", cache_key)
end)
it(":insert handles field vault references ", function()
local reference = "{vault://env/jwk_secret}"
local ref, insert_err = db.keys:insert {
name = "vault references",
set = init_key_set,
kid = "1",
jwk = reference
}
assert.is_nil(insert_err)
assert.same(ref["$refs"]["jwk"], reference)
assert.same(ref.jwk, "wowsuchsecret")
end)
it(":insert handles field private_key when passing a vault reference", function()
local reference = "{vault://env/jwk_secret}"
local ref, insert_err = db.keys:insert {
name = "vault references",
set = init_key_set,
kid = "1",
pem = { private_key = reference, public_key = pem_pub }
}
assert.is_nil(insert_err)
assert.same(ref.pem["$refs"]["private_key"], reference)
assert.same(ref.pem["private_key"], "wowsuchsecret")
end)
it(":insert handles field public_key when passing a vault reference", function()
local reference = "{vault://env/jwk_secret}"
local ref, insert_err = db.keys:insert {
name = "vault references",
set = init_key_set,
kid = "1",
pem = { private_key = pem_priv, public_key = reference}
}
assert.is_nil(insert_err)
assert.same(ref.pem["$refs"]["public_key"], reference)
assert.same(ref.pem["public_key"], "wowsuchsecret")
end)
it("kid is unique accross sets", function()
local test2, err = db.key_sets:insert {
name = "test2"
}
assert.is_nil(err)
assert.is_not_nil(test2)
local key, insert_err = db.keys:insert {
name = "each_test",
set = init_key_set,
kid = "999",
pem = { private_key = pem_priv, public_key = pem_pub }
}
assert.is_nil(insert_err)
assert.is_not_nil(key)
-- inserting a key with the same kid in a different keyset.
-- this should not raise a validation error
local key2, insert2_err = db.keys:insert {
name = "each_test_1",
set = test2,
kid = "999",
pem = { private_key = pem_priv, public_key = pem_pub }
}
assert.is_nil(insert2_err)
assert.is_not_nil(key2)
end)
it(":get_pubkey and :get_privkey [pem]", function()
local pem_t, err = db.keys:insert {
name = "pem_key",
set = init_key_set,
kid = "999",
pem = { private_key = pem_priv, public_key = pem_pub }
}
assert.is_nil(err)
assert(pem_t)
local pem_pub_t, g_err = db.keys:get_pubkey(pem_t)
assert.is_nil(g_err)
assert.matches("-----BEGIN PUBLIC KEY", pem_pub_t)
local pem_priv, p_err = db.keys:get_privkey(pem_t)
assert.is_nil(p_err)
assert.matches("-----BEGIN PRIVATE KEY", pem_priv)
end)
it(":get_pubkey and :get_privkey [jwk]", function()
local jwk_t, _ = db.keys:insert {
name = "jwk_key",
set = init_key_set,
kid = jwk.kid,
jwk = cjson.encode(jwk)
}
assert(jwk_t)
local jwk_pub, err = db.keys:get_pubkey(jwk_t)
assert.is_nil(err)
local jwk_pub_o = cjson.decode(jwk_pub)
assert.is_not_nil(jwk_pub_o.e)
assert.is_not_nil(jwk_pub_o.kid)
assert.is_not_nil(jwk_pub_o.kty)
assert.is_not_nil(jwk_pub_o.n)
local jwk_priv, err_t = db.keys:get_privkey(jwk_t)
local decoded_jwk = cjson.decode(jwk_priv)
assert.is_nil(err_t)
assert.is_not_nil(decoded_jwk.kid)
assert.is_not_nil(decoded_jwk.kty)
assert.is_not_nil(decoded_jwk.d)
assert.is_not_nil(decoded_jwk.dp)
assert.is_not_nil(decoded_jwk.dq)
assert.is_not_nil(decoded_jwk.e)
assert.is_not_nil(decoded_jwk.n)
assert.is_not_nil(decoded_jwk.p)
assert.is_not_nil(decoded_jwk.q)
assert.is_not_nil(decoded_jwk.qi)
end)
it(":get_privkey errors if only got pubkey [pem]", function()
local pem_t, err = db.keys:insert {
name = "pem_key",
set = init_key_set,
kid = "999",
pem = { public_key = pem_pub }
}
assert.is_nil(err)
assert(pem_t)
local pem_pub_t, g_err = db.keys:get_pubkey(pem_t)
assert.is_nil(g_err)
assert.matches("-----BEGIN PUBLIC KEY", pem_pub_t)
local pem_priv, p_err = db.keys:get_privkey(pem_t)
assert.is_nil(pem_priv)
assert.matches("could not load a private key from public key material", p_err)
end)
it(":get_privkey errors if only got pubkey [jwk]", function()
jwk.d = nil
local jwk_t, _ = db.keys:insert {
name = "jwk_key",
set = init_key_set,
kid = jwk.kid,
jwk = cjson.encode(jwk)
}
assert(jwk_t)
local jwk_pub_t, g_err = db.keys:get_pubkey(jwk_t)
assert.is_nil(g_err)
local jwk_pub_o = cjson.decode(jwk_pub_t)
assert.is_not_nil(jwk_pub_o.e)
assert.is_not_nil(jwk_pub_o.kid)
assert.is_not_nil(jwk_pub_o.kty)
assert.is_not_nil(jwk_pub_o.n)
local jwk_priv, p_err = db.keys:get_privkey(jwk_t)
assert.is_nil(jwk_priv)
assert.matches("could not load a private key from public key material", p_err)
end)
end)
end