• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 22550237931

01 Mar 2026 06:56PM UTC coverage: 64.812% (-8.9%) from 73.687%
22550237931

Pull #14920

github

web-flow
Merge e05854a6d into 90823fa90
Pull Request #14920: draft: rust based configuration file parser and loader - v4

561 of 789 new or added lines in 4 files covered. (71.1%)

23225 existing lines in 498 files now uncovered.

131605 of 203055 relevant lines covered (64.81%)

2328818.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/util-lua-hashlib.c
1
/* Copyright (C) 2025 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
 * Hashing library for Lua.
22
 *
23
 * Usage:
24
 *
25
 * local hashing = require("suricata.hashing")
26
 *
27
 * -- One shot hash
28
 * hash = hashing.sha256_digest("www.suricata.io")
29
 *
30
 * -- One shot hash to hex
31
 * hash = hashing.sha256_hexdigest("www.suricata.io")
32
 *
33
 * -- Incremental hashing
34
 * hasher = hashing.sha256()
35
 * hasher:update("www.")
36
 * hasher:update("suricata.io")
37
 * hash = hasher:finalize()
38
 *
39
 * Support hashes: sha256, sha1, md5
40
 */
41

42
#include "util-lua-hashlib.h"
43

44
#include "lauxlib.h"
45
#include "rust-bindings.h"
46

UNCOV
47
#define SHA256_MT "suricata:hashlib:sha256"
×
UNCOV
48
#define SHA1_MT   "suricata:hashlib:sha1"
×
UNCOV
49
#define MD5_MT    "suricata:hashlib:md5"
×
50

51
/**
52
 * \brief Create a new SHA-256 hash instance.
53
 */
54
static int LuaHashLibSha256New(lua_State *L)
UNCOV
55
{
×
UNCOV
56
    struct SCSha256 **hasher = lua_newuserdata(L, sizeof(struct SCSha256 *));
×
UNCOV
57
    if (hasher == NULL) {
×
58
        return luaL_error(L, "failed to allocate userdata for sha256");
×
59
    }
×
UNCOV
60
    *hasher = SCSha256New();
×
UNCOV
61
    luaL_getmetatable(L, SHA256_MT);
×
UNCOV
62
    lua_setmetatable(L, -2);
×
UNCOV
63
    return 1;
×
UNCOV
64
}
×
65

66
/**
67
 * \brief Add more data to an existing SHA-256 hash instance.
68
 */
69
static int LuaHashLibSha256Update(lua_State *L)
UNCOV
70
{
×
UNCOV
71
    struct SCSha256 **hasher = luaL_checkudata(L, 1, SHA256_MT);
×
UNCOV
72
    if (hasher == NULL) {
×
73
        return luaL_error(L, "null userdata");
×
74
    }
×
UNCOV
75
    size_t data_len;
×
UNCOV
76
    const char *data = luaL_checklstring(L, 2, &data_len);
×
UNCOV
77
    SCSha256Update(*hasher, (const uint8_t *)data, (uint32_t)data_len);
×
UNCOV
78
    return 0;
×
UNCOV
79
}
×
80

81
static int LuaHashLibSha256Finalize(lua_State *L)
UNCOV
82
{
×
UNCOV
83
    struct SCSha256 **hasher = luaL_checkudata(L, 1, SHA256_MT);
×
UNCOV
84
    if (hasher == NULL) {
×
85
        return luaL_error(L, "null userdata");
×
86
    }
×
87

UNCOV
88
    uint8_t hash[SC_SHA256_LEN];
×
UNCOV
89
    SCSha256Finalize(*hasher, hash, sizeof(hash));
×
UNCOV
90
    lua_pushlstring(L, (const char *)hash, sizeof(hash));
×
91

92
    // Finalize consumes the hasher, so set to NULL so its not free'd
93
    // during garbage collection.
UNCOV
94
    *hasher = NULL;
×
95

UNCOV
96
    return 1;
×
UNCOV
97
}
×
98

