Skip to content

Commit de99069

Browse files
committed
fix(*) test cdata type before passing in ffi
1 parent ede4f81 commit de99069

File tree

9 files changed

+199
-1
lines changed

9 files changed

+199
-1
lines changed

lib/resty/openssl/digest.lua

+6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ local format_error = require("resty.openssl.err").format_error
1414

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

17+
local md_ctx_ptr_ct = ffi.typeof('EVP_MD_CTX*')
18+
1719
function _M.new(typ)
1820
local ctx
1921
if version_num >= 0x10100000 then
@@ -40,6 +42,10 @@ function _M.new(typ)
4042
return setmetatable({ ctx = ctx }, mt), nil
4143
end
4244

45+
function _M.istype(l)
46+
return l.ctx and ffi.istype(md_ctx_ptr_ct, l.ctx)
47+
end
48+
4349
function _M:update(...)
4450
for _, s in ipairs({...}) do
4551
C.EVP_DigestUpdate(self.ctx, s, #s)

lib/resty/openssl/pkey.lua

+7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require "resty.openssl.pem"
1616
require "resty.openssl.objects"
1717
local util = require "resty.openssl.util"
1818
require "resty.openssl.x509"
19+
local digest_lib = require "resty.openssl.digest"
1920
local format_error = require("resty.openssl.err").format_error
2021

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

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

323327
function _M:verify(signature, digest)
328+
if not digest_lib.istype(digest) then
329+
return nil, "expect a digest instance at #2"
330+
end
324331
local code = C.EVP_VerifyFinal(digest.ctx, signature, #signature, self.ctx)
325332
if code == 0 then
326333
return false, nil

lib/resty/openssl/x509/altname.lua

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ require "resty.openssl.asn1"
1717
local _M = {}
1818
local mt = { __index = _M, __tostring = tostring }
1919

20+
local general_names_ptr_ct = ffi.typeof("GENERAL_NAMES*")
21+
2022
local GENERAL_NAME_stack_gc = stack_lib.gc_of("GENERAL_NAME")
2123

2224
function _M.new()
@@ -35,6 +37,10 @@ function _M.new()
3537
return self, nil
3638
end
3739

40+
function _M.istype(l)
41+
return l.ctx and ffi.istype(general_names_ptr_ct, l.ctx)
42+
end
43+
3844
local GEN_OTHERNAME = 0
3945
local GEN_EMAIL = 1
4046
local GEN_DNS = 2

lib/resty/openssl/x509/csr.lua

+21
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ require "resty.openssl.ossl_typ"
1111
require "resty.openssl.evp"
1212
require "resty.openssl.objects"
1313
local stack_lib = require "resty.openssl.stack"
14+
local pkey_lib = require "resty.openssl.pkey"
15+
local altname_lib = require "resty.openssl.x509.altname"
16+
local x509_name_lib = require "resty.openssl.x509.name"
1417
local util = require "resty.openssl.util"
1518

1619
ffi.cdef [[
@@ -54,6 +57,8 @@ end
5457
local _M = {}
5558
local mt = { __index = _M, __tostring = __tostring }
5659

60+
local x509_req_ptr_ct = ffi.typeof("X509_REQ*")
61+
5762
function _M.new()
5863
local ctx = C.X509_REQ_new()
5964
if ctx == il then
@@ -68,8 +73,14 @@ function _M.new()
6873
return self, nil
6974
end
7075

76+
function _M.istype(l)
77+
return l.ctx and ffi.istype(x509_req_ptr_ct, l.ctx)
78+
end
7179

7280
function _M:setSubject(name)
81+
if not x509_name_lib.istype(name) then
82+
return "expect a x509.name instance at #1"
83+
end
7384
local code = C.X509_REQ_set_subject_name(self.ctx, name.ctx)
7485
if code ~= 1 then
7586
return "X509_REQ_set_subject_name() failed: " .. code
@@ -104,12 +115,18 @@ local function xr_modifyRequestedExtension(csr, target_nid, value, crit, flags)
104115
end
105116

106117
function _M:setSubjectAlt(alt)
118+
if not altname_lib.istype(alt) then
119+
return "expect a x509.altname instance at #1"
120+
end
107121
-- #define NID_subject_alt_name 85
108122
-- #define X509V3_ADD_REPLACE 2L
109123
return xr_modifyRequestedExtension(self.ctx, 85, alt.ctx, 0, 2)
110124
end
111125

112126
function _M:setPublicKey(pkey)
127+
if not pkey_lib.istype(pkey) then
128+
return "expect a pkey instance at #1"
129+
end
113130
local code = C.X509_REQ_set_pubkey(self.ctx, pkey.ctx)
114131
if code ~= 1 then
115132
return "X509_REQ_set_pubkey() failed: " .. code
@@ -118,6 +135,10 @@ end
118135

119136
local int_ptr = ffi.typeof("int[1]")
120137
function _M:sign(pkey)
138+
if not pkey_lib.istype(pkey) then
139+
return "expect a pkey instance at #1"
140+
end
141+
121142
local nid = int_ptr()
122143
local code = C.EVP_PKEY_get_default_digest_nid(pkey.ctx, nid)
123144
if code <= 0 then -- 1: advisory 2: mandatory

lib/resty/openssl/x509/init.lua

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ local _M = {}
1111
local mt = {__index = _M}
1212

1313
require "resty.openssl.ossl_typ"
14+
require "resty.openssl.bio"
15+
require "resty.openssl.pem"
1416
local asn1_lib = require("resty.openssl.asn1")
1517
local format_error = require("resty.openssl.err").format_error
1618
local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10

lib/resty/openssl/x509/name.lua

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ local MBSTRING_ASC = 0x1001 -- (MBSTRING_FLAG|1)
2525
local _M = {}
2626
local mt = { __index = _M, __tostring = tostring }
2727

28+
local x509_name_ptr_ct = ffi.typeof("X509_NAME*")
29+
2830
function _M.new(cert)
2931
local ctx = C.X509_NAME_new()
3032
if ctx == nil then
@@ -39,6 +41,9 @@ function _M.new(cert)
3941
return self, nil
4042
end
4143

44+
function _M.istype(l)
45+
return l.ctx and ffi.istype(x509_name_ptr_ct, l.ctx)
46+
end
4247

4348
function _M:add(nid, txt)
4449
local asn1 = C.OBJ_txt2obj(nid, 0)

t/openssl/pkey.t

+27-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,33 @@ true
220220
--- no_error_log
221221
[error]
222222

223-
=== TEST 9: Outputs public key
223+
=== TEST 9: Bail on bad digest or verify parameters
224+
--- http_config eval: $::HttpConfig
225+
--- config
226+
location =/t {
227+
content_by_lua_block {
228+
local p, err = require("resty.openssl.pkey").new()
229+
if err then
230+
ngx.log(ngx.ERR, err)
231+
return
232+
end
233+
234+
local s, err = p:sign("not a cdata")
235+
ngx.say(err)
236+
local v, err = p:verify(s, "not a cdata")
237+
ngx.say(err)
238+
}
239+
}
240+
--- request
241+
GET /t
242+
--- response_body eval
243+
"expect a digest instance at #1
244+
expect a digest instance at #2
245+
"
246+
--- no_error_log
247+
[error]
248+
249+
=== TEST 10: Outputs public key
224250
--- http_config eval: $::HttpConfig
225251
--- config
226252
location =/t {

t/openssl/x509/csr.t

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# vim:set ft= ts=4 sw=4 et fdm=marker:
2+
3+
use Test::Nginx::Socket::Lua 'no_plan';
4+
use Cwd qw(cwd);
5+
6+
7+
my $pwd = cwd();
8+
9+
our $HttpConfig = qq{
10+
lua_package_path "$pwd/t/openssl/x509/?.lua;$pwd/lib/?.lua;$pwd/lib/?/init.lua;$pwd/../lib/?.lua;$pwd/../lib/?/init.lua;;";
11+
};
12+
13+
14+
run_tests();
15+
16+
__DATA__
17+
=== TEST 1: Generates CSR with RSA pkey correctly
18+
--- http_config eval: $::HttpConfig
19+
--- config
20+
location =/t {
21+
content_by_lua_block {
22+
local util = require("util")
23+
local pkey = require("resty.openssl.pkey").new()
24+
local der, err = util.create_csr(pkey, "dns1.com", "dns2.com", "dns3.com")
25+
if err then
26+
ngx.log(ngx.ERR, err)
27+
return
28+
end
29+
ngx.update_time()
30+
local fname = "ci_" .. math.floor(ngx.now() * 1000)
31+
local f = io.open(fname, "wb")
32+
f:write(der)
33+
f:close()
34+
ngx.say(io.popen("openssl req -inform der -in " .. fname .. " -noout -text", 'r'):read("*a"))
35+
os.remove(fname)
36+
}
37+
}
38+
--- request
39+
GET /t
40+
--- response_body_like eval
41+
".+CN\\s*=\\s*dns1.com.+rsaEncryption.+2048 bit.+DNS:dns1.com.+DNS:dns2.com.+DNS:dns3.com"
42+
--- no_error_log
43+
[error]
44+
45+
=== TEST 2: Rejects invalid arguments
46+
--- http_config eval: $::HttpConfig
47+
--- config
48+
location =/t {
49+
content_by_lua_block {
50+
local csr = require("resty.openssl.x509.csr").new()
51+
err = csr:setSubject("not a subject")
52+
ngx.say(err)
53+
err = csr:setSubjectAlt("not a alt")
54+
ngx.say(err)
55+
err = csr:setPublicKey("not a pkey")
56+
ngx.say(err)
57+
err = csr:sign("not a pkey")
58+
ngx.say(err)
59+
}
60+
}
61+
--- request
62+
GET /t
63+
--- response_body eval
64+
"expect a x509.name instance at #1
65+
expect a x509.altname instance at #1
66+
expect a pkey instance at #1
67+
expect a pkey instance at #1
68+
"
69+
--- no_error_log
70+
[error]

t/openssl/x509/util.lua

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
local function create_csr(domain_pkey, ...)
3+
local domains = {...}
4+
5+
local err
6+
7+
local subject = require("resty.openssl.x509.name").new()
8+
err = subject:add("CN", domains[1])
9+
if err then
10+
return nil, err
11+
end
12+
13+
local alt, err
14+
if #{...} > 1 then
15+
alt, err = require("resty.openssl.x509.altname").new()
16+
if err then
17+
return nil, err
18+
end
19+
20+
for _, domain in pairs(domains) do
21+
err = alt:add("DNS", domain)
22+
if err then
23+
return nil, err
24+
end
25+
end
26+
end
27+
28+
local csr = require("resty.openssl.x509.csr").new()
29+
err = csr:setSubject(subject)
30+
if err then
31+
return nil, err
32+
end
33+
if alt then
34+
err = csr:setSubjectAlt(alt)
35+
if err then
36+
return nil, err
37+
end
38+
end
39+
40+
err = csr:setPublicKey(domain_pkey)
41+
if err then
42+
return nil, err
43+
end
44+
45+
err = csr:sign(domain_pkey)
46+
if err then
47+
return nil, err
48+
end
49+
50+
return csr:tostring("DER"), nil
51+
end
52+
53+
return {
54+
create_csr = create_csr,
55+
}

0 commit comments

Comments
 (0)