Skip to content

Commit

Permalink
feat(provider) cipher, digest, kdf, pkey and x509 can now fetch
Browse files Browse the repository at this point in the history
by provider and has new get_provider_name function
  • Loading branch information
fffonion committed Oct 23, 2021
1 parent 5ffbbcc commit 52938ca
Show file tree
Hide file tree
Showing 11 changed files with 156 additions and 25 deletions.
40 changes: 31 additions & 9 deletions lib/resty/openssl/cipher.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ local mt = {__index = _M}

local cipher_ctx_ptr_ct = ffi.typeof('EVP_CIPHER_CTX*')

function _M.new(typ)
function _M.new(typ, properties)
if not typ then
return nil, "cipher.new: expect type to be defined"
end
Expand All @@ -39,19 +39,25 @@ function _M.new(typ)
return nil, "cipher.new: failed to create EVP_CIPHER_CTX"
end

local dtyp = C.EVP_get_cipherbyname(typ)
if dtyp == nil then
return nil, string.format("cipher.new: invalid cipher type \"%s\"", typ)
local ctyp
if OPENSSL_30 then
ctyp = C.EVP_CIPHER_fetch(nil, typ, properties)
else
ctyp = C.EVP_get_cipherbyname(typ)
end
local err_new = string.format("cipher.new: invalid cipher type \"%s\"", typ)
if ctyp == nil then
return nil, format_error(err_new)
end

local code = C.EVP_CipherInit_ex(ctx, dtyp, nil, "", nil, -1)
local code = C.EVP_CipherInit_ex(ctx, ctyp, nil, "", nil, -1)
if code ~= 1 then
return nil, format_error("cipher.new")
return nil, format_error(err_new)
end