99
static int LuaHashLibSha256FinalizeToHex(lua_State *L)
UNCOV
100
{
×
UNCOV
101
    struct SCSha256 **hasher = luaL_checkudata(L, 1, SHA256_MT);
×
UNCOV
102
    if (hasher == NULL) {
×
103
        return luaL_error(L, "null userdata");
×
104
    }
×
105

UNCOV
106
    char hash[SC_SHA256_HEX_LEN + 1];
×
UNCOV
107
    if (!SCSha256FinalizeToHex(*hasher, hash, sizeof(hash))) {
×
108
        *hasher = NULL;
×
109
        return luaL_error(L, "sha256 hashing failed");
×
110
    }
×
111

UNCOV
112
    lua_pushstring(L, (const char *)hash);
×
113

114
    // Finalize consumes the hasher, so set to NULL so its not free'd
115
    // during garbage collection.
UNCOV
116
    *hasher = NULL;
×
117

UNCOV
118
    return 1;
×
UNCOV
119
}
×
120

121
static int LuaHashLibSha256Digest(lua_State *L)
UNCOV
122
{
×
UNCOV
123
    size_t buf_len;
×
UNCOV
124
    const char *input = luaL_checklstring(L, 1, &buf_len);
×
125

UNCOV
126
    uint32_t output_len = SC_SHA256_LEN;
×
UNCOV
127
    uint8_t output[output_len];
×
UNCOV
128
    if (!SCSha256HashBuffer((uint8_t *)input, (uint32_t)buf_len, output, output_len)) {
×
129
        return luaL_error(L, "sha256 hashing failed");
×
130
    }
×
131

UNCOV
132
    lua_pushlstring(L, (const char *)output, output_len);
×
133

UNCOV
134
    return 1;
×
UNCOV
135
}
×
136

137
static int LuaHashLibSha256HexDigest(lua_State *L)
UNCOV
138
{
×
UNCOV
139
    size_t buf_len;
×
UNCOV
140
    const char *input = luaL_checklstring(L, 1, &buf_len);
×
141

UNCOV
142
    char output[SC_SHA256_HEX_LEN + 1];
×
UNCOV
143
    if (!SCSha256HashBufferToHex((uint8_t *)input, (uint32_t)buf_len, output, sizeof(output))) {
×
144
        return luaL_error(L, "sha256 hashing failed");
×
145
    }
×
146

UNCOV
147
    lua_pushstring(L, (const char *)output);
×
UNCOV
148
    return 1;
×
UNCOV
149
}
×
150

151
static int LuaHashLibSha256Gc(lua_State *L)
UNCOV
152
{
×
UNCOV
153
    struct SCSha256 **hasher = luaL_checkudata(L, 1, SHA256_MT);
×
UNCOV
154
    if (hasher && *hasher) {
×
155
        SCSha256Free(*hasher);
×
156
    }
×
UNCOV
157
    return 0;
×
UNCOV
158
}
×
159

160
static int LuaHashLibSha1New(lua_State *L)
UNCOV
161
{
×
UNCOV
162
    struct SCSha1 **hasher = lua_newuserdata(L, sizeof(struct SCSha1 *));
×
UNCOV
163
    if (hasher == NULL) {
×
164
        return luaL_error(L, "failed to allocate userdata for sha1");
×
165
    }
×
UNCOV
166
    *hasher = SCSha1New();
×
UNCOV
167
    luaL_getmetatable(L, SHA1_MT);
×
UNCOV
168
    lua_setmetatable(L, -2);
×
UNCOV
169
    return 1;
×
UNCOV
170
}
×
171

172
static int LuaHashLibSha1Update(lua_State *L)
UNCOV
173
{
×
UNCOV
174
    struct SCSha1 **hasher = luaL_checkudata(L, 1, SHA1_MT);
×
UNCOV
175
    if (hasher == NULL) {
×
176
        return luaL_error(L, "null userdata");
×
177
    }
×
178

UNCOV
179
    size_t data_len;
×
UNCOV
180
    const char *data = luaL_checklstring(L, 2, &data_len);
×
UNCOV
181
    SCSha1Update(*hasher, (const uint8_t *)data, (uint32_t)data_len);
×
UNCOV
182
    return 0;
×
UNCOV
183
}
×
184

