Skip to content

Commit

Permalink
fix(*) test cdata type before passing in ffi
Browse files Browse the repository at this point in the history
  • Loading branch information
fffonion committed Oct 11, 2019
1 parent ede4f81 commit de99069
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 1 deletion.
6 changes: 6 additions & 0 deletions lib/resty/openssl/digest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ local format_error = require("resty.openssl.err").format_error

local version_num = require("resty.openssl.version").version_num

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

function _M.new(typ)
local ctx
if version_num >= 0x10100000 then
Expand All @@ -40,6 +42,10 @@ function _M.new(typ)
return setmetatable({ ctx = ctx }, mt), nil
end

function _M.istype(l)
return l.ctx and ffi.istype(md_ctx_ptr_ct, l.ctx)
end

function _M:update(...)
for _, s in ipairs({...}) do
C.EVP_DigestUpdate(self.ctx, s, #s)
Expand Down
7 changes: 7 additions & 0 deletions lib/resty/openssl/pkey.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require "resty.openssl.pem"
require "resty.openssl.objects"
local util = require "resty.openssl.util"
require "resty.openssl.x509"
local digest_lib = require "resty.openssl.digest"
local format_error = require("resty.openssl.err").format_error

local OPENSSL_11 = require("resty.openssl.version").OPENSSL_11
Expand Down Expand Up @@ -314,13 +315,19 @@ end
local uint_ptr = ffi.typeof("unsigned int[1]")

function _M:sign(digest)
if not digest_lib.istype(digest) then
return nil, "expect a digest instance at #1"
end
local buf = ffi_new('unsigned char[?]', self.key_size)
local length = uint_ptr()
local code = C.EVP_SignFinal(digest.ctx, buf, length, self.ctx)
return ffi_str(buf, length[0]), nil
end

function _M:verify(signature, digest)
if not digest_lib.istype(digest) then
return nil, "expect a digest instance at #2"
end
local code = C.EVP_VerifyFinal(digest.ctx, signature, #signature, self.ctx)
if code == 0 then
return false, nil
Expand Down
6 changes: 6 additions & 0 deletions lib/resty/openssl/x509/altname.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ require "resty.openssl.asn1"
local _M = {}
local mt = { __index = _M, __tostring = tostring }

local general_names_ptr_ct = ffi.typeof("GENERAL_NAMES*")

local GENERAL_NAME_stack_gc = stack_lib.gc_of("GENERAL_NAME")

function _M.new()
Expand All @@ -35,6 +37,10 @@ function _M.new()
return self, nil
end

function _M.istype(l)
return l.ctx and ffi.istype(general_names_ptr_ct, l.ctx)
end

local GEN_OTHERNAME = 0
local GEN_EMAIL = 1
local GEN_DNS = 2
Expand Down
21 changes: 21 additions & 0 deletions lib/resty/openssl/x509/csr.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ require "resty.openssl.ossl_typ"
require "resty.openssl.evp"
require "resty.openssl.objects"
local stack_lib = require "resty.openssl.stack"
local pkey_lib = require "resty.openssl.pkey"
local altname_lib = require "resty.openssl.x509.altname"
local x509_name_lib = require "resty.openssl.x509.name"
local util = require "resty.openssl.util"

ffi.cdef [[
Expand Down Expand Up @@ -54,6 +57,8 @@ end
local _M = {}
local mt = { __index = _M, __tostring = __tostring }

local x509_req_ptr_ct = ffi.typeof("X509_REQ*")

function _M.new()
local ctx = C.X509_REQ_new()
if ctx == il then
Expand All @@ -68,8 +73,14 @@ function _M.new()
return self, nil
end

function _M.istype(l)
return l.ctx and ffi.istype(x509_req_ptr_ct, l.ctx)
end

function _M:setSubject(name)
if not x509_name_lib.istype(name) then
return "expect a x509.name instance at #1"
end
local code = C.X509_REQ_set_subject_name(self.ctx, name.ctx)
if code ~= 1 then
return "X509_REQ_set_subject_name() failed: " .. code
Expand Down Expand Up @@ -104,12 +115,18 @@ local function xr_modifyRequestedExtension(csr, target_nid, value, crit, flags)
end

function _M:setSubjectAlt(alt)
if not altname_lib.istype(alt) then
return "expect a x509.altname instance at #1"
end
-- #define NID_subject_alt_name 85
-- #define X509V3_ADD_REPLACE 2L
return xr_modifyRequestedExtension(self.ctx, 85, alt.ctx, 0, 2)
end

function _M:setPublicKey(pkey)
if not pkey_lib.istype(pkey) then
return "expect a pkey instance at #1"
end
local code = C.X509_REQ_set_pubkey(self.ctx, pkey.ctx)
if code ~= 1 then
return "X509_REQ_set_pubkey() failed: " .. code
Expand All @@ -118,6 +135,10 @@ end

local int_ptr = ffi.typeof("int[1]")
function _M:sign(pkey)
if not pkey_lib.istype(pkey) then
return "expect a pkey instance at #1"
end

local nid = int_ptr()
local code = C.EVP_PKEY_get_default_digest_nid(pkey.ctx, nid)
if code <= 0 then -- 1: advisory 2: mandatory
Expand Down
2 changes: 2 additions & 0 deletions lib/resty/openssl/x509/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ local _M = {}
local mt = {__index = _M}

require "resty.openssl.ossl_typ"
require "resty.openssl.bio"
require "resty.openssl.pem"
local asn1_lib = require("resty.openssl.asn1")
local format_error = require("resty.openssl.err").format_error
local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10
Expand Down
5 changes: 5 additions & 0 deletions lib/resty/openssl/x509/name.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ local MBSTRING_ASC = 0x1001 -- (MBSTRING_FLAG|1)
local _M = {}
local mt = { __index = _M, __tostring = tostring }

local x509_name_ptr_ct = ffi.typeof("X509_NAME*")

function _M.new(cert)
local ctx = C.X509_NAME_new()
if ctx == nil then
Expand All @@ -39,6 +41,9 @@ function _M.new(cert)
return self, nil
end

function _M.istype(l)
return l.ctx and ffi.istype(x509_name_ptr_ct, l.ctx)
end

function _M:add(nid, txt)
local asn1 = C.OBJ_txt2obj(nid, 0)
Expand Down
28 changes: 27 additions & 1 deletion t/openssl/pkey.t
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,33 @@ true
--- no_error_log
[error]

=== TEST 9: Outputs public key
=== TEST 9: Bail on bad digest or verify parameters
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
local p, err = require("resty.openssl.pkey").new()
if err then
ngx.log(ngx.ERR, err)
return
end
local s, err = p:sign("not a cdata")
ngx.say(err)
local v, err = p:verify(s, "not a cdata")
ngx.say(err)
}
}
--- request
GET /t
--- response_body eval
"expect a digest instance at #1
expect a digest instance at #2
"
--- no_error_log
[error]

=== TEST 10: Outputs public key
--- http_config eval: $::HttpConfig
--- config
location =/t {
Expand Down
70 changes: 70 additions & 0 deletions t/openssl/x509/csr.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:

use Test::Nginx::Socket::Lua 'no_plan';
use Cwd qw(cwd);


my $pwd = cwd();

our $HttpConfig = qq{
lua_package_path "$pwd/t/openssl/x509/?.lua;$pwd/lib/?.lua;$pwd/lib/?/init.lua;$pwd/../lib/?.lua;$pwd/../lib/?/init.lua;;";
};


run_tests();

__DATA__
=== TEST 1: Generates CSR with RSA pkey correctly
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
local util = require("util")
local pkey = require("resty.openssl.pkey").new()
local der, err = util.create_csr(pkey, "dns1.com", "dns2.com", "dns3.com")
if err then
ngx.log(ngx.ERR, err)
return
end
ngx.update_time()
local fname = "ci_" .. math.floor(ngx.now() * 1000)
local f = io.open(fname, "wb")
f:write(der)
f:close()
ngx.say(io.popen("openssl req -inform der -in " .. fname .. " -noout -text", 'r'):read("*a"))
os.remove(fname)
}
}
--- request
GET /t
--- response_body_like eval
".+CN\\s*=\\s*dns1.com.+rsaEncryption.+2048 bit.+DNS:dns1.com.+DNS:dns2.com.+DNS:dns3.com"
--- no_error_log
[error]

=== TEST 2: Rejects invalid arguments
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
local csr = require("resty.openssl.x509.csr").new()
err = csr:setSubject("not a subject")
ngx.say(err)
err = csr:setSubjectAlt("not a alt")
ngx.say(err)
err = csr:setPublicKey("not a pkey")
ngx.say(err)
err = csr:sign("not a pkey")
ngx.say(err)
}
}
--- request
GET /t
--- response_body eval
"expect a x509.name instance at #1
expect a x509.altname instance at #1
expect a pkey instance at #1
expect a pkey instance at #1
"
--- no_error_log
[error]
55 changes: 55 additions & 0 deletions t/openssl/x509/util.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

local function create_csr(domain_pkey, ...)
local domains = {...}

local err

local subject = require("resty.openssl.x509.name").new()
err = subject:add("CN", domains[1])
if err then
return nil, err
end

local alt, err
if #{...} > 1 then
alt, err = require("resty.openssl.x509.altname").new()
if err then
return nil, err
end

for _, domain in pairs(domains) do
err = alt:add("DNS", domain)
if err then
return nil, err
end
end
end

local csr = require("resty.openssl.x509.csr").new()
err = csr:setSubject(subject)
if err then
return nil, err
end
if alt then
err = csr:setSubjectAlt(alt)
if err then
return nil, err
end
end

err = csr:setPublicKey(domain_pkey)
if err then
return nil, err
end

err = csr:sign(domain_pkey)
if err then
return nil, err
end

return csr:tostring("DER"), nil
end

return {
create_csr = create_csr,
}

0 comments on commit de99069

Please sign in to comment.