return setmetatable({
ctx = ctx,
cipher_type = dtyp,
cipher_type = ctyp,
initialized = false,
block_size = tonumber(OPENSSL_30 and C.EVP_CIPHER_CTX_get_block_size(ctx)
or C.EVP_CIPHER_CTX_block_size(ctx)),
Expand All @@ -66,6 +72,17 @@ function _M.istype(l)
return l and l.ctx and ffi.istype(cipher_ctx_ptr_ct, l.ctx)
end

function _M:get_provider_name()
if not OPENSSL_30 then
return false, "cipher:get_provider_name is not supported"
end
local p = C.EVP_CIPHER_get0_provider(self.cipher_type)
if p == nil then
return nil
end
return ffi_str(C.OSSL_PROVIDER_get0_name(p))
end

function _M:init(key, iv, opts)
opts = opts or {}
if not key or #key ~= self.key_size then
Expand Down Expand Up @@ -221,7 +238,7 @@ function _M:final(s)
return (ret or "") .. ffi_str(outm, outl[0])
end

function _M:derive(key, salt, count, md)
function _M:derive(key, salt, count, md, md_properties)
if type(key) ~= "string" then
return nil, nil, "cipher:derive: expect a string at #1"
elseif salt and type(salt) ~= "string" then
Expand All @@ -245,7 +262,12 @@ function _M:derive(key, salt, count, md)
end
end

local mdt = C.EVP_get_digestbyname(md or 'sha1')
local mdt
if OPENSSL_30 then
mdt = C.EVP_MD_fetch(nil, md or 'sha1', md_properties)
else
mdt = C.EVP_get_digestbyname(md or 'sha1')
end
if mdt == nil then
return nil, nil, string.format("cipher:derive: invalid digest type \"%s\"", md)
end
Expand Down
25 changes: 21 additions & 4 deletions lib/resty/openssl/digest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ local mt = {__index = _M}

local md_ctx_ptr_ct = ffi.typeof('EVP_MD_CTX*')

function _M.new(typ)
function _M.new(typ, properties)
local ctx
if OPENSSL_11_OR_LATER then
ctx = C.EVP_MD_CTX_new()
Expand All @@ -28,19 +28,25 @@ function _M.new(typ)
return nil, "digest.new: failed to create EVP_MD_CTX"
end

local err_new = string.format("digest.new: invalid digest type \"%s\"", typ)

local dtyp
if typ == "null" then
dtyp = C.EVP_md_null()
else
dtyp = C.EVP_get_digestbyname(typ or 'sha1')
if OPENSSL_30 then
dtyp = C.EVP_MD_fetch(nil, typ or 'sha1', properties)
else
dtyp = C.EVP_get_digestbyname(typ or 'sha1')
end
if dtyp == nil then
return nil, string.format("digest.new: invalid digest type \"%s\"", typ)
return nil, format_error(err_new)
end
end

local code = C.EVP_DigestInit_ex(ctx, dtyp, nil)
if code ~= 1 then
return nil, format_error("digest.new")
return nil, format_error(err_new)
end

return setmetatable({
Expand All @@ -54,6 +60,17 @@ function _M.istype(l)
return l and l.ctx and ffi.istype(md_ctx_ptr_ct, l.ctx)
end

function _M:get_provider_name()
if not OPENSSL_30 then
return false, "digest:get_provider_name is not supported"
end
local p = C.EVP_MD_get0_provider(self.dtyp)
if p == nil then
return nil
end
return ffi_str(C.OSSL_PROVIDER_get0_name(p))
end

function _M:update(...)
for _, s in ipairs({...}) do
if C.EVP_DigestUpdate(self.ctx, s, #s) ~= 1 then
Expand Down
1 change: 1 addition & 0 deletions lib/resty/openssl/include/asn1.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ declare_asn1_functions("ASN1_ENUMERATED")

local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10
local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER
local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110

local ASN1_STRING_get0_data
if OPENSSL_11_OR_LATER then
Expand Down
6 changes: 5 additions & 1 deletion lib/resty/openssl/kdf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,11 @@ function _M.derive(options)
end

local md
md = C.EVP_get_digestbyname(options.md or "sha1")
if OPENSSL_30 and false then
md = C.EVP_MD_fetch(nil, options.md or 'sha1', options.properties)
else
md = C.EVP_get_digestbyname(options.md or 'sha1')
end
if md == nil then
return nil, string.format("kdf.derive: invalid digest type \"%s\"", md)
end
Expand Down
17 changes: 16 additions & 1 deletion lib/resty/openssl/pkey.lua
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,17 @@ function _M:get_key_type()
return objects_lib.nid2table(self.key_type)
end

function _M:get_provider_name()
if not OPENSSL_30 then
return false, "pkey:get_provider_name is not supported"
end
local p = C.EVP_PKEY_get0_provider(self.ctx)
if p == nil then
return nil
end
return ffi_str(C.OSSL_PROVIDER_get0_name(p))
end

local get_pkey_key
if OPENSSL_11_OR_LATER then
get_pkey_key = {
Expand Down Expand Up @@ -648,7 +659,11 @@ local function sign_verify_prepare(self, fint, md_alg, padding, opts)

local dtyp
if md_alg then
dtyp = C.EVP_get_digestbyname(md_alg)
if OPENSSL_30 then
dtyp = C.EVP_MD_fetch(nil, md_alg, nil)
else
dtyp = C.EVP_get_digestbyname(md_alg)
end
if dtyp == nil then
return nil, string.format("pkey:sign_verify_prepare: invalid digest type \"%s\"", md_alg)
end
Expand Down
1 change: 1 addition & 0 deletions lib/resty/openssl/version.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ return setmetatable({
OPENSSL_111_OR_LATER = version_num >= 0x10101000 and version_num < 0x30100000,
OPENSSL_10 = version_num < 0x10100000 and version_num > 0x10000000,
BORINGSSL = BORINGSSL,
BORINGSSL_110 = BORINGSSL and version_num >= 0x10100000 and version_num < 0x10101000
}, {
__index = types_table,
})
17 changes: 11 additions & 6 deletions lib/resty/openssl/x509/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ function _M:get_crl_url(return_all)
end
end

local function digest(self, cfunc, typ)
local function digest(self, cfunc, typ, properties)
-- TODO: dedup the following with resty.openssl.digest
local ctx
if OPENSSL_11_OR_LATER then
Expand All @@ -327,7 +327,12 @@ local function digest(self, cfunc, typ)
return nil, "x509:digest: failed to create EVP_MD_CTX"
end

local dtyp = C.EVP_get_digestbyname(typ or 'sha1')
local dtyp
if OPENSSL_30 then
dtyp = C.EVP_MD_fetch(nil, typ or 'sha1', properties)
else
dtyp = C.EVP_get_digestbyname(typ or 'sha1')
end
if dtyp == nil then
return nil, string.format("x509:digest: invalid digest type \"%s\"", typ)
end
Expand All @@ -343,12 +348,12 @@ local function digest(self, cfunc, typ)
return ffi_str(buf, length[0])
end

function _M:digest(typ)
return digest(self, C.X509_digest, typ)
function _M:digest(typ, properties)
return digest(self, C.X509_digest, typ, properties)
end

function _M:pubkey_digest(typ)
return digest(self, C.X509_pubkey_digest, typ)
function _M:pubkey_digest(typ, properties)
return digest(self, C.X509_pubkey_digest, typ, properties)
end

function _M:check_private_key(key)
Expand Down
24 changes: 23 additions & 1 deletion t/openssl/cipher.t
Original file line number Diff line number Diff line change
Expand Up @@ -366,4 +366,26 @@ nil
nil
"
--- no_error_log
[error]
[error]
=== TEST 13: Returns provider
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
if not require("resty.openssl.version").OPENSSL_30 then
ngx.say("default")
ngx.exit(0)
end
local cipher = require("resty.openssl.cipher")
local c = myassert(cipher.new("aes256"))
ngx.say(myassert(c:get_provider_name()))
}
}
--- request
GET /t
--- response_body
default
--- no_error_log
[error]
22 changes: 22 additions & 0 deletions t/openssl/digest.t
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,26 @@ __DATA__
2iuYqSWdAyVAtQxL/p+AOl2kqp83fN4k+da6ngAt8+s=
"
--- no_error_log
[error]

=== TEST 6: Returns provider
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
if not require("resty.openssl.version").OPENSSL_30 then
ngx.say("default")
ngx.exit(0)
end
local digest = require("resty.openssl.digest")
local d = myassert(digest.new("sha256"))
ngx.say(myassert(d:get_provider_name()))
}
}
--- request
GET /t
--- response_body
default
--- no_error_log
[error]
4 changes: 2 additions & 2 deletions t/openssl/hmac.t
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ __DATA__
}
--- request
GET /t
--- response_body eval
"hmac.new: invalid digest type \"sha257\""
--- response_body_like eval
"hmac.new:.+(?:invalid|unsupported).*"
--- no_error_log
[error]

Expand Down
24 changes: 23 additions & 1 deletion t/openssl/pkey.t
Original file line number Diff line number Diff line change
Expand Up @@ -1123,9 +1123,31 @@ true
GET /t
--- response_body_like eval
"errored out with too many callbacks
pkey.new.+(?:bad decrypt|failed|BAD_DECRYPT|no start line|DECODER routines::unsupported)
pkey.new.+(?:bad decrypt|failed|BAD_DECRYPT|no start line|NO_START_LINE|DECODER routines::unsupported)
ok
ok
"
--- no_error_log
[error]

=== TEST 34: Returns provider
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
if not require("resty.openssl.version").OPENSSL_30 then
ngx.say("default")
ngx.exit(0)
end
local pkey = require("resty.openssl.pkey")
local p = myassert(pkey.new({ type = "EC" }))
ngx.say(myassert(p:get_provider_name()))
}
}
--- request
GET /t
--- response_body
default
--- no_error_log
[error]

0 comments on commit 52938ca

Please sign in to comment.