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  SCLuaTxRef ref; /* (flow, tx id); the state is resolved on demand */
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 = SCLuaNewUserData(luastate, SCLUA_TUD_TLS_STATE, 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  SCLuaTxRefInit(luastate, &s->ref, LuaStateGetTxId(luastate));
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 = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
105  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
106  const SSLState *ssl = (const SSLState *)txptr;
107 
108  return GetCertNotBefore(luastate, false, ssl);
109 }
110 
111 static int LuaTlsGetClientCertNotBefore(lua_State *luastate)
112 {
113  struct LuaTls *s = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
114  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
115  const SSLState *ssl = (const SSLState *)txptr;
116 
117  return GetCertNotBefore(luastate, true, ssl);
118 }
119 
120 static int GetCertNotAfter(lua_State *luastate, bool client, const SSLState *ssl_state)
121 {
122  const SSLStateConnp *connp;
123 
124  if (client) {
125  connp = &ssl_state->client_connp;
126  } else {
127  connp = &ssl_state->server_connp;
128  }
129 
130  if (connp->cert0_not_after == 0)
131  return LuaCallbackError(luastate, "error: no certificate NotAfter");
132 
133  return LuaPushInteger(luastate, connp->cert0_not_after);
134 }
135 
136 static int LuaTlsGetServerCertNotAfter(lua_State *luastate)
137 {
138  struct LuaTls *s = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
139  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
140  const SSLState *ssl = (const SSLState *)txptr;
141 
142  return GetCertNotAfter(luastate, false, ssl);
143 }
144 static int LuaTlsGetClientCertNotAfter(lua_State *luastate)
145 {
146  struct LuaTls *s = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
147  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
148  const SSLState *ssl = (const SSLState *)txptr;
149 
150  return GetCertNotAfter(luastate, true, ssl);
151 }
152 
153 static int GetCertInfo(lua_State *luastate, bool client, const SSLState *ssl_state)
154 {
155  const SSLStateConnp *connp;
156 
157  if (client) {
158  connp = &ssl_state->client_connp;
159  } else {
160  connp = &ssl_state->server_connp;
161  }
162 
163  if (connp->cert0_subject == NULL)
164  return LuaCallbackError(luastate, "error: no cert");
165 
166  /* the selected direction's version: the client hello version can
167  * differ from the server's. "Unknown" fallback: on a false return
168  * the buffer is left untouched */
169  char ssl_version[SSL_VERSION_MAX_STRLEN] = "Unknown";
170  SSLVersionToString(connp->version, ssl_version);
171 
172  int r = LuaPushStringBuffer(luastate, (uint8_t *)ssl_version, strlen(ssl_version));
173  r += LuaPushStringBuffer(luastate, connp->cert0_subject, connp->cert0_subject_len);
174  /* issuerdn/fingerprint are separate allocations that can be NULL while
175  * subject is set (alloc-failure paths); push an empty string to keep
176  * the 4-value return shape */
177  if (connp->cert0_issuerdn != NULL) {
178  r += LuaPushStringBuffer(luastate, connp->cert0_issuerdn, connp->cert0_issuerdn_len);
179  } else {
180  r += LuaPushStringBuffer(luastate, NULL, 0);
181  }
182  if (connp->cert0_fingerprint != NULL) {
183  r += LuaPushStringBuffer(
184  luastate, (uint8_t *)connp->cert0_fingerprint, strlen(connp->cert0_fingerprint));
185  } else {
186  r += LuaPushStringBuffer(luastate, NULL, 0);
187  }
188  return r;
189 }
190 
191 static int LuaTlsGetServerCertInfo(lua_State *luastate)
192 {
193  struct LuaTls *s = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
194  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
195  const SSLState *ssl = (const SSLState *)txptr;
196 
197  return GetCertInfo(luastate, false, ssl);
198 }
199 
200 static int LuaTlsGetClientCertInfo(lua_State *luastate)
201 {
202  struct LuaTls *s = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
203  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
204  const SSLState *ssl = (const SSLState *)txptr;
205 
206  return GetCertInfo(luastate, true, ssl);
207 }
208 
209 static int GetSNI(lua_State *luastate, const SSLState *ssl_state)
210 {
211  if (ssl_state->client_connp.sni == NULL)
212  return LuaCallbackError(luastate, "error: no server name indication");
213 
214  return LuaPushStringBuffer(
215  luastate, ssl_state->client_connp.sni, ssl_state->client_connp.sni_len);
216 }
217 
218 static int LuaTlsGetSNI(lua_State *luastate)
219 {
220  struct LuaTls *s = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
221  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
222  const SSLState *ssl = (const SSLState *)txptr;
223 
224  if (!(LuaStateNeedProto(luastate, ALPROTO_TLS)))
225  return LuaCallbackError(luastate, "error: protocol not tls");
226 
227  return GetSNI(luastate, ssl);
228 }
229 
230 static int GetCertChain(lua_State *luastate, bool client)
231 {
232  struct LuaTls *s = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
233  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
234  const SSLState *ssl = (const SSLState *)txptr;
235 
236  if (!(LuaStateNeedProto(luastate, ALPROTO_TLS)))
237  return LuaCallbackError(luastate, "error: protocol not tls");
238 
239  const SSLStateConnp *connp;
240 
241  if (client) {
242  connp = &ssl->client_connp;
243  } else {
244  connp = &ssl->server_connp;
245  }
246 
247  uint32_t u = 0;
248  lua_newtable(luastate);
249  SSLCertsChain *cert = NULL;
250 
251  TAILQ_FOREACH(cert, &connp->certs, next)
252  {
253  lua_pushinteger(luastate, u++);
254 
255  lua_newtable(luastate);
256 
257  lua_pushstring(luastate, "length");
258  lua_pushinteger(luastate, cert->cert_len);
259  lua_settable(luastate, -3);
260 
261  lua_pushstring(luastate, "data");
262  LuaPushStringBuffer(luastate, cert->cert_data, cert->cert_len);
263 
264  lua_settable(luastate, -3);
265  lua_settable(luastate, -3);
266  }
267 
268  return 1;
269 }
270 
271 static int LuaTlsGetServerCertChain(lua_State *luastate)
272 {
273  return GetCertChain(luastate, false);
274 }
275 
276 static int LuaTlsGetClientCertChain(lua_State *luastate)
277 {
278  return GetCertChain(luastate, true);
279 }
280 
281 static int GetCertSerial(lua_State *luastate, bool client)
282 {
283  struct LuaTls *s = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
284  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
285  const SSLState *ssl = (const SSLState *)txptr;
286 
287  const SSLStateConnp *connp;
288 
289  if (client) {
290  connp = &ssl->client_connp;
291  } else {
292  connp = &ssl->server_connp;
293  }
294  if (connp->cert0_serial == NULL)
295  return LuaCallbackError(luastate, "error: no certificate serial");
296 
297  return LuaPushStringBuffer(luastate, connp->cert0_serial, connp->cert0_serial_len);
298 }
299 
300 static int LuaTlsGetServerCertSerial(lua_State *luastate)
301 {
302  return GetCertSerial(luastate, false);
303 }
304 
305 static int LuaTlsGetClientCertSerial(lua_State *luastate)
306 {
307  return GetCertSerial(luastate, true);
308 }
309 
310 static int GetAgreedVersion(lua_State *luastate, bool client)
311 {
312  struct LuaTls *s = SCLuaCheckUserData(luastate, 1, tls_state_mt, SCLUA_TUD_TLS_STATE);
313  SCLUA_RESOLVE_TX(luastate, &s->ref, txptr);
314  const SSLState *ssl = (const SSLState *)txptr;
315 
316  uint16_t version;
317  if (client) {
319  } else {
321  }
322 
323  char ssl_version[SSL_VERSION_MAX_STRLEN] = "Unknown";
324  SSLVersionToString(version, ssl_version);
325 
326  lua_pushstring(luastate, (const char *)&ssl_version);
327  return 1;
328 }
329 
330 static int LuaTlsGetServerVersion(lua_State *luastate)
331 {
332  return GetAgreedVersion(luastate, false);
333 }
334 
335 static int LuaTlsGetClientVersion(lua_State *luastate)
336 {
337  return GetAgreedVersion(luastate, true);
338 }
339 
340 static const struct luaL_Reg tlslib_meta[] = {
341  // clang-format off
342  { "get_server_cert_not_before", LuaTlsGetServerCertNotBefore },
343  { "get_client_cert_not_before", LuaTlsGetClientCertNotBefore },
344  { "get_server_cert_not_after", LuaTlsGetServerCertNotAfter },
345  { "get_client_cert_not_after", LuaTlsGetClientCertNotAfter },
346  { "get_server_version", LuaTlsGetServerVersion },
347  { "get_client_version", LuaTlsGetClientVersion },
348  { "get_server_serial", LuaTlsGetServerCertSerial },
349  { "get_client_serial", LuaTlsGetClientCertSerial },
350  { "get_server_cert_info", LuaTlsGetServerCertInfo },
351  { "get_client_cert_info", LuaTlsGetClientCertInfo },
352  { "get_client_sni", LuaTlsGetSNI },
353  { "get_client_cert_chain", LuaTlsGetClientCertChain },
354  { "get_server_cert_chain", LuaTlsGetServerCertChain },
355  { NULL, NULL, }
356  // clang-format off
357 };
358 
359 static const struct luaL_Reg tlslib[] = {
360  // clang-format off
361  { "get_tx", LuaTlsFlowStateGet },
362  { NULL, NULL, },
363  // clang-format on
364 };
365 
367 {
368  luaL_newmetatable(L, tls_state_mt);
369  lua_pushvalue(L, -1);
370  lua_setfield(L, -2, "__index");
371  luaL_setfuncs(L, tlslib_meta, 0);
372 
373  luaL_newlib(L, tlslib);
374  return 1;
375 }
tm-threads.h
SSLState_
SSLv[2.0|3.[0|1|2|3]] state structure.
Definition: app-layer-ssl.h:265
LUA_ERROR
#define LUA_ERROR(msg)
Definition: util-lua-common.h:195
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:286
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:287
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:218
SSLStateConnp_
Definition: app-layer-ssl.h:177
SCLuaTxRef_
Definition: util-lua-common.h:92
threads.h
Flow_
Flow data structure.
Definition: flow.h:359
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
SCLuaCheckUserData
void * SCLuaCheckUserData(lua_State *L, int idx, const char *mt, uint32_t type_id)
Definition: util-lua-common.c:101
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
SCLuaNewUserData
void * SCLuaNewUserData(lua_State *L, uint32_t type_id, size_t size)
Definition: util-lua-common.c:42
SCLuaLoadTlsLib
int SCLuaLoadTlsLib(lua_State *L)
Definition: util-lua-tls.c:366
SSLStateConnp_::cert0_subject_len
uint32_t cert0_subject_len
Definition: app-layer-ssl.h:198
LuaStateGetTxId
uint64_t LuaStateGetTxId(lua_State *luastate)
get tx id from the lua state
Definition: util-lua.c:240
suricata-common.h
LuaTls::ref
SCLuaTxRef ref
Definition: util-lua-tls.c:59
version
uint8_t version
Definition: decode-gre.h:1
SCLUA_TUD_TLS_STATE
@ SCLUA_TUD_TLS_STATE
Definition: util-lua-common.h:61
threadvars.h
util-logopenfile.h
SCLUA_RESOLVE_TX
#define SCLUA_RESOLVE_TX(L, refp, txvar)
Definition: util-lua-common.h:128
util-buffer.h
LuaStateGetFlow
Flow * LuaStateGetFlow(lua_State *luastate)
get flow pointer from lua state
Definition: util-lua.c:260
util-lua-tls.h
SCLuaTxRefInit
void SCLuaTxRefInit(lua_State *L, SCLuaTxRef *ref, uint64_t tx_id)
Definition: util-lua-common.c:164
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:289
app-layer-ssl.h
output.h
LuaPushInteger
int LuaPushInteger(lua_State *luastate, lua_Integer n)
Definition: util-lua.c:393
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:380
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