185
static int LuaHashLibSha1Finalize(lua_State *L)
UNCOV
186
{
×
UNCOV
187
    struct SCSha1 **hasher = luaL_checkudata(L, 1, SHA1_MT);
×
UNCOV
188
    if (hasher == NULL) {
×
189
        return luaL_error(L, "null userdata");
×
190
    }
×
191

UNCOV
192
    uint8_t hash[SC_SHA1_LEN];
×
UNCOV
193
    SCSha1Finalize(*hasher, hash, sizeof(hash));
×
UNCOV
194
    lua_pushlstring(L, (const char *)hash, sizeof(hash));
×
195

196
    // Finalize consumes the hasher, so set to NULL so its not free'd
197
    // during garbage collection.
UNCOV
198
    *hasher = NULL;
×
199

UNCOV
200
    return 1;
×
UNCOV
201
}
×
202

203
static int LuaHashLibSha1FinalizeToHex(lua_State *L)
UNCOV
204
{
×
UNCOV
205
    struct SCSha1 **hasher = luaL_checkudata(L, 1, SHA1_MT);
×
UNCOV
206
    if (hasher == NULL) {
×
207
        return luaL_error(L, "null userdata");
×
208
    }
×
209

UNCOV
210
    char hash[SC_SHA1_HEX_LEN + 1];
×
UNCOV
211
    if (!SCSha1FinalizeToHex(*hasher, hash, sizeof(hash))) {
×
212
        *hasher = NULL;
×
213
        return luaL_error(L, "sha1 hashing failed");
×
214
    }
×
215

UNCOV
216
    lua_pushstring(L, (const char *)hash);
×
217

218
    // Finalize consumes the hasher, so set to NULL so its not free'd
219
    // during garbage collection.
UNCOV
220
    *hasher = NULL;
×
221

UNCOV
222
    return 1;
×
UNCOV
223
}
×
224

225
static int LuaHashLibSha1Digest(lua_State *L)
UNCOV
226
{
×
UNCOV
227
    size_t buf_len;
×
UNCOV
228
    const char *input = luaL_checklstring(L, 1, &buf_len);
×
229

UNCOV
230
    uint8_t output[SC_SHA1_LEN];
×
UNCOV
231
    if (!SCSha1HashBuffer((uint8_t *)input, (uint32_t)buf_len, output, sizeof(output))) {
×
232
        return luaL_error(L, "sha1 hashing failed");
×
233
    }
×
234

UNCOV
235
    lua_pushlstring(L, (const char *)output, sizeof(output));
×
UNCOV
236
    return 1;
×
UNCOV
237
}
×
238

239
static int LuaHashLibSha1HexDigest(lua_State *L)
UNCOV
240
{
×
UNCOV
241
    size_t buf_len;
×
UNCOV
242
    const char *input = luaL_checklstring(L, 1, &buf_len);
×
243

UNCOV
244
    char output[SC_SHA1_HEX_LEN + 1];
×
UNCOV
245
    if (!SCSha1HashBufferToHex((uint8_t *)input, (uint32_t)buf_len, output, sizeof(output))) {
×
246
        return luaL_error(L, "sha1 hashing failed");
×
247
    }
×
248

UNCOV
249
    lua_pushstring(L, (const char *)output);
×
UNCOV
250
    return 1;
×
UNCOV
251
}
×
252

253
static int LuaHashLibSha1Gc(lua_State *L)
UNCOV
254
{
×
UNCOV
255
    struct SCSha1 **hasher = luaL_checkudata(L, 1, SHA1_MT);
×
UNCOV
256
    if (hasher && *hasher) {
×
257
        SCSha1Free(*hasher);
×
258
    }
×
UNCOV
259
    return 0;
×
UNCOV
260
}
×
261

