Skip to content

Commit

Permalink
feat(x509) add get_ocsp_url and get_crl_url
Browse files Browse the repository at this point in the history
  • Loading branch information
fffonion committed Jan 9, 2020
1 parent 46bb723 commit 6141b6f
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 6 deletions.
2 changes: 2 additions & 0 deletions lib/resty/openssl.lua
Expand Up @@ -12,6 +12,7 @@ local _M = {
digest = require("resty.openssl.digest"), digest = require("resty.openssl.digest"),
hmac = require("resty.openssl.hmac"), hmac = require("resty.openssl.hmac"),
pkey = require("resty.openssl.pkey"), pkey = require("resty.openssl.pkey"),
objects = require("resty.openssl.objects"),
rand = require("resty.openssl.rand"), rand = require("resty.openssl.rand"),
version = require("resty.openssl.version"), version = require("resty.openssl.version"),
x509 = require("resty.openssl.x509"), x509 = require("resty.openssl.x509"),
Expand Down Expand Up @@ -73,6 +74,7 @@ function _M.luaossl_compat()
_M.x509.getSubject = _M.x509.get_subject_name _M.x509.getSubject = _M.x509.get_subject_name
_M.x509.setIssuer = _M.x509.set_issuer_name _M.x509.setIssuer = _M.x509.set_issuer_name
_M.x509.getIssuer = _M.x509.get_issuer_name _M.x509.getIssuer = _M.x509.get_issuer_name
_M.x509.getOCSP = _M.x509.get_ocsp_url


_M.cipher.encrypt = function(self, key, iv, padding) _M.cipher.encrypt = function(self, key, iv, padding)
return self, _M.cipher.init(self, key, iv, true, not padding) return self, _M.cipher.init(self, key, iv, true, not padding)
Expand Down
4 changes: 4 additions & 0 deletions lib/resty/openssl/include/stack.lua
Expand Up @@ -14,6 +14,10 @@ local OPENSSL_11 = require("resty.openssl.version").OPENSSL_11


local _M = {} local _M = {}


ffi.cdef [[
typedef char *OPENSSL_STRING;
]]

if OPENSSL_11 then if OPENSSL_11 then
ffi.cdef [[ ffi.cdef [[
typedef struct stack_st OPENSSL_STACK; typedef struct stack_st OPENSSL_STACK;
Expand Down
1 change: 1 addition & 0 deletions lib/resty/openssl/include/x509/init.lua
Expand Up @@ -28,6 +28,7 @@ ffi.cdef [[
int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); int X509_EXTENSION_get_critical(const X509_EXTENSION *ex);
ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);


// needed by pkey // needed by pkey
EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
Expand Down
4 changes: 4 additions & 0 deletions lib/resty/openssl/include/x509v3.lua
Expand Up @@ -10,6 +10,10 @@ local BASIC_CONSTRAINTS = {
} }


ffi.cdef [[ ffi.cdef [[
// STACK_OF(OPENSSL_STRING)
OPENSSL_STACK *X509_get1_ocsp(X509 *x);
void X509_email_free(OPENSSL_STACK *sk);

typedef struct EDIPartyName_st EDIPARTYNAME; typedef struct EDIPartyName_st EDIPARTYNAME;


typedef struct otherName_st OTHERNAME; typedef struct otherName_st OTHERNAME;
Expand Down
20 changes: 20 additions & 0 deletions lib/resty/openssl/x509/extension.lua
Expand Up @@ -79,6 +79,26 @@ function _M.dup(ctx)
return self, nil return self, nil
end end


function _M.from_data(any, nid, crit)
if type(any) ~= "table" or type(any.ctx) ~= "cdata" then
return nil, "expect a table with ctx at #1"
elseif type(nid) ~= "number" then
return nil, "expect a table at #2"
end

local ctx = C.X509V3_EXT_i2d(nid, crit and 1 or 0, any.ctx)
if ctx == nil then
return nil, format_error("extension:from_data: X509V3_EXT_i2d")
end
ffi_gc(ctx, C.X509_EXTENSION_free)

local self = setmetatable({
ctx = ctx,
}, mt)

return self, nil
end

function _M:get_object() function _M:get_object()
-- retruns the internal pointer -- retruns the internal pointer
local asn1 = C.X509_EXTENSION_get_object(self.ctx) local asn1 = C.X509_EXTENSION_get_object(self.ctx)
Expand Down
84 changes: 80 additions & 4 deletions lib/resty/openssl/x509/init.lua
Expand Up @@ -9,6 +9,7 @@ require "resty.openssl.include.x509"
require "resty.openssl.include.x509v3" require "resty.openssl.include.x509v3"
require "resty.openssl.include.evp" require "resty.openssl.include.evp"
require "resty.openssl.include.objects" require "resty.openssl.include.objects"
local stack_macro = require("resty.openssl.include.stack")
local stack_lib = require("resty.openssl.stack") local stack_lib = require("resty.openssl.stack")
local asn1_lib = require("resty.openssl.asn1") local asn1_lib = require("resty.openssl.asn1")
local digest_lib = require("resty.openssl.digest") local digest_lib = require("resty.openssl.digest")
Expand Down Expand Up @@ -166,15 +167,89 @@ function _M:get_lifetime()
return not_before, not_after, nil return not_before, not_after, nil
end end


-- note: index is 0 based
local OPENSSL_STRING_value_at = function(ctx, i)
local ct = ffi_cast("OPENSSL_STRING", stack_macro.OPENSSL_sk_value(ctx, i))
if ct == nil then
return nil
end
return ffi_str(ct)
end

function _M:get_ocsp_url(return_all)
local st = C.X509_get1_ocsp(self.ctx)
local ret
if return_all then
ret = {}
local count = stack_macro.OPENSSL_sk_num(st)
for i=0,count do
ret[i+1] = OPENSSL_STRING_value_at(st, i)
end
else
ret = OPENSSL_STRING_value_at(st, 0)
end

C.X509_email_free(st)
return ret
end

function _M:get_ocsp_request()

end

function _M:get_crl_url(return_all)
local cdp, err = self:get_crl_distribution_points()
if err then
return nil, err
end

if cdp:count() == 0 then
return
end

if return_all then
local ret = {}
local cdp_iter = cdp:each()
while true do
local _, gn = cdp_iter()
if not gn then
break
end
local gn_iter = gn:each()
while true do
local k, v = gn_iter()
if not k then
break
elseif k == "URI" then
table.insert(ret, v)
end
end
end
return ret
else
local gn, err = cdp:index(1)
if err then
return nil, err
end
local iter = gn:each()
while true do
local k, v = iter()
if not k then
break
elseif k == "URI" then
return v
end
end
end
end

function _M:sign(pkey, digest) function _M:sign(pkey, digest)
local pkey_lib = require("resty.openssl.pkey") local pkey_lib = require("resty.openssl.pkey")
if not pkey_lib.istype(pkey) then if not pkey_lib.istype(pkey) then
return false, "expect a pkey instance at #1" return false, "expect a pkey instance at #1"
end end
if digest then if digest and not digest_lib.istype(digest) then
if not digest_lib.istype(digest) then return false, "expect a digest instance at #2"
return false, "expect a digest instance at #2"
end
end end


-- returns size of signature if success -- returns size of signature if success
Expand Down Expand Up @@ -301,6 +376,7 @@ else
error("X509_delete_ext undefined") error("X509_delete_ext undefined")
end end
end end

function _M:set_extension(extension, last_pos) function _M:set_extension(extension, last_pos)
if not extension_lib.istype(extension) then if not extension_lib.istype(extension) then
return false, "expect a x509.extension instance at #1" return false, "expect a x509.extension instance at #1"
Expand Down
67 changes: 66 additions & 1 deletion t/openssl/x509.t
Expand Up @@ -452,9 +452,74 @@ OCSP - URI:http://somedomain.com
} }
--- request --- request
GET /t GET /t
--- response_body_like eval --- response_body eval
"URI http://crl3.digicert.com/sha2-ev-server-g2.crl "URI http://crl3.digicert.com/sha2-ev-server-g2.crl
URI http://crl4.digicert.com/sha2-ev-server-g2.crl URI http://crl4.digicert.com/sha2-ev-server-g2.crl
" "
--- no_error_log --- no_error_log
[error]
=== TEST 18: Set CRL distribution points
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
-- NYI
}
}
--- request
GET /t
--- no_error_log
[error]
=== TEST 19: Get OCSP url
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
local f = io.open("t/fixtures/Github.pem"):read("*a")
local c, err = require("resty.openssl.x509").new(f)
local ocsp, err = c:get_ocsp_url()
if err then ngx.log(ngx.ERR, err) end
ngx.say(ocsp)
local ocsp, err = c:get_ocsp_url(true)
if err then ngx.log(ngx.ERR, err) end
ngx.say(require("cjson").encode(ocsp))
}
}
--- request
GET /t
--- response_body eval
'http://ocsp.digicert.com
["http:\/\/ocsp.digicert.com"]
'
--- no_error_log
[error]
=== TEST 20: Get CRL url
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
local f = io.open("t/fixtures/Github.pem"):read("*a")
local c, err = require("resty.openssl.x509").new(f)
local crl, err = c:get_crl_url()
if err then ngx.log(ngx.ERR, err) end
ngx.say(crl)
local crl, err = c:get_crl_url(true)
if err then ngx.log(ngx.ERR, err) end
ngx.say(require("cjson").encode(crl))
}
}
--- request
GET /t
--- response_body eval
'http://crl3.digicert.com/sha2-ev-server-g2.crl
["http:\/\/crl3.digicert.com\/sha2-ev-server-g2.crl","http:\/\/crl4.digicert.com\/sha2-ev-server-g2.crl"]
'
--- no_error_log
[error] [error]
2 changes: 1 addition & 1 deletion t/openssl/x509/altname.t
Expand Up @@ -55,7 +55,7 @@ __DATA__
end end
end end
ngx.say(#c) ngx.say(#c)
ngx.say(#c:all()) ngx.say(c:count())
} }
} }
--- request --- request
Expand Down
26 changes: 26 additions & 0 deletions t/openssl/x509/extension.t
Expand Up @@ -191,3 +191,29 @@ CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServe
--- no_error_log --- no_error_log
[error] [error]
=== TEST 7: Creates extension by data
--- http_config eval: $::HttpConfig
--- config
location =/t {
content_by_lua_block {
local altname = require("resty.openssl.x509.altname").new()
altname:add("DNS", "test.com")
altname:add("DNS", "test2.com")
local extension = require("resty.openssl.x509.extension")
local c, err = extension.from_data(altname, 85, false)
if err then
ngx.log(ngx.ERR, err)
return
end
ngx.say(require("cjson").encode(c:get_object()))
ngx.say(tostring(c))
}
}
--- request
GET /t
--- response_body_like eval
'{"ln":"X509v3 Subject Alternative Name","nid":85,"sn":"subjectAltName","id":"2.5.29.17"}
DNS:test.com, DNS:test2.com
'
--- no_error_log
[error]

0 comments on commit 6141b6f

Please sign in to comment.