suricata
util-lua-tls.c
Go to the documentation of this file.
1 /* Copyright (C) 2014 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 
19 /**
20  * \file
21  *
22  * \author Eric Leblond <eric@regit.org>
23  *
24  */
25 
26 #include "suricata-common.h"
27 #include "detect.h"
28 #include "pkt-var.h"
29 #include "conf.h"
30 
31 #include "threads.h"
32 #include "threadvars.h"
33 #include "tm-threads.h"
34 
35 #include "util-print.h"
36 
37 #include "util-debug.h"
38 
39 #include "output.h"
40 #include "app-layer.h"
41 #include "app-layer-parser.h"
42 #include "app-layer-ssl.h"
43 #include "util-privs.h"
44 #include "util-buffer.h"
45 #include "util-proto-name.h"
46 #include "util-logopenfile.h"
47 
48 #include "lua.h"
49 #include "lualib.h"
50 #include "lauxlib.h"
51 
52 #include "util-lua.h"
53 #include "util-lua-common.h"
54 #include "util-lua-tls.h"
55 
56 static const char tls_state_mt[] = "suricata:tls";
57 
58 struct LuaTls {
59  const SSLState *state; // state
60 };
61 
62 static int LuaTlsFlowStateGet(lua_State *luastate)
63 {
64  if (!LuaStateNeedProto(luastate, ALPROTO_TLS)) {
65  return LuaCallbackError(luastate, "error: protocol not tls");
66  }
67  Flow *f = LuaStateGetFlow(luastate);
68  if (f == NULL) {
69  LUA_ERROR("failed to get flow");
70  }
71 
72  struct LuaTls *s = (struct LuaTls *)lua_newuserdata(luastate, sizeof(*s));
73  if (s == NULL) {
74  LUA_ERROR("failed to allocate userdata");
75  }
76 
77  void *state = FlowGetAppState(f);
78  if (state == NULL)
79  return LuaCallbackError(luastate, "error: no app layer state");
80  s->state = (const SSLState *)state;
81  luaL_getmetatable(luastate, tls_state_mt);
82  lua_setmetatable(luastate, -2);
83  return 1;
84 }
85 
86 static int GetCertNotBefore(lua_State *luastate, bool client, const SSLState *ssl_state)
87 {
88  const SSLStateConnp *connp;
89 
90  if (client) {
91  connp = &ssl_state->client_connp;
92  } else {
93  connp = &ssl_state->server_connp;
94  }
95 
96  if (connp->cert0_not_before == 0)
97  return LuaCallbackError(luastate, "error: no certificate NotBefore");
98 
99  return LuaPushInteger(luastate, connp->cert0_not_before);
100 }
101 
102 static int LuaTlsGetServerCertNotBefore(lua_State *luastate)
103 {
104  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
105  if (s->state == NULL) {
106  LUA_ERROR("failed to get flow");
107  }
108 
109  return GetCertNotBefore(luastate, false, s->state);
110 }
111 
112 static int LuaTlsGetClientCertNotBefore(lua_State *luastate)
113 {
114  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
115  if (s->state == NULL) {
116  LUA_ERROR("failed to get flow");
117  }
118 
119  return GetCertNotBefore(luastate, true, s->state);
120 }
121 
122 static int GetCertNotAfter(lua_State *luastate, bool client, const SSLState *ssl_state)
123 {
124  const SSLStateConnp *connp;
125 
126  if (client) {
127  connp = &ssl_state->client_connp;
128  } else {
129  connp = &ssl_state->server_connp;
130  }
131 
132  if (connp->cert0_not_after == 0)
133  return LuaCallbackError(luastate, "error: no certificate NotAfter");
134 
135  return LuaPushInteger(luastate, connp->cert0_not_after);
136 }
137 
138 static int LuaTlsGetServerCertNotAfter(lua_State *luastate)
139 {
140  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
141  if (s->state == NULL) {
142  LUA_ERROR("failed to get state");
143  }
144 
145  return GetCertNotAfter(luastate, false, s->state);
146 }
147 static int LuaTlsGetClientCertNotAfter(lua_State *luastate)
148 {
149  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
150  if (s->state == NULL) {
151  LUA_ERROR("failed to get state");
152  }
153 
154  return GetCertNotAfter(luastate, true, s->state);
155 }
156 
157 static int GetCertInfo(lua_State *luastate, bool client, const SSLState *ssl_state)
158 {
159  const SSLStateConnp *connp;
160 
161  if (client) {
162  connp = &ssl_state->client_connp;
163  } else {
164  connp = &ssl_state->server_connp;
165  }
166 
167  if (connp->cert0_subject == NULL)
168  return LuaCallbackError(luastate, "error: no cert");
169 
170  /* tls.version */
171  char ssl_version[SSL_VERSION_MAX_STRLEN];
172  SSLVersionToString(ssl_state->server_connp.version, ssl_version);
173 
174  int r = LuaPushStringBuffer(luastate, (uint8_t *)ssl_version, strlen(ssl_version));
175  r += LuaPushStringBuffer(luastate, connp->cert0_subject, connp->cert0_subject_len);
176  r += LuaPushStringBuffer(luastate, connp->cert0_issuerdn, connp->cert0_issuerdn_len);
177  r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_fingerprint, strlen(connp->cert0_fingerprint));
178  return r;
179 }
180 
181 static int LuaTlsGetServerCertInfo(lua_State *luastate)
182 {
183  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
184  if (s->state == NULL) {
185  LUA_ERROR("failed to get state");
186  }
187 
188  return GetCertInfo(luastate, false, s->state);
189 }
190 
191 static int LuaTlsGetClientCertInfo(lua_State *luastate)
192 {
193  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
194  if (s->state == NULL) {
195  LUA_ERROR("failed to get state");
196  }
197 
198  return GetCertInfo(luastate, true, s->state);
199 }
200 
201 static int GetSNI(lua_State *luastate, const SSLState *ssl_state)
202 {
203  if (ssl_state->client_connp.sni == NULL)
204  return LuaCallbackError(luastate, "error: no server name indication");
205 
206  return LuaPushStringBuffer(
207  luastate, ssl_state->client_connp.sni, ssl_state->client_connp.sni_len);
208 }
209 
210 static int LuaTlsGetSNI(lua_State *luastate)
211 {
212  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
213  if (s->state == NULL) {
214  LUA_ERROR("failed to get state");
215  }
216 
217  if (!(LuaStateNeedProto(luastate, ALPROTO_TLS)))
218  return LuaCallbackError(luastate, "error: protocol not tls");
219 
220  return GetSNI(luastate, s->state);
221 }
222 
223 static int GetCertChain(lua_State *luastate, bool client)
224 {
225  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
226  if (s->state == NULL) {
227  LUA_ERROR("failed to get state");
228  }
229 
230  if (!(LuaStateNeedProto(luastate, ALPROTO_TLS)))
231  return LuaCallbackError(luastate, "error: protocol not tls");
232 
233  const SSLStateConnp *connp;
234 
235  if (client) {
236  connp = &s->state->client_connp;
237  } else {
238  connp = &s->state->server_connp;
239  }
240 
241  uint32_t u = 0;
242  lua_newtable(luastate);
243  SSLCertsChain *cert = NULL;
244 
245  TAILQ_FOREACH(cert, &connp->certs, next)
246  {
247  lua_pushinteger(luastate, u++);
248 
249  lua_newtable(luastate);
250 
251  lua_pushstring(luastate, "length");
252  lua_pushinteger(luastate, cert->cert_len);
253  lua_settable(luastate, -3);
254 
255  lua_pushstring(luastate, "data");
256  LuaPushStringBuffer(luastate, cert->cert_data, cert->cert_len);
257 
258  lua_settable(luastate, -3);
259  lua_settable(luastate, -3);
260  }
261 
262  return 1;
263 }
264 
265 static int LuaTlsGetServerCertChain(lua_State *luastate)
266 {
267  return GetCertChain(luastate, false);
268 }
269 
270 static int LuaTlsGetClientCertChain(lua_State *luastate)
271 {
272  return GetCertChain(luastate, true);
273 }
274 
275 static int GetCertSerial(lua_State *luastate, bool client)
276 {
277  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
278  if (s->state == NULL) {
279  LUA_ERROR("failed to get flow");
280  }
281 
282  const SSLStateConnp *connp;
283 
284  if (client) {
285  connp = &s->state->client_connp;
286  } else {
287  connp = &s->state->server_connp;
288  }
289  if (connp->cert0_serial == NULL)
290  return LuaCallbackError(luastate, "error: no certificate serial");
291 
292  return LuaPushStringBuffer(luastate, connp->cert0_serial, connp->cert0_serial_len);
293 }
294 
295 static int LuaTlsGetServerCertSerial(lua_State *luastate)
296 {
297  return GetCertSerial(luastate, false);
298 }
299 
300 static int LuaTlsGetClientCertSerial(lua_State *luastate)
301 {
302  return GetCertSerial(luastate, true);
303 }
304 
305 static int GetAgreedVersion(lua_State *luastate, bool client)
306 {
307  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
308  if (s->state == NULL) {
309  LUA_ERROR("failed to get state");
310  }
311 
312  uint16_t version;
313  if (client) {
315  } else {
317  }
318 
319  char ssl_version[SSL_VERSION_MAX_STRLEN];
320  SSLVersionToString(version, ssl_version);
321 
322  lua_pushstring(luastate, (const char *)&ssl_version);
323  return 1;
324 }
325 
326 static int LuaTlsGetServerVersion(lua_State *luastate)
327 {
328  return GetAgreedVersion(luastate, false);
329 }
330 
331 static int LuaTlsGetClientVersion(lua_State *luastate)
332 {
333  return GetAgreedVersion(luastate, true);
334 }
335 
336 static const struct luaL_Reg tlslib_meta[] = {
337  // clang-format off
338  { "get_server_cert_not_before", LuaTlsGetServerCertNotBefore },
339  { "get_client_cert_not_before", LuaTlsGetClientCertNotBefore },
340  { "get_server_cert_not_after", LuaTlsGetServerCertNotAfter },
341  { "get_client_cert_not_after", LuaTlsGetClientCertNotAfter },
342  { "get_server_version", LuaTlsGetServerVersion },
343  { "get_client_version", LuaTlsGetClientVersion },
344  { "get_server_serial", LuaTlsGetServerCertSerial },
345  { "get_client_serial", LuaTlsGetClientCertSerial },
346  { "get_server_cert_info", LuaTlsGetServerCertInfo },
347  { "get_client_cert_info", LuaTlsGetClientCertInfo },
348  { "get_client_sni", LuaTlsGetSNI },
349  { "get_client_cert_chain", LuaTlsGetClientCertChain },
350  { "get_server_cert_chain", LuaTlsGetServerCertChain },
351  { NULL, NULL, }
352  // clang-format off
353 };
354 
355 static const struct luaL_Reg tlslib[] = {
356  // clang-format off
357  { "get_tx", LuaTlsFlowStateGet },
358  { NULL, NULL, },
359  // clang-format on
360 };
361 
363 {
364  luaL_newmetatable(L, tls_state_mt);
365  lua_pushvalue(L, -1);
366  lua_setfield(L, -2, "__index");
367  luaL_setfuncs(L, tlslib_meta, 0);
368 
369  luaL_newlib(L, tlslib);
370  return 1;
371 }
tm-threads.h
SSLState_
SSLv[2.0|3.[0|1|2|3]] state structure.
Definition: app-layer-ssl.h:263
LUA_ERROR
#define LUA_ERROR(msg)
Definition: util-lua-common.h:45
SSLCertsChain_::cert_len
uint32_t cert_len
Definition: app-layer-ssl.h:168
util-lua-common.h
SSLState_::client_connp
SSLStateConnp client_connp
Definition: app-layer-ssl.h:284
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:39
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
SSLState_::server_connp
SSLStateConnp server_connp
Definition: app-layer-ssl.h:285
SSLStateConnp_::cert0_not_before
int64_t cert0_not_before
Definition: app-layer-ssl.h:225
util-lua.h
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:39
SSLStateConnp_
Definition: app-layer-ssl.h:177
threads.h
Flow_
Flow data structure.
Definition: flow.h:359
LuaTls::state
const SSLState * state
Definition: util-lua-tls.c:59
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
util-privs.h
SSLStateConnp_::cert0_not_after
int64_t cert0_not_after
Definition: app-layer-ssl.h:226
lua_State
struct lua_State lua_State
Definition: suricata-common.h:527
util-debug.h
SSLCertsChain_
Definition: app-layer-ssl.h:166
util-print.h
SSLStateConnp_::cert0_serial_len
uint32_t cert0_serial_len
Definition: app-layer-ssl.h:202
detect.h
pkt-var.h
SSLStateConnp_::cert0_serial
uint8_t * cert0_serial
Definition: app-layer-ssl.h:201
app-layer-parser.h
conf.h
SSLStateConnp_::cert0_issuerdn
uint8_t * cert0_issuerdn
Definition: app-layer-ssl.h:199
util-proto-name.h
SSLStateConnp_::sni
uint8_t * sni
Definition: app-layer-ssl.h:232
SSLCertsChain_::cert_data
uint8_t * cert_data
Definition: app-layer-ssl.h:167
SCLuaLoadTlsLib
int SCLuaLoadTlsLib(lua_State *L)
Definition: util-lua-tls.c:362
SSLStateConnp_::cert0_subject_len
uint32_t cert0_subject_len
Definition: app-layer-ssl.h:198
suricata-common.h
version
uint8_t version
Definition: decode-gre.h:1
threadvars.h
util-logopenfile.h
util-buffer.h
LuaStateGetFlow
Flow * LuaStateGetFlow(lua_State *luastate)
get flow pointer from lua state
Definition: util-lua.c:159
util-lua-tls.h
SSLStateConnp_::cert0_issuerdn_len
uint32_t cert0_issuerdn_len
Definition: app-layer-ssl.h:200
SSLStateConnp_::cert0_fingerprint
char * cert0_fingerprint
Definition: app-layer-ssl.h:227
SSLStateConnp_::sni_len
uint16_t sni_len
Definition: app-layer-ssl.h:233
LuaTls
Definition: util-lua-tls.c:58
LuaStateNeedProto
int LuaStateNeedProto(lua_State *luastate, AppProto alproto)
Definition: util-lua-common.c:102
app-layer-ssl.h
output.h
LuaPushInteger
int LuaPushInteger(lua_State *luastate, lua_Integer n)
Definition: util-lua.c:323
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:317
app-layer.h
f
Flow f
Definition: fuzz_dataset.c:32
SSLStateConnp_::cert0_subject
uint8_t * cert0_subject
Definition: app-layer-ssl.h:197
SSLStateConnp_::version
uint16_t version
Definition: app-layer-ssl.h:186