Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor ssl handling in preparation of OCSP stapling #5122

Merged
merged 2 commits into from
Feb 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 44 additions & 23 deletions rootfs/etc/nginx/lua/certificate.lua
Original file line number Diff line number Diff line change
@@ -1,59 +1,66 @@
local ssl = require("ngx.ssl")
local configuration = require("configuration")
local re_sub = ngx.re.sub

local _M = {}

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)
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 der_priv_key, dev_priv_key_err = ssl.priv_key_pem_to_der(pem_cert_key)
if not der_priv_key then
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

local der_priv_key, dev_priv_key_err = ssl.priv_key_pem_to_der(pem_cert_key)
if not der_priv_key then
return "failed to convert private key from PEM to DER: " .. dev_priv_key_err
end

local set_priv_key_ok, set_priv_key_err = ssl.set_der_priv_key(der_priv_key)
if not set_priv_key_ok then
return "failed to set DER private key: " .. set_priv_key_err
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 pem_cert_key = configuration.get_pem_cert_key(hostname)
if pem_cert_key then
return pem_cert_key
local uid = certificate_servers:get(hostname)
if uid then
return uid
end

local wildcard_hosatname, _, err = re_sub(hostname, "^[^\\.]+\\.", "*.", "jo")
if err then
ngx.log(ngx.ERR, "error: ", err)
return pem_cert_key
return uid
end

if wildcard_hosatname then
pem_cert_key = configuration.get_pem_cert_key(wildcard_hosatname)
uid = ngx.shared.certificate_servers:get(wildcard_hosatname)
end
return pem_cert_key

return uid
end

function _M.configured_for_current_request()
if ngx.ctx.configured_for_current_request ~= nil then
return ngx.ctx.configured_for_current_request
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
end
Expand All @@ -69,11 +76,15 @@ function _M.call()
hostname = DEFAULT_CERT_HOSTNAME
end

local pem_cert_key = get_pem_cert_key(hostname)
if not pem_cert_key then
pem_cert_key = get_pem_cert_key(DEFAULT_CERT_HOSTNAME)
local pem_cert
local pem_cert_uid = get_pem_cert_uid(hostname)
if not pem_cert_uid then
pem_cert_uid = get_pem_cert_uid(DEFAULT_CERT_HOSTNAME)
end
if pem_cert_uid then
pem_cert = certificate_data:get(pem_cert_uid)
end
if not pem_cert_key then
if not pem_cert then
ngx.log(ngx.ERR, "certificate not found, falling back to fake certificate for hostname: " .. tostring(hostname))
return
end
Expand All @@ -84,11 +95,21 @@ function _M.call()
return ngx.exit(ngx.ERROR)
end

local set_pem_cert_key_err = set_pem_cert_key(pem_cert_key)
if set_pem_cert_key_err then
ngx.log(ngx.ERR, set_pem_cert_key_err)
local der_cert, der_priv_key, der_err = get_der_cert_and_priv_key(pem_cert)
if der_err then
ngx.log(ngx.ERR, der_err)
return ngx.exit(ngx.ERROR)
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

return _M
4 changes: 2 additions & 2 deletions rootfs/etc/nginx/lua/configuration.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ local function fetch_request_body()
return body
end

function _M.get_pem_cert_key(hostname)
local function get_pem_cert(hostname)
local uid = certificate_servers:get(hostname)
if not uid then
return nil
Expand Down Expand Up @@ -143,7 +143,7 @@ local function handle_certs()
return
end

local key = _M.get_pem_cert_key(query["hostname"])
local key = get_pem_cert(query["hostname"])
if key then
ngx.status = ngx.HTTP_OK
ngx.print(key)
Expand Down