262
static int LuaHashLibMd5New(lua_State *L)
UNCOV
263
{
×
UNCOV
264
    struct SCMd5 **hasher = lua_newuserdata(L, sizeof(struct SCMd5 *));
×
UNCOV
265
    if (hasher == NULL) {
×
266
        return luaL_error(L, "failed to allocate userdata for sha1");
×
267
    }
×
UNCOV
268
    *hasher = SCMd5New();
×
UNCOV
269
    luaL_getmetatable(L, MD5_MT);
×
UNCOV
270
    lua_setmetatable(L, -2);
×
UNCOV
271
    return 1;
×
UNCOV
272
}
×
273

274
static int LuaHashLibMd5Update(lua_State *L)
UNCOV
275
{
×
UNCOV
276
    struct SCMd5 **hasher = luaL_checkudata(L, 1, MD5_MT);
×
UNCOV
277
    if (hasher == NULL) {
×
278
        return luaL_error(L, "null userdata");
×
279
    }
×
280

UNCOV
281
    size_t data_len;
×
UNCOV
282
    const char *data = luaL_checklstring(L, 2, &data_len);
×
UNCOV
283
    SCMd5Update(*hasher, (const uint8_t *)data, (uint32_t)data_len);
×
UNCOV
284
    return 0;
×
UNCOV
285
}
×
286

287
static int LuaHashLibMd5Finalize(lua_State *L)
UNCOV
288
{
×
UNCOV
289
    struct SCMd5 **hasher = luaL_checkudata(L, 1, MD5_MT);
×
UNCOV
290
    if (hasher == NULL) {
×
291
        return luaL_error(L, "null userdata");
×
292
    }
×
293

UNCOV
294
    uint8_t hash[SC_MD5_LEN];
×
UNCOV
295
    SCMd5Finalize(*hasher, hash, sizeof(hash));
×
UNCOV
296
    lua_pushlstring(L, (const char *)hash, sizeof(hash));
×
297

298
    // Finalize consumes the hasher, so set to NULL so its not free'd
299
    // during garbage collection.
UNCOV
300
    *hasher = NULL;
×
301

UNCOV
302
    return 1;
×
UNCOV
303
}
×
304

305
static int LuaHashLibMd5FinalizeToHex(lua_State *L)
UNCOV
306
{
×
UNCOV
307
    struct SCMd5 **hasher = luaL_checkudata(L, 1, MD5_MT);
×
UNCOV
308
    if (hasher == NULL) {
×
309
        return luaL_error(L, "null userdata");
×
310
    }
×
311

UNCOV
312
    char hash[SC_MD5_HEX_LEN + 1];
×
UNCOV
313
    if (!SCMd5FinalizeToHex(*hasher, hash, sizeof(hash))) {
×
314
        *hasher = NULL;
×
315
        return luaL_error(L, "md5 hashing failed");
×
316
    }
×
317

UNCOV
318
    lua_pushstring(L, (const char *)hash);
×
319

320
    // Finalize consumes the hasher, so set to NULL so its not free'd
321
    // during garbage collection.
UNCOV
322
    *hasher = NULL;
×
323

UNCOV
324
    return 1;
×
UNCOV
325
}
×
326

327
static int LuaHashLibMd5Digest(lua_State *L)
UNCOV
328
{
×
UNCOV
329
    size_t buf_len;
×
UNCOV
330
    const char *input = luaL_checklstring(L, 1, &buf_len);
×
331

UNCOV
332
    uint8_t output[SC_MD5_LEN];
×
UNCOV
333
    if (!SCMd5HashBuffer((uint8_t *)input, (uint32_t)buf_len, output, sizeof(output))) {
×
334
        return luaL_error(L, "md5 hashing failed");
×
335
    }
×
336

UNCOV
337
    lua_pushlstring(L, (const char *)output, sizeof(output));
×
UNCOV
338
    return 1;
×
UNCOV
339
}
×
340

