1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
-- Copyright (C) Yichun Zhang (agentzh)
local base = require "resty.core.base"
base.allows_subsystem('http')
local ffi = require "ffi"
local C = ffi.C
local ffi_new = ffi.new
local ffi_str = ffi.string
local get_request = base.get_request
local error = error
local tonumber = tonumber
local errmsg = base.get_errmsg_ptr()
local get_string_buf = base.get_string_buf
local get_string_buf_size = base.get_string_buf_size
local get_size_ptr = base.get_size_ptr
local FFI_DECLINED = base.FFI_DECLINED
local FFI_OK = base.FFI_OK
local FFI_BUSY = base.FFI_BUSY
ffi.cdef[[
int ngx_http_lua_ffi_ssl_get_ocsp_responder_from_der_chain(
const char *chain_data, size_t chain_len, char *out, size_t *out_size,
char **err);
int ngx_http_lua_ffi_ssl_create_ocsp_request(const char *chain_data,
size_t chain_len, unsigned char *out, size_t *out_size, char **err);
int ngx_http_lua_ffi_ssl_validate_ocsp_response(const unsigned char *resp,
size_t resp_len, const char *chain_data, size_t chain_len,
unsigned char *errbuf, size_t *errbuf_size, long *valid);
int ngx_http_lua_ffi_ssl_set_ocsp_status_resp(ngx_http_request_t *r,
const unsigned char *resp, size_t resp_len, char **err);
]]
local _M = { version = base.version }
function _M.get_ocsp_responder_from_der_chain(certs, maxlen)
local buf_size = maxlen
if not buf_size then
buf_size = get_string_buf_size()
end
local buf = get_string_buf(buf_size)
local sizep = get_size_ptr()
sizep[0] = buf_size
local rc = C.ngx_http_lua_ffi_ssl_get_ocsp_responder_from_der_chain(certs,
#certs, buf, sizep, errmsg)
if rc == FFI_DECLINED then
return nil
end
if rc == FFI_OK then
return ffi_str(buf, sizep[0])
end
if rc == FFI_BUSY then
return ffi_str(buf, sizep[0]), "truncated"
end
return nil, ffi_str(errmsg[0])
end
function _M.create_ocsp_request(certs, maxlen)
local buf_size = maxlen
if not buf_size then
buf_size = get_string_buf_size()
end
local buf = get_string_buf(buf_size)
local sizep = get_size_ptr()
sizep[0] = buf_size
local rc = C.ngx_http_lua_ffi_ssl_create_ocsp_request(certs,
#certs, buf, sizep,
errmsg)
if rc == FFI_OK then
return ffi_str(buf, sizep[0])
end
if rc == FFI_BUSY then
return nil, ffi_str(errmsg[0]) .. ": " .. tonumber(sizep[0])
.. " > " .. buf_size
end
return nil, ffi_str(errmsg[0])
end
local next_update_p = ffi_new("long[1]")
function _M.validate_ocsp_response(resp, chain, max_errmsg_len)
local errbuf_size = max_errmsg_len
if not errbuf_size then
errbuf_size = get_string_buf_size()
end
local errbuf = get_string_buf(errbuf_size)
local sizep = get_size_ptr()
sizep[0] = errbuf_size
next_update_p[0] = 0
local rc = C.ngx_http_lua_ffi_ssl_validate_ocsp_response(resp, #resp,
chain, #chain,
errbuf, sizep,
next_update_p)
if rc == FFI_OK then
local next_update = tonumber(next_update_p[0])
if next_update == 0 then
next_update = nil
end
return true, next_update
end
-- rc == FFI_ERROR
return nil, ffi_str(errbuf, sizep[0])
end
function _M.set_ocsp_status_resp(ocsp_resp)
local r = get_request()
if not r then
error("no request found")
end
local rc = C.ngx_http_lua_ffi_ssl_set_ocsp_status_resp(r, ocsp_resp,
#ocsp_resp,
errmsg)
if rc == FFI_DECLINED then
-- no client status req
return true, "no status req"
end
if rc == FFI_OK then
return true
end
-- rc == FFI_ERROR
return nil, ffi_str(errmsg[0])
end
return _M
|