suricata
detect-tls-cert-fingerprint.c
Go to the documentation of this file.
1 /* Copyright (C) 2017 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  * \file
20  *
21  * \author Mats Klepsland <mats.klepsland@gmail.com>
22  *
23  * Implements support for tls_cert_fingerprint keyword.
24  */
25 
26 #include "suricata-common.h"
27 #include "threads.h"
28 #include "debug.h"
29 #include "decode.h"
30 #include "detect.h"
31 
32 #include "detect-parse.h"
33 #include "detect-engine.h"
34 #include "detect-engine-mpm.h"
36 #include "detect-content.h"
37 #include "detect-pcre.h"
39 
40 #include "flow.h"
41 #include "flow-util.h"
42 #include "flow-var.h"
43 
44 #include "util-debug.h"
45 #include "util-unittest.h"
46 #include "util-spm.h"
47 #include "util-print.h"
48 
49 #include "stream-tcp.h"
50 
51 #include "app-layer.h"
52 #include "app-layer-ssl.h"
53 
54 #include "util-unittest.h"
55 #include "util-unittest-helper.h"
56 
57 static int DetectTlsFingerprintSetup(DetectEngineCtx *, Signature *, const char *);
58 static void DetectTlsFingerprintRegisterTests(void);
59 static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
60  const DetectEngineTransforms *transforms,
61  Flow *_f, const uint8_t _flow_flags,
62  void *txv, const int list_id);
63 static void DetectTlsFingerprintSetupCallback(const DetectEngineCtx *de_ctx,
64  Signature *s);
65 static _Bool DetectTlsFingerprintValidateCallback(const Signature *s,
66  const char **sigerror);
67 static int g_tls_cert_fingerprint_buffer_id = 0;
68 
69 /**
70  * \brief Registration function for keyword: tls_cert_fingerprint
71  */
73 {
74  sigmatch_table[DETECT_AL_TLS_CERT_FINGERPRINT].name = "tls_cert_fingerprint";
75  sigmatch_table[DETECT_AL_TLS_CERT_FINGERPRINT].desc = "content modifier to match the TLS cert fingerprint buffer";
76  sigmatch_table[DETECT_AL_TLS_CERT_FINGERPRINT].url = DOC_URL DOC_VERSION "/rules/tls-keywords.html#tls-cert-fingerprint";
78  sigmatch_table[DETECT_AL_TLS_CERT_FINGERPRINT].Setup = DetectTlsFingerprintSetup;
80  sigmatch_table[DETECT_AL_TLS_CERT_FINGERPRINT].RegisterTests = DetectTlsFingerprintRegisterTests;
81 
83 
84  DetectAppLayerInspectEngineRegister2("tls_cert_fingerprint", ALPROTO_TLS,
87 
88  DetectAppLayerMpmRegister2("tls_cert_fingerprint", SIG_FLAG_TOCLIENT, 2,
91 
92  DetectBufferTypeSetDescriptionByName("tls_cert_fingerprint",
93  "TLS certificate fingerprint");
94 
95  DetectBufferTypeRegisterSetupCallback("tls_cert_fingerprint",
96  DetectTlsFingerprintSetupCallback);
97 
98  DetectBufferTypeRegisterValidateCallback("tls_cert_fingerprint",
99  DetectTlsFingerprintValidateCallback);
100 
101  g_tls_cert_fingerprint_buffer_id = DetectBufferTypeGetByName("tls_cert_fingerprint");
102 }
103 
104 /**
105  * \brief this function setup the tls_cert_fingerprint modifier keyword used in the rule
106  *
107  * \param de_ctx Pointer to the Detection Engine Context
108  * \param s Pointer to the Signature to which the current keyword belongs
109  * \param str Should hold an empty string always
110  *
111  * \retval 0 On success
112  */
113 static int DetectTlsFingerprintSetup(DetectEngineCtx *de_ctx, Signature *s,
114  const char *str)
115 {
116  DetectBufferSetActiveList(s, g_tls_cert_fingerprint_buffer_id);
117 
119  return -1;
120 
121  return 0;
122 }
123 
124 static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
125  const DetectEngineTransforms *transforms, Flow *_f,
126  const uint8_t _flow_flags, void *txv, const int list_id)
127 {
128  InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
129  if (buffer->inspect == NULL) {
130  SSLState *ssl_state = (SSLState *)_f->alstate;
131 
132  if (ssl_state->server_connp.cert0_fingerprint == NULL) {
133  return NULL;
134  }
135 
136  const uint32_t data_len = strlen(ssl_state->server_connp.cert0_fingerprint);
137  const uint8_t *data = (uint8_t *)ssl_state->server_connp.cert0_fingerprint;
138 
139  InspectionBufferSetup(buffer, data, data_len);
140  InspectionBufferApplyTransforms(buffer, transforms);
141  }
142 
143  return buffer;
144 }
145 
146 static _Bool DetectTlsFingerprintValidateCallback(const Signature *s,
147  const char **sigerror)
148 {
149  const SigMatch *sm = s->init_data->smlists[g_tls_cert_fingerprint_buffer_id];
150  for ( ; sm != NULL; sm = sm->next)
151  {
152  if (sm->type != DETECT_CONTENT)
153  continue;
154 
155  const DetectContentData *cd = (DetectContentData *)sm->ctx;
156 
157  if (cd->content_len != 59) {
158  *sigerror = "Invalid length of the specified fingerprint. "
159  "This rule will therefore never match.";
160  SCLogWarning(SC_WARN_POOR_RULE, "rule %u: %s", s->id, *sigerror);
161  return FALSE;
162  }
163 
164  _Bool have_delimiters = FALSE;
165  uint32_t u;
166  for (u = 0; u < cd->content_len; u++)
167  {
168  if (cd->content[u] == ':') {
169  have_delimiters = TRUE;
170  break;
171  }
172  }
173 
174  if (have_delimiters == FALSE) {
175  *sigerror = "No colon delimiters ':' detected in content after "
176  "tls_cert_fingerprint. This rule will therefore "
177  "never match.";
178  SCLogWarning(SC_WARN_POOR_RULE, "rule %u: %s", s->id, *sigerror);
179  return FALSE;
180  }
181 
182  if (cd->flags & DETECT_CONTENT_NOCASE) {
183  *sigerror = "tls_cert_fingerprint should not be used together "
184  "with nocase, since the rule is automatically "
185  "lowercased anyway which makes nocase redundant.";
186  SCLogWarning(SC_WARN_POOR_RULE, "rule %u: %s", s->id, *sigerror);
187  }
188  }
189 
190  return TRUE;
191 }
192 
193 static void DetectTlsFingerprintSetupCallback(const DetectEngineCtx *de_ctx,
194  Signature *s)
195 {
196  SigMatch *sm = s->init_data->smlists[g_tls_cert_fingerprint_buffer_id];
197  for ( ; sm != NULL; sm = sm->next)
198  {
199  if (sm->type != DETECT_CONTENT)
200  continue;
201 
203 
204  _Bool changed = FALSE;
205  uint32_t u;
206  for (u = 0; u < cd->content_len; u++)
207  {
208  if (isupper(cd->content[u])) {
209  cd->content[u] = tolower(cd->content[u]);
210  changed = TRUE;
211  }
212  }
213 
214  /* recreate the context if changes were made */
215  if (changed) {
216  SpmDestroyCtx(cd->spm_ctx);
217  cd->spm_ctx = SpmInitCtx(cd->content, cd->content_len, 1,
218  de_ctx->spm_global_thread_ctx);
219  }
220  }
221 }
222 
223 #ifdef UNITTESTS
224 
225 /**
226  * \test Test that a signature containing tls_cert_fingerprint is correctly parsed
227  * and that the keyword is registered.
228  */
229 static int DetectTlsFingerprintTest01(void)
230 {
231  DetectEngineCtx *de_ctx = NULL;
232  SigMatch *sm = NULL;
233 
234  de_ctx = DetectEngineCtxInit();
235  FAIL_IF_NULL(de_ctx);
236 
237  de_ctx->flags |= DE_QUIET;
238  de_ctx->sig_list = SigInit(de_ctx, "alert tls any any -> any any "
239  "(msg:\"Testing tls_cert_fingerprint\"; "
240  "tls_cert_fingerprint; "
241  "content:\"11:22:33:44:55:66:77:88:99:00:11:22:33:44:55:66:77:88:99:00\"; "
242  "sid:1;)");
243  FAIL_IF_NULL(de_ctx->sig_list);
244 
245  /* sm should not be in the MATCH list */
246  sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_MATCH];
247  FAIL_IF_NOT_NULL(sm);
248 
249  sm = de_ctx->sig_list->sm_lists[g_tls_cert_fingerprint_buffer_id];
250  FAIL_IF_NULL(sm);
251 
252  FAIL_IF(sm->type != DETECT_CONTENT);
253  FAIL_IF_NOT_NULL(sm->next);
254 
255  SigGroupCleanup(de_ctx);
256  SigCleanSignatures(de_ctx);
257  DetectEngineCtxFree(de_ctx);
258 
259  PASS;
260 }
261 
262 /**
263  * \test Test matching for fingerprint of a certificate.
264  */
265 static int DetectTlsFingerprintTest02(void)
266 {
267  /* client hello */
268  uint8_t client_hello[] = {
269  0x16, 0x03, 0x01, 0x00, 0xc8, 0x01, 0x00, 0x00,
270  0xc4, 0x03, 0x03, 0xd6, 0x08, 0x5a, 0xa2, 0x86,
271  0x5b, 0x85, 0xd4, 0x40, 0xab, 0xbe, 0xc0, 0xbc,
272  0x41, 0xf2, 0x26, 0xf0, 0xfe, 0x21, 0xee, 0x8b,
273  0x4c, 0x7e, 0x07, 0xc8, 0xec, 0xd2, 0x00, 0x46,
274  0x4c, 0xeb, 0xb7, 0x00, 0x00, 0x16, 0xc0, 0x2b,
275  0xc0, 0x2f, 0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x13,
276  0xc0, 0x14, 0x00, 0x33, 0x00, 0x39, 0x00, 0x2f,
277  0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x85,
278  0x00, 0x00, 0x00, 0x12, 0x00, 0x10, 0x00, 0x00,
279  0x0d, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f,
280  0x67, 0x6c, 0x65, 0x2e, 0x6e, 0x6f, 0xff, 0x01,
281  0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00,
282  0x06, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
283  0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00,
284  0x00, 0x33, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00,
285  0x29, 0x00, 0x27, 0x05, 0x68, 0x32, 0x2d, 0x31,
286  0x36, 0x05, 0x68, 0x32, 0x2d, 0x31, 0x35, 0x05,
287  0x68, 0x32, 0x2d, 0x31, 0x34, 0x02, 0x68, 0x32,
288  0x08, 0x73, 0x70, 0x64, 0x79, 0x2f, 0x33, 0x2e,
289  0x31, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31,
290  0x2e, 0x31, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00,
291  0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x16, 0x00,
292  0x14, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02,
293  0x01, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02,
294  0x03, 0x04, 0x02, 0x02, 0x02
295  };
296 
297  /* server hello */
298  uint8_t server_hello[] = {
299  0x16, 0x03, 0x03, 0x00, 0x48, 0x02, 0x00, 0x00,
300  0x44, 0x03, 0x03, 0x57, 0x91, 0xb8, 0x63, 0xdd,
301  0xdb, 0xbb, 0x23, 0xcf, 0x0b, 0x43, 0x02, 0x1d,
302  0x46, 0x11, 0x27, 0x5c, 0x98, 0xcf, 0x67, 0xe1,
303  0x94, 0x3d, 0x62, 0x7d, 0x38, 0x48, 0x21, 0x23,
304  0xa5, 0x62, 0x31, 0x00, 0xc0, 0x2f, 0x00, 0x00,
305  0x1c, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
306  0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10,
307  0x00, 0x05, 0x00, 0x03, 0x02, 0x68, 0x32, 0x00,
308  0x0b, 0x00, 0x02, 0x01, 0x00
309  };
310 
311  /* certificate */
312  uint8_t certificate[] = {
313  0x16, 0x03, 0x03, 0x04, 0x93, 0x0b, 0x00, 0x04,
314  0x8f, 0x00, 0x04, 0x8c, 0x00, 0x04, 0x89, 0x30,
315  0x82, 0x04, 0x85, 0x30, 0x82, 0x03, 0x6d, 0xa0,
316  0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x5c, 0x19,
317  0xb7, 0xb1, 0x32, 0x3b, 0x1c, 0xa1, 0x30, 0x0d,
318  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
319  0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x49, 0x31,
320  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
321  0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11,
322  0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x47,
323  0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
324  0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55,
325  0x04, 0x03, 0x13, 0x1c, 0x47, 0x6f, 0x6f, 0x67,
326  0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72,
327  0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68,
328  0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x47, 0x32,
329  0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x37,
330  0x31, 0x33, 0x31, 0x33, 0x32, 0x34, 0x35, 0x32,
331  0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x30, 0x30,
332  0x35, 0x31, 0x33, 0x31, 0x36, 0x30, 0x30, 0x5a,
333  0x30, 0x65, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
334  0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
335  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
336  0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f,
337  0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14,
338  0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d,
339  0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20,
340  0x56, 0x69, 0x65, 0x77, 0x31, 0x13, 0x30, 0x11,
341  0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x47,
342  0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e,
343  0x63, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
344  0x04, 0x03, 0x0c, 0x0b, 0x2a, 0x2e, 0x67, 0x6f,
345  0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6e, 0x6f, 0x30,
346  0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
347  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
348  0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
349  0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
350  0xa5, 0x0a, 0xb9, 0xb1, 0xca, 0x36, 0xd1, 0xae,
351  0x22, 0x38, 0x07, 0x06, 0xc9, 0x1a, 0x56, 0x4f,
352  0xbb, 0xdf, 0xa8, 0x6d, 0xbd, 0xee, 0x76, 0x16,
353  0xbc, 0x53, 0x3c, 0x03, 0x6a, 0x5c, 0x94, 0x50,
354  0x87, 0x2f, 0x28, 0xb4, 0x4e, 0xd5, 0x9b, 0x8f,
355  0xfe, 0x02, 0xde, 0x2a, 0x83, 0x01, 0xf9, 0x45,
356  0x61, 0x0e, 0x66, 0x0e, 0x24, 0x22, 0xe2, 0x59,
357  0x66, 0x0d, 0xd3, 0xe9, 0x77, 0x8a, 0x7e, 0x42,
358  0xaa, 0x5a, 0xf9, 0x05, 0xbf, 0x30, 0xc7, 0x03,
359  0x2b, 0xdc, 0xa6, 0x9c, 0xe0, 0x9f, 0x0d, 0xf1,
360  0x28, 0x19, 0xf8, 0xf2, 0x02, 0xfa, 0xbd, 0x62,
361  0xa0, 0xf3, 0x02, 0x2b, 0xcd, 0xf7, 0x09, 0x04,
362  0x3b, 0x52, 0xd8, 0x65, 0x4b, 0x4a, 0x70, 0xe4,
363  0x57, 0xc9, 0x2e, 0x2a, 0xf6, 0x9c, 0x6e, 0xd8,
364  0xde, 0x01, 0x52, 0xc9, 0x6f, 0xe9, 0xef, 0x82,
365  0xbc, 0x0b, 0x95, 0xb2, 0xef, 0xcb, 0x91, 0xa6,
366  0x0b, 0x2d, 0x14, 0xc6, 0x00, 0xa9, 0x33, 0x86,
367  0x64, 0x00, 0xd4, 0x92, 0x19, 0x53, 0x3d, 0xfd,
368  0xcd, 0xc6, 0x1a, 0xf2, 0x0e, 0x67, 0xc2, 0x1d,
369  0x2c, 0xe0, 0xe8, 0x29, 0x97, 0x1c, 0xb6, 0xc4,
370  0xb2, 0x02, 0x0c, 0x83, 0xb8, 0x60, 0x61, 0xf5,
371  0x61, 0x2d, 0x73, 0x5e, 0x85, 0x4d, 0xbd, 0x0d,
372  0xe7, 0x1a, 0x37, 0x56, 0x8d, 0xe5, 0x50, 0x0c,
373  0xc9, 0x64, 0x4c, 0x11, 0xea, 0xf3, 0xcb, 0x26,
374  0x34, 0xbd, 0x02, 0xf5, 0xc1, 0xfb, 0xa2, 0xec,
375  0x27, 0xbb, 0x60, 0xbe, 0x0b, 0xf6, 0xe7, 0x3c,
376  0x2d, 0xc9, 0xe7, 0xb0, 0x30, 0x28, 0x17, 0x3d,
377  0x90, 0xf1, 0x63, 0x8e, 0x49, 0xf7, 0x15, 0x78,
378  0x21, 0xcc, 0x45, 0xe6, 0x86, 0xb2, 0xd8, 0xb0,
379  0x2e, 0x5a, 0xb0, 0x58, 0xd3, 0xb6, 0x11, 0x40,
380  0xae, 0x81, 0x1f, 0x6b, 0x7a, 0xaf, 0x40, 0x50,
381  0xf9, 0x2e, 0x81, 0x8b, 0xec, 0x26, 0x11, 0x3f,
382  0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
383  0x53, 0x30, 0x82, 0x01, 0x4f, 0x30, 0x1d, 0x06,
384  0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14,
385  0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
386  0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
387  0x05, 0x07, 0x03, 0x02, 0x30, 0x21, 0x06, 0x03,
388  0x55, 0x1d, 0x11, 0x04, 0x1a, 0x30, 0x18, 0x82,
389  0x0b, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
390  0x65, 0x2e, 0x6e, 0x6f, 0x82, 0x09, 0x67, 0x6f,
391  0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6e, 0x6f, 0x30,
392  0x68, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
393  0x07, 0x01, 0x01, 0x04, 0x5c, 0x30, 0x5a, 0x30,
394  0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
395  0x07, 0x30, 0x02, 0x86, 0x1f, 0x68, 0x74, 0x74,
396  0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x6b, 0x69, 0x2e,
397  0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63,
398  0x6f, 0x6d, 0x2f, 0x47, 0x49, 0x41, 0x47, 0x32,
399  0x2e, 0x63, 0x72, 0x74, 0x30, 0x2b, 0x06, 0x08,
400  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
401  0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
402  0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73,
403  0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
404  0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73,
405  0x70, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
406  0x04, 0x16, 0x04, 0x14, 0xc6, 0x53, 0x87, 0x42,
407  0x2d, 0xc8, 0xee, 0x7a, 0x62, 0x1e, 0x83, 0xdb,
408  0x0d, 0xe2, 0x32, 0xeb, 0x8b, 0xaf, 0x69, 0x40,
409  0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
410  0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f,
411  0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
412  0x16, 0x80, 0x14, 0x4a, 0xdd, 0x06, 0x16, 0x1b,
413  0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81, 0xb6,
414  0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30,
415  0x21, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x1a,
416  0x30, 0x18, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06,
417  0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x05, 0x01,
418  0x30, 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01,
419  0x02, 0x02, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d,
420  0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0,
421  0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74,
422  0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x6b, 0x69, 0x2e,
423  0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63,
424  0x6f, 0x6d, 0x2f, 0x47, 0x49, 0x41, 0x47, 0x32,
425  0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09,
426  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
427  0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
428  0x7b, 0x27, 0x00, 0x46, 0x8f, 0xfd, 0x5b, 0xff,
429  0xcb, 0x05, 0x9b, 0xf7, 0xf1, 0x68, 0xf6, 0x9a,
430  0x7b, 0xba, 0x53, 0xdf, 0x63, 0xed, 0x11, 0x94,
431  0x39, 0xf2, 0xd0, 0x20, 0xcd, 0xa3, 0xc4, 0x98,
432  0xa5, 0x10, 0x74, 0xe7, 0x10, 0x6d, 0x07, 0xf8,
433  0x33, 0x87, 0x05, 0x43, 0x0e, 0x64, 0x77, 0x09,
434  0x18, 0x4f, 0x38, 0x2e, 0x45, 0xae, 0xa8, 0x34,
435  0x3a, 0xa8, 0x33, 0xac, 0x9d, 0xdd, 0x25, 0x91,
436  0x59, 0x43, 0xbe, 0x0f, 0x87, 0x16, 0x2f, 0xb5,
437  0x27, 0xfd, 0xce, 0x2f, 0x35, 0x5d, 0x12, 0xa1,
438  0x66, 0xac, 0xf7, 0x95, 0x38, 0x0f, 0xe5, 0xb1,
439  0x18, 0x18, 0xe6, 0x80, 0x52, 0x31, 0x8a, 0x66,
440  0x02, 0x52, 0x1a, 0xa4, 0x32, 0x6a, 0x61, 0x05,
441  0xcf, 0x1d, 0xf9, 0x90, 0x73, 0xf0, 0xeb, 0x20,
442  0x31, 0x7b, 0x2e, 0xc0, 0xb0, 0xfb, 0x5c, 0xcc,
443  0xdc, 0x76, 0x55, 0x72, 0xaf, 0xb1, 0x05, 0xf4,
444  0xad, 0xf9, 0xd7, 0x73, 0x5c, 0x2c, 0xbf, 0x0d,
445  0x84, 0x18, 0x01, 0x1d, 0x4d, 0x08, 0xa9, 0x4e,
446  0x37, 0xb7, 0x58, 0xc4, 0x05, 0x0e, 0x65, 0x63,
447  0xd2, 0x88, 0x02, 0xf5, 0x82, 0x17, 0x08, 0xd5,
448  0x8f, 0x80, 0xc7, 0x82, 0x29, 0xbb, 0xe1, 0x04,
449  0xbe, 0xf6, 0xe1, 0x8c, 0xbc, 0x3a, 0xf8, 0xf9,
450  0x56, 0xda, 0xdc, 0x8e, 0xc6, 0xe6, 0x63, 0x98,
451  0x12, 0x08, 0x41, 0x2c, 0x9d, 0x7c, 0x82, 0x0d,
452  0x1e, 0xea, 0xba, 0xde, 0x32, 0x09, 0xda, 0x52,
453  0x24, 0x4f, 0xcc, 0xb6, 0x09, 0x33, 0x8b, 0x00,
454  0xf9, 0x83, 0xb3, 0xc6, 0xa4, 0x90, 0x49, 0x83,
455  0x2d, 0x36, 0xd9, 0x11, 0x78, 0xd0, 0x62, 0x9f,
456  0xc4, 0x8f, 0x84, 0xba, 0x7f, 0xaa, 0x04, 0xf1,
457  0xd9, 0xa4, 0xad, 0x5d, 0x63, 0xee, 0x72, 0xc6,
458  0x4d, 0xd1, 0x4b, 0x41, 0x8f, 0x40, 0x0f, 0x7d,
459  0xcd, 0xb8, 0x2e, 0x5b, 0x6e, 0x21, 0xc9, 0x3d
460  };
461 
462  Flow f;
463  SSLState *ssl_state = NULL;
464  TcpSession ssn;
465  Packet *p1 = NULL;
466  Packet *p2 = NULL;
467  Packet *p3 = NULL;
468  Signature *s = NULL;
469  ThreadVars tv;
470  DetectEngineThreadCtx *det_ctx = NULL;
472 
473  memset(&tv, 0, sizeof(ThreadVars));
474  memset(&f, 0, sizeof(Flow));
475  memset(&ssn, 0, sizeof(TcpSession));
476 
477  p1 = UTHBuildPacketReal(client_hello, sizeof(client_hello), IPPROTO_TCP,
478  "192.168.1.5", "192.168.1.1", 51251, 443);
479  p2 = UTHBuildPacketReal(server_hello, sizeof(server_hello), IPPROTO_TCP,
480  "192.168.1.1", "192.168.1.5", 443, 51251);
481  p3 = UTHBuildPacketReal(certificate, sizeof(certificate), IPPROTO_TCP,
482  "192.168.1.1", "192.168.1.5", 443, 51251);
483 
484  FLOW_INITIALIZE(&f);
485  f.flags |= FLOW_IPV4;
486  f.proto = IPPROTO_TCP;
488  f.alproto = ALPROTO_TLS;
489 
490  p1->flow = &f;
494  p1->pcap_cnt = 1;
495 
496  p2->flow = &f;
500  p2->pcap_cnt = 2;
501 
502  p3->flow = &f;
506  p3->pcap_cnt = 3;
507 
509 
511  FAIL_IF_NULL(de_ctx);
512 
514  de_ctx->flags |= DE_QUIET;
515 
516  s = DetectEngineAppendSig(de_ctx, "alert tls any any -> any any "
517  "(msg:\"Test tls_cert_fingerprint\"; "
518  "tls_cert_fingerprint; "
519  "content:\"4a:a3:66:76:82:cb:6b:23:bb:c3:58:47:23:a4:63:a7:78:a4:a1:18\"; "
520  "sid:1;)");
521  FAIL_IF_NULL(s);
522 
523  SigGroupBuild(de_ctx);
524  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
525 
526  FLOWLOCK_WRLOCK(&f);
527  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS,
528  STREAM_TOSERVER, client_hello,
529  sizeof(client_hello));
530  FLOWLOCK_UNLOCK(&f);
531 
532  FAIL_IF(r != 0);
533 
534  ssl_state = f.alstate;
535  FAIL_IF_NULL(ssl_state);
536 
537  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
538 
539  FAIL_IF(PacketAlertCheck(p1, 1));
540 
541  FLOWLOCK_WRLOCK(&f);
542  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT,
543  server_hello, sizeof(server_hello));
544  FLOWLOCK_UNLOCK(&f);
545 
546  FAIL_IF(r != 0);
547 
548  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
549 
550  FAIL_IF(PacketAlertCheck(p2, 1));
551 
552  FLOWLOCK_WRLOCK(&f);
553  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT,
554  certificate, sizeof(certificate));
555  FLOWLOCK_UNLOCK(&f);
556 
557  FAIL_IF(r != 0);
558 
559  SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
560 
562 
563  AppLayerParserThreadCtxFree(alp_tctx);
564  DetectEngineThreadCtxDeinit(&tv, det_ctx);
565  SigGroupCleanup(de_ctx);
566  DetectEngineCtxFree(de_ctx);
568  FLOW_DESTROY(&f);
569  UTHFreePacket(p1);
570  UTHFreePacket(p2);
571  UTHFreePacket(p3);
572 
573  PASS;
574 }
575 
576 #endif /* UNITTESTS */
577 
578 static void DetectTlsFingerprintRegisterTests(void)
579 {
580 #ifdef UNITTESTS
581  UtRegisterTest("DetectTlsFingerprintTest01", DetectTlsFingerprintTest01);
582  UtRegisterTest("DetectTlsFingerprintTest02", DetectTlsFingerprintTest02);
583 #endif /* UNITTESTS */
584 }
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1403
SignatureInitData * init_data
Definition: detect.h:560
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1146
SpmGlobalThreadCtx * spm_global_thread_ctx
Definition: detect.h:774
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
struct Flow_ * flow
Definition: decode.h:444
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint8_t proto
Definition: flow.h:346
uint32_t id
Definition: detect.h:525
#define FALSE
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:235
#define PASS
Pass the test.
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
char * cert0_fingerprint
Signature * sig_list
Definition: detect.h:726
int PrefilterGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectMpmAppLayerRegistery *mpm_reg, int list_id)
SSLStateConnp server_connp
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:95
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:195
void SigCleanSignatures(DetectEngineCtx *de_ctx)
void DetectBufferTypeRegisterSetupCallback(const char *name, void(*SetupCallback)(const DetectEngineCtx *, Signature *))
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:232
uint64_t pcap_cnt
Definition: decode.h:566
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
InspectionBuffer * InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id)
const char * name
Definition: detect.h:1160
Signature container.
Definition: detect.h:492
#define TRUE
struct SigMatch_ * next
Definition: detect.h:328
main detection engine ctx
Definition: detect.h:720
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
SSLv[2.0|3.[0|1|2|3]] state structure.
void * alstate
Definition: flow.h:436
#define DE_QUIET
Definition: detect.h:298
int DetectBufferTypeGetByName(const char *name)
#define str(s)
#define SIG_FLAG_TOCLIENT
Definition: detect.h:244
SpmCtx * SpmInitCtx(const uint8_t *needle, uint16_t needle_len, int nocase, SpmGlobalThreadCtx *global_thread_ctx)
Definition: util-spm.c:166
uint8_t flags
Definition: detect.h:721
void(* Free)(void *)
Definition: detect.h:1151
#define FLOW_DESTROY(f)
Definition: flow-util.h:115
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
uint16_t mpm_matcher
Definition: detect.h:769
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1752
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
void DetectAppLayerInspectEngineRegister2(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr2 Callback2, InspectionBufferGetDataPtr GetData)
register inspect engine at start up time
Packet * UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst, uint16_t sport, uint16_t dport)
UTHBuildPacketReal is a function that create tcp/udp packets for unittests specifying ip and port sou...
uint8_t flowflags
Definition: decode.h:438
void DetectTlsFingerprintRegister(void)
Registration function for keyword: tls_cert_fingerprint.
#define STREAM_TOCLIENT
Definition: stream.h:32
#define FLOW_PKT_TOSERVER
Definition: flow.h:193
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
int SigGroupCleanup(DetectEngineCtx *de_ctx)
uint8_t type
Definition: detect.h:325
int DetectEngineInspectBufferGeneric(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
const char * desc
Definition: detect.h:1162
struct SigMatch_ ** smlists
Definition: detect.h:486
SigMatchCtx * ctx
Definition: detect.h:327
int mpm_default_matcher
Definition: util-mpm.h:166
void InspectionBufferSetup(InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len)
setup the buffer with our initial data
void InspectionBufferApplyTransforms(InspectionBuffer *buffer, const DetectEngineTransforms *transforms)
#define SIGMATCH_NOOPT
Definition: detect.h:1328
int(* Match)(ThreadVars *, DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1129
void SpmDestroyCtx(SpmCtx *ctx)
Definition: util-spm.c:176
const char * url
Definition: detect.h:1163
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
#define PKT_HAS_FLOW
Definition: decode.h:1101
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
int DetectBufferSetActiveList(Signature *s, const int list)
const uint8_t * inspect
Definition: detect.h:349
#define DOC_URL
Definition: suricata.h:86
void DetectBufferTypeSetDescriptionByName(const char *name, const char *desc)
#define DETECT_CONTENT_NOCASE
Per thread variable structure.
Definition: threadvars.h:57
void DetectBufferTypeRegisterValidateCallback(const char *name, _Bool(*ValidateCallback)(const Signature *, const char **sigerror))
#define FLOW_PKT_TOCLIENT
Definition: flow.h:194
AppProto alproto
application level protocol
Definition: flow.h:407
uint32_t flags
Definition: decode.h:442
#define DOC_VERSION
Definition: suricata.h:91
uint16_t flags
Definition: detect.h:1154
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
uint8_t protomap
Definition: flow.h:402
Flow data structure.
Definition: flow.h:327
#define FLOW_IPV4
Definition: flow.h:93
uint32_t flags
Definition: flow.h:377
#define PKT_STREAM_EST
Definition: decode.h:1099
void(* RegisterTests)(void)
Definition: detect.h:1152
a single match condition for a signature
Definition: detect.h:324
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, uint8_t *input, uint32_t input_len)
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectAppLayerMpmRegister2(const char *name, int direction, int priority, int(*PrefilterRegister)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectMpmAppLayerRegistery *mpm_reg, int list_id), InspectionBufferGetDataPtr GetData, AppProto alproto, int tx_min_progress)
register a MPM engine