From 026b86b5e056f301051a480035aad35cf4e6e697 Mon Sep 17 00:00:00 2001 From: Samuele Illuminati Date: Fri, 2 Sep 2022 15:16:02 +0200 Subject: [PATCH] feat(conf): support base64 encoded *_cert and *_cert_key (#9367) * support base64 encoded *_cert and *_cert_key * support base64url encoding This adds a test case to ensure base64 encoded properties are corectly parsed and decoded. --- kong/conf_loader/init.lua | 35 +++++++++++++++++++++++++ spec/01-unit/03-conf_loader_spec.lua | 39 ++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/kong/conf_loader/init.lua b/kong/conf_loader/init.lua index 00487455a126..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 @@ -44,6 +45,8 @@ local abspath = pl_path.abspath 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 @@ -622,6 +625,26 @@ local function infer_value(value, typ, opts) end +local function try_base64_decode(vals) + if type(vals) == "table" then + 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 decode_base64url(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 +669,18 @@ 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 --------------------- 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, {