Merge pull request #5122 from ElvinEfendi/lua-ssl-refactoring

refactor ssl handling in preparation of OCSP stapling
This commit is contained in:
Kubernetes Prow Robot 2020-02-19 14:39:46 -08:00 committed by GitHub
commit 9cf4154f4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 26 deletions

View file

@ -1,25 +1,31 @@
local ssl = require("ngx.ssl") local ssl = require("ngx.ssl")
local configuration = require("configuration")
local re_sub = ngx.re.sub local re_sub = ngx.re.sub
local _M = {} local _M = {}
local DEFAULT_CERT_HOSTNAME = "_" local DEFAULT_CERT_HOSTNAME = "_"
local function set_pem_cert_key(pem_cert_key) local certificate_data = ngx.shared.certificate_data
local certificate_servers = ngx.shared.certificate_servers
local function get_der_cert_and_priv_key(pem_cert_key)
local der_cert, der_cert_err = ssl.cert_pem_to_der(pem_cert_key) local der_cert, der_cert_err = ssl.cert_pem_to_der(pem_cert_key)
if not der_cert then if not der_cert then
return "failed to convert certificate chain from PEM to DER: " .. der_cert_err return nil, nil, "failed to convert certificate chain from PEM to DER: " .. der_cert_err
end
local set_cert_ok, set_cert_err = ssl.set_der_cert(der_cert)
if not set_cert_ok then
return "failed to set DER cert: " .. set_cert_err
end end
local der_priv_key, dev_priv_key_err = ssl.priv_key_pem_to_der(pem_cert_key) local der_priv_key, dev_priv_key_err = ssl.priv_key_pem_to_der(pem_cert_key)
if not der_priv_key then if not der_priv_key then
return "failed to convert private key from PEM to DER: " .. dev_priv_key_err return nil, nil, "failed to convert private key from PEM to DER: " .. dev_priv_key_err
end
return der_cert, der_priv_key, nil
end
local function set_der_cert_and_key(der_cert, der_priv_key)
local set_cert_ok, set_cert_err = ssl.set_der_cert(der_cert)
if not set_cert_ok then
return "failed to set DER cert: " .. set_cert_err
end end
local set_priv_key_ok, set_priv_key_err = ssl.set_der_priv_key(der_priv_key) local set_priv_key_ok, set_priv_key_err = ssl.set_der_priv_key(der_priv_key)
@ -28,24 +34,25 @@ local function set_pem_cert_key(pem_cert_key)
end end
end end
local function get_pem_cert_key(raw_hostname) local function get_pem_cert_uid(raw_hostname)
local hostname = re_sub(raw_hostname, "\\.$", "", "jo") local hostname = re_sub(raw_hostname, "\\.$", "", "jo")
local pem_cert_key = configuration.get_pem_cert_key(hostname) local uid = certificate_servers:get(hostname)
if pem_cert_key then if uid then
return pem_cert_key return uid
end end
local wildcard_hosatname, _, err = re_sub(hostname, "^[^\\.]+\\.", "*.", "jo") local wildcard_hosatname, _, err = re_sub(hostname, "^[^\\.]+\\.", "*.", "jo")
if err then if err then
ngx.log(ngx.ERR, "error: ", err) ngx.log(ngx.ERR, "error: ", err)
return pem_cert_key return uid
end end
if wildcard_hosatname then if wildcard_hosatname then
pem_cert_key = configuration.get_pem_cert_key(wildcard_hosatname) uid = ngx.shared.certificate_servers:get(wildcard_hosatname)
end end
return pem_cert_key
return uid
end end
function _M.configured_for_current_request() function _M.configured_for_current_request()
@ -53,7 +60,7 @@ function _M.configured_for_current_request()
return ngx.ctx.configured_for_current_request return ngx.ctx.configured_for_current_request
end end
ngx.ctx.configured_for_current_request = get_pem_cert_key(ngx.var.host) ~= nil ngx.ctx.configured_for_current_request = get_pem_cert_uid(ngx.var.host) ~= nil
return ngx.ctx.configured_for_current_request return ngx.ctx.configured_for_current_request
end end
@ -69,11 +76,15 @@ function _M.call()
hostname = DEFAULT_CERT_HOSTNAME hostname = DEFAULT_CERT_HOSTNAME
end end
local pem_cert_key = get_pem_cert_key(hostname) local pem_cert
if not pem_cert_key then local pem_cert_uid = get_pem_cert_uid(hostname)
pem_cert_key = get_pem_cert_key(DEFAULT_CERT_HOSTNAME) if not pem_cert_uid then
pem_cert_uid = get_pem_cert_uid(DEFAULT_CERT_HOSTNAME)
end end
if not pem_cert_key then if pem_cert_uid then
pem_cert = certificate_data:get(pem_cert_uid)
end
if not pem_cert then
ngx.log(ngx.ERR, "certificate not found, falling back to fake certificate for hostname: " .. tostring(hostname)) ngx.log(ngx.ERR, "certificate not found, falling back to fake certificate for hostname: " .. tostring(hostname))
return return
end end
@ -84,11 +95,21 @@ function _M.call()
return ngx.exit(ngx.ERROR) return ngx.exit(ngx.ERROR)
end end
local set_pem_cert_key_err = set_pem_cert_key(pem_cert_key) local der_cert, der_priv_key, der_err = get_der_cert_and_priv_key(pem_cert)
if set_pem_cert_key_err then if der_err then
ngx.log(ngx.ERR, set_pem_cert_key_err) ngx.log(ngx.ERR, der_err)
return ngx.exit(ngx.ERROR) return ngx.exit(ngx.ERROR)
end end
local set_der_err = set_der_cert_and_key(der_cert, der_priv_key)
if set_der_err then
ngx.log(ngx.ERR, set_der_err)
return ngx.exit(ngx.ERROR)
end
-- TODO: based on `der_cert` find OCSP responder URL
-- make OCSP request and POST it there and get the response and staple it to
-- the current SSL connection if OCSP stapling is enabled
end end
return _M return _M

View file

@ -37,7 +37,7 @@ local function fetch_request_body()
return body return body
end end
function _M.get_pem_cert_key(hostname) local function get_pem_cert(hostname)
local uid = certificate_servers:get(hostname) local uid = certificate_servers:get(hostname)
if not uid then if not uid then
return nil return nil
@ -143,7 +143,7 @@ local function handle_certs()
return return
end end
local key = _M.get_pem_cert_key(query["hostname"]) local key = get_pem_cert(query["hostname"])
if key then if key then
ngx.status = ngx.HTTP_OK ngx.status = ngx.HTTP_OK
ngx.print(key) ngx.print(key)