File: ocsp.lua

package info (click to toggle)
lua-resty-core 0.1.32-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,268 kB
  • sloc: sh: 207; perl: 143; makefile: 26
file content (160 lines) | stat: -rw-r--r-- 4,154 bytes parent folder | download | duplicates (2)
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