341
static int LuaHashLibMd5HexDigest(lua_State *L)
UNCOV
342
{
×
UNCOV
343
    size_t buf_len;
×
UNCOV
344
    const char *input = luaL_checklstring(L, 1, &buf_len);
×
345

UNCOV
346
    char output[SC_MD5_HEX_LEN + 1];
×
UNCOV
347
    if (!SCMd5HashBufferToHex((uint8_t *)input, (uint32_t)buf_len, output, sizeof(output))) {
×
348
        return luaL_error(L, "md5 hashing failed");
×
349
    }
×
350

UNCOV
351
    lua_pushstring(L, (const char *)output);
×
UNCOV
352
    return 1;
×
UNCOV
353
}
×
354

355
static int LuaHashLibMd5Gc(lua_State *L)
UNCOV
356
{
×
UNCOV
357
    struct SCMd5 **hasher = luaL_checkudata(L, 1, MD5_MT);
×
UNCOV
358
    if (hasher && *hasher) {
×
359
        SCMd5Free(*hasher);
×
360
    }
×
UNCOV
361
    return 0;
×
UNCOV
362
}
×
363

364
static const struct luaL_Reg hashlib[] = {
365
    // clang-format off
366
    { "sha256_digest", LuaHashLibSha256Digest },
367
    { "sha256_hexdigest", LuaHashLibSha256HexDigest },
368
    { "sha256", LuaHashLibSha256New },
369
    { "sha1_digest", LuaHashLibSha1Digest },
370
    { "sha1_hexdigest", LuaHashLibSha1HexDigest },
371
    { "sha1", LuaHashLibSha1New },
372
    { "md5_digest", LuaHashLibMd5Digest },
373
    { "md5_hexdigest", LuaHashLibMd5HexDigest },
374
    { "md5", LuaHashLibMd5New },
375
    { NULL, NULL },
376
    // clang-format on
377
};
378

379
static const struct luaL_Reg sha256_meta[] = {
380
    // clang-format off
381
    { "update", LuaHashLibSha256Update },
382
    { "finalize", LuaHashLibSha256Finalize },
383
    { "finalize_to_hex", LuaHashLibSha256FinalizeToHex },
384
    { "__gc", LuaHashLibSha256Gc },
385
    { NULL, NULL },
386
    // clang-format on
387
};
388

389
static const struct luaL_Reg sha1_meta[] = {
390
    // clang-format off
391
    { "update", LuaHashLibSha1Update },
392
    { "finalize", LuaHashLibSha1Finalize },
393
    { "finalize_to_hex", LuaHashLibSha1FinalizeToHex },
394
    { "__gc", LuaHashLibSha1Gc },
395
    { NULL, NULL },
396
    // clang-format on
397
};
398

399
static const struct luaL_Reg md5_meta[] = {
400
    // clang-format off
401
    { "update", LuaHashLibMd5Update },
402
    { "finalize", LuaHashLibMd5Finalize },
403
    { "finalize_to_hex", LuaHashLibMd5FinalizeToHex },
404
    { "__gc", LuaHashLibMd5Gc },
405
    { NULL, NULL },
406
    // clang-format on
407
};
408

409
int SCLuaLoadHashlib(lua_State *L)
UNCOV
410
{
×
UNCOV
411
    luaL_newmetatable(L, SHA256_MT);
×
UNCOV
412
    lua_pushvalue(L, -1);
×
UNCOV
413
    lua_setfield(L, -2, "__index");
×
UNCOV
414
    luaL_setfuncs(L, sha256_meta, 0);
×
415

UNCOV
416
    luaL_newmetatable(L, SHA1_MT);
×
UNCOV
417
    lua_pushvalue(L, -1);
×
UNCOV
418
    lua_setfield(L, -2, "__index");
×
UNCOV
419
    luaL_setfuncs(L, sha1_meta, 0);
×
420

UNCOV
421
    luaL_newmetatable(L, MD5_MT);
×
UNCOV
422
    lua_pushvalue(L, -1);
×
UNCOV
423
    lua_setfield(L, -2, "__index");
×
UNCOV
424
    luaL_setfuncs(L, md5_meta, 0);
×
425

UNCOV
426
    luaL_newlib(L, hashlib);
×
427

UNCOV
428
    return 1;
×
UNCOV
429
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc