From c9fde0d6c5ced089d2d9f3eac2df8ecb30f986f5 Mon Sep 17 00:00:00 2001 From: samugi Date: Thu, 1 Sep 2022 18:47:43 +0200 Subject: [PATCH 1/2] feat(config): support base64 encoded *_cert and *_cert_key --- kong/conf_loader/init.lua | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/kong/conf_loader/init.lua b/kong/conf_loader/init.lua index 00487455a126..3cbd4ea4db21 100644 --- a/kong/conf_loader/init.lua +++ b/kong/conf_loader/init.lua @@ -44,6 +44,7 @@ local abspath = pl_path.abspath local tostring = tostring local tonumber = tonumber local setmetatable = setmetatable +local decode_base64 = ngx.decode_base64 local get_phase do @@ -622,6 +623,22 @@ local function infer_value(value, typ, opts) end +local function try_base64_decode(vals) + if type(vals) == "table" then + for k, v in pairs(vals) do + vals[k] = decode_base64(v) or v + end + return vals + end + + if type(vals) == "string" then + return decode_base64(vals) or vals + end + + return vals +end + + -- Validate properties (type/enum/custom) and infer their type. -- @param[type=table] conf The configuration table to treat. local function check_and_infer(conf, opts) @@ -646,6 +663,20 @@ local function check_and_infer(conf, opts) conf[k] = value end + + -- decode base64 for supported fields + for _, prefix in ipairs({ + "ssl", + "admin_ssl", + "status_ssl", + "client_ssl", + "cluster" + }) do + conf[prefix .. "_cert"] = try_base64_decode(conf[prefix .. "_cert"]) + conf[prefix .. "_cert_key"] = try_base64_decode(conf[prefix .. "_cert_key"]) + end + + --------------------- -- custom validations --------------------- From 89b0eeb77352cd107bedc657b010c2dd30750e70 Mon Sep 17 00:00:00 2001 From: samugi Date: Fri, 2 Sep 2022 11:25:13 +0200 Subject: [PATCH 2/2] feat(config): add support for base64url encoding This adds a test case to ensure base64 encoded properties are corectly parsed and decoded. --- kong/conf_loader/init.lua | 14 ++++++---- spec/01-unit/03-conf_loader_spec.lua | 39 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/kong/conf_loader/init.lua b/kong/conf_loader/init.lua index 3cbd4ea4db21..e0f3681fc551 100644 --- a/kong/conf_loader/init.lua +++ b/kong/conf_loader/init.lua @@ -18,6 +18,7 @@ local utils = require "kong.tools.utils" local log = require "kong.cmd.utils.log" local env = require "kong.cmd.utils.env" local ffi = require "ffi" +local base64 = require "ngx.base64" local fmt = string.format @@ -45,6 +46,7 @@ local tostring = tostring local tonumber = tonumber local setmetatable = setmetatable local decode_base64 = ngx.decode_base64 +local decode_base64url = base64.decode_base64url local get_phase do @@ -625,14 +627,18 @@ end local function try_base64_decode(vals) if type(vals) == "table" then - for k, v in pairs(vals) do - vals[k] = decode_base64(v) or v + for i, v in ipairs(vals) do + vals[i] = decode_base64(v) + or decode_base64url(v) + or v end return vals end if type(vals) == "string" then - return decode_base64(vals) or vals + return decode_base64(vals) + or decode_base64url(vals) + or vals end return vals @@ -663,7 +669,6 @@ local function check_and_infer(conf, opts) conf[k] = value end - -- decode base64 for supported fields for _, prefix in ipairs({ "ssl", @@ -676,7 +681,6 @@ local function check_and_infer(conf, opts) conf[prefix .. "_cert_key"] = try_base64_decode(conf[prefix .. "_cert_key"]) end - --------------------- -- custom validations --------------------- diff --git a/spec/01-unit/03-conf_loader_spec.lua b/spec/01-unit/03-conf_loader_spec.lua index ac0c88a09f8f..9840ca9dad4a 100644 --- a/spec/01-unit/03-conf_loader_spec.lua +++ b/spec/01-unit/03-conf_loader_spec.lua @@ -728,6 +728,45 @@ describe("Configuration loader", function() assert.is_nil(conf) end) describe("SSL", function() + it("accepts and decodes valid base64 values", function() + local ssl_fixtures = require "spec.fixtures.ssl" + local prefixes = { + "ssl", + "admin_ssl", + "status_ssl", + "client_ssl", + "cluster" + } + local cert = ssl_fixtures.cert + local key = ssl_fixtures.key + local cert_base64 = ngx.encode_base64(cert) + local key_base64 = ngx.encode_base64(key) + local params = {} + for _, prefix in ipairs(prefixes) do + params[prefix .. "_cert"] = cert_base64 + params[prefix .. "_cert_key"] = key_base64 + end + local conf, err = conf_loader(nil, params) + + assert.is_nil(err) + assert.is_table(conf) + for _, prefix in ipairs(prefixes) do + local certs = conf[prefix .. "_cert"] + local keys = conf[prefix .. "_cert_key"] + + if type(certs) == "table" then + for i = 1, #certs do + assert.equals(cert, certs[i]) + assert.equals(key, keys[i]) + end + end + + if type(certs) == "string" then + assert.equals(cert, certs) + assert.equals(key, keys) + end + end + end) describe("proxy", function() it("does not check SSL cert and key if SSL is off", function() local conf, err = conf_loader(nil, {