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 #include "util-unittest.h"
37 
38 #include "util-debug.h"
39 
40 #include "output.h"
41 #include "app-layer.h"
42 #include "app-layer-parser.h"
43 #include "app-layer-ssl.h"
44 #include "util-privs.h"
45 #include "util-buffer.h"
46 #include "util-proto-name.h"
47 #include "util-logopenfile.h"
48 #include "util-time.h"
49 
50 #include "lua.h"
51 #include "lualib.h"
52 #include "lauxlib.h"
53 
54 #include "util-lua.h"
55 #include "util-lua-common.h"
56 #include "util-lua-tls.h"
57 
58 static const char tls_state_mt[] = "suricata:tls";
59 
60 struct LuaTls {
61  const SSLState *state; // state
62 };
63 
64 static int LuaTlsFlowStateGet(lua_State *luastate)
65 {
66  if (!LuaStateNeedProto(luastate, ALPROTO_TLS)) {
67  return LuaCallbackError(luastate, "error: protocol not tls");
68  }
69  Flow *f = LuaStateGetFlow(luastate);
70  if (f == NULL) {
71  LUA_ERROR("failed to get flow");
72  }
73 
74  struct LuaTls *s = (struct LuaTls *)lua_newuserdata(luastate, sizeof(*s));
75  if (s == NULL) {
76  LUA_ERROR("failed to allocate userdata");
77  }
78 
79  void *state = FlowGetAppState(f);
80  if (state == NULL)
81  return LuaCallbackError(luastate, "error: no app layer state");
82  s->state = (const SSLState *)state;
83  luaL_getmetatable(luastate, tls_state_mt);
84  lua_setmetatable(luastate, -2);
85  return 1;
86 }
87 
88 static int GetCertNotBefore(lua_State *luastate, bool client, const SSLState *ssl_state)
89 {
90  const SSLStateConnp *connp;
91 
92  if (client) {
93  connp = &ssl_state->client_connp;
94  } else {
95  connp = &ssl_state->server_connp;
96  }
97 
98  if (connp->cert0_not_before == 0)
99  return LuaCallbackError(luastate, "error: no certificate NotBefore");
100 
101  return LuaPushInteger(luastate, connp->cert0_not_before);
102 }
103 
104 static int LuaTlsGetServerCertNotBefore(lua_State *luastate)
105 {
106  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
107  if (s->state == NULL) {
108  LUA_ERROR("failed to get flow");
109  }
110 
111  return GetCertNotBefore(luastate, false, s->state);
112 }
113 
114 static int LuaTlsGetClientCertNotBefore(lua_State *luastate)
115 {
116  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
117  if (s->state == NULL) {
118  LUA_ERROR("failed to get flow");
119  }
120 
121  return GetCertNotBefore(luastate, true, s->state);
122 }
123 
124 static int GetCertNotAfter(lua_State *luastate, bool client, const SSLState *ssl_state)
125 {
126  const SSLStateConnp *connp;
127 
128  if (client) {
129  connp = &ssl_state->client_connp;
130  } else {
131  connp = &ssl_state->server_connp;
132  }
133 
134  if (connp->cert0_not_after == 0)
135  return LuaCallbackError(luastate, "error: no certificate NotAfter");
136 
137  return LuaPushInteger(luastate, connp->cert0_not_after);
138 }
139 
140 static int LuaTlsGetServerCertNotAfter(lua_State *luastate)
141 {
142  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
143  if (s->state == NULL) {
144  LUA_ERROR("failed to get state");
145  }
146 
147  return GetCertNotAfter(luastate, false, s->state);
148 }
149 static int LuaTlsGetClientCertNotAfter(lua_State *luastate)
150 {
151  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
152  if (s->state == NULL) {
153  LUA_ERROR("failed to get state");
154  }
155 
156  return GetCertNotAfter(luastate, true, s->state);
157 }
158 
159 static int GetCertInfo(lua_State *luastate, bool client, const SSLState *ssl_state)
160 {
161  const SSLStateConnp *connp;
162 
163  if (client) {
164  connp = &ssl_state->client_connp;
165  } else {
166  connp = &ssl_state->server_connp;
167  }
168 
169  if (connp->cert0_subject == NULL)
170  return LuaCallbackError(luastate, "error: no cert");
171 
172  /* tls.version */
173  char ssl_version[SSL_VERSION_MAX_STRLEN];
174  SSLVersionToString(ssl_state->server_connp.version, ssl_version);
175 
176  int r = LuaPushStringBuffer(luastate, (uint8_t *)ssl_version, strlen(ssl_version));
177  r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_subject, strlen(connp->cert0_subject));
178  r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_issuerdn, strlen(connp->cert0_issuerdn));
179  r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_fingerprint, strlen(connp->cert0_fingerprint));
180  return r;
181 }
182 
183 static int LuaTlsGetServerCertInfo(lua_State *luastate)
184 {
185  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
186  if (s->state == NULL) {
187  LUA_ERROR("failed to get state");
188  }
189 
190  return GetCertInfo(luastate, false, s->state);
191 }
192 
193 static int LuaTlsGetClientCertInfo(lua_State *luastate)
194 {
195  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
196  if (s->state == NULL) {
197  LUA_ERROR("failed to get state");
198  }
199 
200  return GetCertInfo(luastate, true, s->state);
201 }
202 
203 static int GetSNI(lua_State *luastate, const SSLState *ssl_state)
204 {
205  if (ssl_state->client_connp.sni == NULL)
206  return LuaCallbackError(luastate, "error: no server name indication");
207 
208  return LuaPushStringBuffer(luastate, (uint8_t *)ssl_state->client_connp.sni,
209  strlen(ssl_state->client_connp.sni));
210 }
211 
212 static int LuaTlsGetSNI(lua_State *luastate)
213 {
214  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
215  if (s->state == NULL) {
216  LUA_ERROR("failed to get state");
217  }
218 
219  if (!(LuaStateNeedProto(luastate, ALPROTO_TLS)))
220  return LuaCallbackError(luastate, "error: protocol not tls");
221 
222  return GetSNI(luastate, s->state);
223 }
224 
225 static int GetCertChain(lua_State *luastate, bool client)
226 {
227  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
228  if (s->state == NULL) {
229  LUA_ERROR("failed to get state");
230  }
231 
232  if (!(LuaStateNeedProto(luastate, ALPROTO_TLS)))
233  return LuaCallbackError(luastate, "error: protocol not tls");
234 
235  const SSLStateConnp *connp;
236 
237  if (client) {
238  connp = &s->state->client_connp;
239  } else {
240  connp = &s->state->server_connp;
241  }
242 
243  uint32_t u = 0;
244  lua_newtable(luastate);
245  SSLCertsChain *cert = NULL;
246 
247  TAILQ_FOREACH(cert, &connp->certs, next)
248  {
249  lua_pushinteger(luastate, u++);
250 
251  lua_newtable(luastate);
252 
253  lua_pushstring(luastate, "length");
254  lua_pushinteger(luastate, cert->cert_len);
255  lua_settable(luastate, -3);
256 
257  lua_pushstring(luastate, "data");
258  LuaPushStringBuffer(luastate, cert->cert_data, cert->cert_len);
259 
260  lua_settable(luastate, -3);
261  lua_settable(luastate, -3);
262  }
263 
264  return 1;
265 }
266 
267 static int LuaTlsGetServerCertChain(lua_State *luastate)
268 {
269  return GetCertChain(luastate, false);
270 }
271 
272 static int LuaTlsGetClientCertChain(lua_State *luastate)
273 {
274  return GetCertChain(luastate, true);
275 }
276 
277 static int GetCertSerial(lua_State *luastate, bool client)
278 {
279  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
280  if (s->state == NULL) {
281  LUA_ERROR("failed to get flow");
282  }
283 
284  const SSLStateConnp *connp;
285 
286  if (client) {
287  connp = &s->state->client_connp;
288  } else {
289  connp = &s->state->server_connp;
290  }
291  if (connp->cert0_serial == NULL)
292  return LuaCallbackError(luastate, "error: no certificate serial");
293 
294  return LuaPushStringBuffer(
295  luastate, (uint8_t *)connp->cert0_serial, strlen(connp->cert0_serial));
296 }
297 
298 static int LuaTlsGetServerCertSerial(lua_State *luastate)
299 {
300  return GetCertSerial(luastate, false);
301 }
302 
303 static int LuaTlsGetClientCertSerial(lua_State *luastate)
304 {
305  return GetCertSerial(luastate, true);
306 }
307 
308 static int GetAgreedVersion(lua_State *luastate, bool client)
309 {
310  struct LuaTls *s = (struct LuaTls *)luaL_checkudata(luastate, 1, tls_state_mt);
311  if (s->state == NULL) {
312  LUA_ERROR("failed to get state");
313  }
314 
315  uint16_t version;
316  if (client) {
318  } else {
320  }
321 
322  char ssl_version[SSL_VERSION_MAX_STRLEN];
323  SSLVersionToString(version, ssl_version);
324 
325  lua_pushstring(luastate, (const char *)&ssl_version);
326  return 1;
327 }
328 
329 static int LuaTlsGetServerVersion(lua_State *luastate)
330 {
331  return GetAgreedVersion(luastate, false);
332 }
333 
334 static int LuaTlsGetClientVersion(lua_State *luastate)
335 {
336  return GetAgreedVersion(luastate, true);
337 }
338 
339 static const struct luaL_Reg tlslib_meta[] = {
340  // clang-format off
341  { "get_server_cert_not_before", LuaTlsGetServerCertNotBefore },
342  { "get_client_cert_not_before", LuaTlsGetClientCertNotBefore },
343  { "get_server_cert_not_after", LuaTlsGetServerCertNotAfter },
344  { "get_client_cert_not_after", LuaTlsGetClientCertNotAfter },
345  { "get_server_version", LuaTlsGetServerVersion },
346  { "get_client_version", LuaTlsGetClientVersion },
347  { "get_server_serial", LuaTlsGetServerCertSerial },
348  { "get_client_serial", LuaTlsGetClientCertSerial },
349  { "get_server_cert_info", LuaTlsGetServerCertInfo },
350  { "get_client_cert_info", LuaTlsGetClientCertInfo },
351  { "get_client_sni", LuaTlsGetSNI },
352  { "get_client_cert_chain", LuaTlsGetClientCertChain },
353  { "get_server_cert_chain", LuaTlsGetServerCertChain },
354  { NULL, NULL, }
355  // clang-format off
356 };
357 
358 static const struct luaL_Reg tlslib[] = {
359  // clang-format off
360  { "get_tx", LuaTlsFlowStateGet },
361  { NULL, NULL, },
362  // clang-format on
363 };
364 
366 {
367  luaL_newmetatable(L, tls_state_mt);
368  lua_pushvalue(L, -1);
369  lua_setfield(L, -2, "__index");
370  luaL_setfuncs(L, tlslib_meta, 0);
371 
372  luaL_newlib(L, tlslib);
373  return 1;
374 }
tm-threads.h
SSLStateConnp_::cert0_subject
char * cert0_subject
Definition: app-layer-ssl.h:187
SSLState_
SSLv[2.0|3.[0|1|2|3]] state structure.
Definition: app-layer-ssl.h:227
LUA_ERROR
#define LUA_ERROR(msg)
Definition: util-lua-common.h:44
SSLCertsChain_::cert_len
uint32_t cert_len
Definition: app-layer-ssl.h:163
util-lua-common.h
SSLState_::client_connp
SSLStateConnp client_connp
Definition: app-layer-ssl.h:248
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:249
SSLStateConnp_::cert0_not_before
int64_t cert0_not_before
Definition: app-layer-ssl.h:190
util-lua.h
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:39
SSLStateConnp_
Definition: app-layer-ssl.h:167
threads.h
Flow_
Flow data structure.
Definition: flow.h:356
LuaTls::state
const SSLState * state
Definition: util-lua-tls.c:61
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
util-privs.h
SSLStateConnp_::sni
char * sni
Definition: app-layer-ssl.h:197
util-unittest.h
SSLStateConnp_::cert0_issuerdn
char * cert0_issuerdn
Definition: app-layer-ssl.h:188
SSLStateConnp_::cert0_not_after
int64_t cert0_not_after
Definition: app-layer-ssl.h:191
lua_State
struct lua_State lua_State
Definition: suricata-common.h:523
util-debug.h
SSLCertsChain_
Definition: app-layer-ssl.h:161
util-print.h
detect.h
pkt-var.h
util-time.h
app-layer-parser.h
conf.h
util-proto-name.h
SSLCertsChain_::cert_data
uint8_t * cert_data
Definition: app-layer-ssl.h:162
SCLuaLoadTlsLib
int SCLuaLoadTlsLib(lua_State *L)
Definition: util-lua-tls.c:365
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:161
util-lua-tls.h
SSLStateConnp_::cert0_fingerprint
char * cert0_fingerprint
Definition: app-layer-ssl.h:192
SSLStateConnp_::cert0_serial
char * cert0_serial
Definition: app-layer-ssl.h:189
LuaTls
Definition: util-lua-tls.c:60
LuaStateNeedProto
int LuaStateNeedProto(lua_State *luastate, AppProto alproto)
Definition: util-lua-common.c:169
app-layer-ssl.h
output.h
LuaPushInteger
int LuaPushInteger(lua_State *luastate, lua_Integer n)
Definition: util-lua.c:340
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:319
app-layer.h
SSLStateConnp_::version
uint16_t version
Definition: app-layer-ssl.h:176