aboutsummaryrefslogtreecommitdiffstats
path: root/server/resty/openssl/dh.lua
diff options
context:
space:
mode:
Diffstat (limited to 'server/resty/openssl/dh.lua')
-rw-r--r--server/resty/openssl/dh.lua142
1 files changed, 142 insertions, 0 deletions
diff --git a/server/resty/openssl/dh.lua b/server/resty/openssl/dh.lua
new file mode 100644
index 0000000..93e4941
--- /dev/null
+++ b/server/resty/openssl/dh.lua
@@ -0,0 +1,142 @@
+local ffi = require "ffi"
+local C = ffi.C
+
+require "resty.openssl.include.dh"
+local bn_lib = require "resty.openssl.bn"
+
+local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10
+local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER
+local format_error = require("resty.openssl.err").format_error
+
+local _M = {}
+
+_M.params = {"public", "private", "p", "q", "g"}
+
+local empty_table = {}
+local bn_ptrptr_ct = ffi.typeof("const BIGNUM *[1]")
+function _M.get_parameters(dh_st)
+ return setmetatable(empty_table, {
+ __index = function(_, k)
+ local ptr, ret
+ if OPENSSL_11_OR_LATER then
+ ptr = bn_ptrptr_ct()
+ end
+
+ if OPENSSL_11_OR_LATER then
+ ptr = bn_ptrptr_ct()
+ end
+
+ if k == 'p' then
+ if OPENSSL_11_OR_LATER then
+ C.DH_get0_pqg(dh_st, ptr, nil, nil)
+ end
+ elseif k == 'q' then
+ if OPENSSL_11_OR_LATER then
+ C.DH_get0_pqg(dh_st, nil, ptr, nil)
+ end
+ elseif k == 'g' then
+ if OPENSSL_11_OR_LATER then
+ C.DH_get0_pqg(dh_st, nil, nil, ptr)
+ end
+ elseif k == 'public' then
+ if OPENSSL_11_OR_LATER then
+ C.DH_get0_key(dh_st, ptr, nil)
+ end
+ k = "pub_key"
+ elseif k == 'private' then
+ if OPENSSL_11_OR_LATER then
+ C.DH_get0_key(dh_st, nil, ptr)
+ end
+ k = "priv_key"
+ else
+ return nil, "rsa.get_parameters: unknown parameter \"" .. k .. "\" for RSA key"
+ end
+
+ if OPENSSL_11_OR_LATER then
+ ret = ptr[0]
+ elseif OPENSSL_10 then
+ ret = dh_st[k]
+ end
+
+ if ret == nil then
+ return nil
+ end
+ return bn_lib.dup(ret)
+ end
+ }), nil
+end
+
+local function dup_bn_value(v)
+ if not bn_lib.istype(v) then
+ return nil, "expect value to be a bn instance"
+ end
+ local bn = C.BN_dup(v.ctx)
+ if bn == nil then
+ return nil, "BN_dup() failed"
+ end
+ return bn
+end
+
+function _M.set_parameters(dh_st, opts)
+ local err
+ local opts_bn = {}
+ -- remember which parts of BNs has been added to dh_st, they should be freed
+ -- by DH_free and we don't cleanup them on failure
+ local cleanup_from_idx = 1
+ -- dup input
+ local do_set_key, do_set_pqg
+ for k, v in pairs(opts) do
+ opts_bn[k], err = dup_bn_value(v)
+ if err then
+ err = "dh.set_parameters: cannot process parameter \"" .. k .. "\":" .. err
+ goto cleanup_with_error
+ end
+ if k == "private" or k == "public" then
+ do_set_key = true
+ elseif k == "p" or k == "q" or k == "g" then
+ do_set_pqg = true
+ end
+ end
+ if OPENSSL_11_OR_LATER then
+ local code
+ if do_set_key then
+ code = C.DH_set0_key(dh_st, opts_bn["public"], opts_bn["private"])
+ if code == 0 then
+ err = format_error("dh.set_parameters: DH_set0_key")
+ goto cleanup_with_error
+ end
+ end
+ cleanup_from_idx = cleanup_from_idx + 2
+ if do_set_pqg then
+ code = C.DH_set0_pqg(dh_st, opts_bn["p"], opts_bn["q"], opts_bn["g"])
+ if code == 0 then
+ err = format_error("dh.set_parameters: DH_set0_pqg")
+ goto cleanup_with_error
+ end
+ end
+ return true
+ elseif OPENSSL_10 then
+ for k, v in pairs(opts_bn) do
+ if k == "public" then
+ k = "pub_key"
+ elseif k == "private" then
+ k = "priv_key"
+ end
+ if dh_st[k] ~= nil then
+ C.BN_free(dh_st[k])
+ end
+ dh_st[k]= v
+ end
+ return true
+ end
+
+::cleanup_with_error::
+ for i, k in pairs(_M.params) do
+ if i >= cleanup_from_idx then
+ C.BN_free(opts_bn[k])
+ end
+ end
+ return false, err
+end
+
+return _M