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

zhaozg / lua-openssl / 14016924506

23 Mar 2025 07:55AM UTC coverage: 93.18% (+0.3%) from 92.866%
14016924506

push

travis-ci

zhaozg
style: .clang-format

3374 of 3453 new or added lines in 34 files covered. (97.71%)

148 existing lines in 23 files now uncovered.

9291 of 9971 relevant lines covered (93.18%)

1907.56 hits per line

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

91.18
/src/engine.c
1
/*=========================================================================*\
2
* engine.c
3
* engine object for lua-openssl binding
4
*
5
* Author:  george zhao <zhaozg(at)gmail.com>
6
\*=========================================================================*/
7

8
#include <openssl/engine.h>
9
#include <openssl/ssl.h>
10

11
#include "openssl.h"
12
#include "private.h"
13

14
#ifndef OPENSSL_NO_ENGINE
15
enum
16
{
17
  TYPE_RSA,
18
  TYPE_DSA,
19
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
20
  TYPE_ECDH,
21
  TYPE_ECDSA,
22
#else
23
  TYPE_EC,
24
#endif
25
  TYPE_DH,
26
  TYPE_RAND,
27
  TYPE_CIPHERS,
28
  TYPE_DIGESTS,
29
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
30
  TYPE_STORE,
31
#else
32
  TYPE_PKEY_METHODS,
33
  TYPE_PKEY_ASN1_METHODS,
34
#endif
35
  TYPE_COMPLETE
36
};
37

38
static const char *const list[] = { "RSA", /* 0 */
39
                                    "DSA",
40
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
41
                                    "ECDH", /* 2 */
42
                                    "ECDSA",
43
#else
44
                                    "EC",
45
#endif
46
                                    "DH", /* 4 */
47
                                    "RAND",     "ciphers", "digests", /* 8 */
48
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
49
                                    "STORE", /* 6 */
50
#else
51
                                    "PKEY",     "ASN1",
52
#endif
53
                                    "complete", /* 9 */
54

55
                                    NULL };
56

57
int
58
openssl_engine(lua_State *L)
42✔
59
{
60
  const ENGINE *eng = NULL;
42✔
61
  if (lua_isstring(L, 1)) {
42✔
62
    const char *id = luaL_checkstring(L, 1);
36✔
63
    eng = ENGINE_by_id(id);
36✔
64
  } else if (lua_isboolean(L, 1)) {
6✔
65
    int first = lua_toboolean(L, 1);
6✔
66
    if (first)
6✔
67
      eng = ENGINE_get_first();
3✔
68
    else
69
      eng = ENGINE_get_last();
3✔
70
  } else
UNCOV
71
    luaL_error(L,
×
72
               "#1 may be string or boolean\n"
73
               "\tstring for an engine id to load\n"
74
               "\ttrue for first engine, false or last engine\n"
75
               "\tbut we get %s:%s",
76
               lua_typename(L, lua_type(L, 1)),
77
               lua_tostring(L, 1));
78
  if (eng) {
42✔
79
    PUSH_OBJECT((void *)eng, "openssl.engine");
42✔
80
  } else
UNCOV
81
    lua_pushnil(L);
×
82
  return 1;
42✔
83
}
84

85
static int
86
openssl_engine_next(lua_State *L)
9✔
87
{
88
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
9✔
89
  ENGINE_up_ref(eng);
9✔
90
  eng = ENGINE_get_next(eng);
9✔
91
  if (eng) {
9✔
92
    PUSH_OBJECT(eng, "openssl.engine");
6✔
93
  } else
94
    lua_pushnil(L);
3✔
95
  return 1;
9✔
96
}
97

98
static int
99
openssl_engine_prev(lua_State *L)
9✔
100
{
101
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
9✔
102
  ENGINE_up_ref(eng);
9✔
103
  eng = ENGINE_get_prev(eng);
9✔
104
  if (eng) {
9✔
105
    PUSH_OBJECT(eng, "openssl.engine");
6✔
106
  } else
107
    lua_pushnil(L);
3✔
108
  return 1;
9✔
109
}
110

111
static int
112
openssl_engine_add(lua_State *L)
3✔
113
{
114
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
3✔
115
  int     ret = ENGINE_add(eng);
3✔
116
  lua_pushboolean(L, ret);
3✔
117
  return 1;
3✔
118
}
119

120
static int
121
openssl_engine_remove(lua_State *L)
3✔
122
{
123
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
3✔
124
  int     ret = ENGINE_remove(eng);
3✔
125
  lua_pushboolean(L, ret);
3✔
126
  return 1;
3✔
127
}
128

129
static int
130
openssl_engine_register(lua_State *L)
60✔
131
{
132
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
60✔
133
  int     unregister = 0;
60✔
134
  int     first = 2;
60✔
135
  int     top = lua_gettop(L);
60✔
136
  if (lua_isboolean(L, 2)) {
60✔
137
    unregister = lua_toboolean(L, 2);
60✔
138
    first = 3;
60✔
139
  };
140
  while (first <= top) {
114✔
141
    int c = luaL_checkoption(L, first, "RSA", list);
60✔
142
    switch (c) {
60✔
143
    case TYPE_RSA:
6✔
144
      if (unregister)
6✔
145
        ENGINE_unregister_RSA(eng);
3✔
146
      else
147
        ENGINE_register_RSA(eng);
3✔
148
      break;
6✔
149
    case TYPE_DSA:
6✔
150
      if (unregister)
6✔
151
        ENGINE_unregister_DSA(eng);
3✔
152
      else
153
        ENGINE_register_DSA(eng);
3✔
154
      break;
6✔
155
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
156
    case TYPE_ECDH:
2✔
157
      if (unregister)
2✔
158
        ENGINE_unregister_ECDH(eng);
1✔
159
      else
160
        ENGINE_register_ECDH(eng);
1✔
161
      break;
2✔
162
    case TYPE_ECDSA:
2✔
163
      if (unregister)
2✔
164
        ENGINE_unregister_ECDSA(eng);
1✔
165
      else
166
        ENGINE_register_ECDSA(eng);
1✔
167
      break;
2✔
168
#else
169
    case TYPE_EC:
4✔
170
      if (unregister)
4✔
171
        ENGINE_unregister_EC(eng);
2✔
172
      else
173
        ENGINE_register_EC(eng);
2✔
174
      break;
4✔
175
#endif
176
    case TYPE_DH:
6✔
177
      if (unregister)
6✔
178
        ENGINE_unregister_DH(eng);
3✔
179
      else
180
        ENGINE_register_DH(eng);
3✔
181
      break;
6✔
182
    case TYPE_RAND:
6✔
183
      if (unregister)
6✔
184
        ENGINE_unregister_RAND(eng);
3✔
185
      else
186
        ENGINE_register_RAND(eng);
3✔
187
      break;
6✔
188
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
189
    case TYPE_STORE:
2✔
190
      if (unregister)
2✔
191
        ENGINE_unregister_STORE(eng);
1✔
192
      else
193
        ENGINE_register_STORE(eng);
1✔
194
      break;
2✔
195
#else
196
    case TYPE_PKEY_METHODS:
4✔
197
      if (unregister)
4✔
198
        ENGINE_unregister_pkey_meths(eng);
2✔
199
      else
200
        ENGINE_register_pkey_meths(eng);
2✔
201
      break;
4✔
202
    case TYPE_PKEY_ASN1_METHODS:
4✔
203
      if (unregister)
4✔
204
        ENGINE_unregister_pkey_asn1_meths(eng);
2✔
205
      else
206
        ENGINE_register_pkey_asn1_meths(eng);
2✔
207
      break;
4✔
208
#endif
209
    case TYPE_CIPHERS:
6✔
210
      if (unregister)
6✔
211
        ENGINE_unregister_ciphers(eng);
3✔
212
      else
213
        ENGINE_register_ciphers(eng);
3✔
214
      break;
6✔
215
    case TYPE_DIGESTS:
6✔
216
      if (unregister)
6✔
217
        ENGINE_unregister_digests(eng);
3✔
218
      else
219
        ENGINE_register_digests(eng);
3✔
220
      break;
6✔
221
    case TYPE_COMPLETE: {
6✔
222
      int ret = ENGINE_register_complete(eng);
6✔
223
      lua_pushboolean(L, ret);
6✔
224
      return 1;
6✔
225
    }
226
    default:
×
227
      luaL_error(L, "not support %d for %s", c, list[c]);
×
228
      break;
×
229
    }
230
    first++;
54✔
231
  }
232
  return 0;
54✔
233
};
234

235
static int
236
openssl_engine_ctrl(lua_State *L)
15✔
237
{
238
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
15✔
239
  int     ret = 0;
15✔
240
  if (lua_isnumber(L, 2)) {
15✔
241
    int cmd = luaL_checkint(L, 2);
6✔
242
    if (lua_isnone(L, 3)) {
6✔
243
      ret = ENGINE_cmd_is_executable(eng, cmd);
3✔
244
      lua_pushboolean(L, ret);
3✔
245
      return 1;
3✔
246
    } else {
247
      long  i = (long)luaL_checknumber(L, 3);
3✔
248
      void *p = lua_touserdata(L, 4);
3✔
249
      void *arg = lua_isnoneornil(L, 5) ? NULL : lua_touserdata(L, 5);
3✔
250
      ret = ENGINE_ctrl(eng, cmd, i, p, arg);
3✔
251
    }
252
  } else {
253
    const char *cmd = luaL_checkstring(L, 2);
9✔
254
    if (lua_type(L, 3) == LUA_TNUMBER) {
9✔
255
      long i = (long)luaL_checknumber(L, 3);
6✔
256
      if (lua_isstring(L, 4)) {
6✔
NEW
257
        const char *s = lua_tostring(L, 4);
×
NEW
258
        void       *arg = lua_isnoneornil(L, 5) ? NULL : lua_touserdata(L, 5);
×
NEW
259
        int         opt = luaL_optint(L, 6, 0);
×
NEW
260
        ret = ENGINE_ctrl_cmd(eng, cmd, i, (void *)s, arg, opt);
×
261
      } else {
262
        void *p = lua_touserdata(L, 4);
6✔
263
        void *arg = lua_isnoneornil(L, 5) ? NULL : lua_touserdata(L, 5);
6✔
264
        int   opt = luaL_optint(L, 6, 0);
6✔
265
        ret = ENGINE_ctrl_cmd(eng, cmd, i, p, arg, opt);
6✔
266
      }
267
    } else {
268
      const char *arg = luaL_optstring(L, 3, NULL);
3✔
269
      int         opt = luaL_optint(L, 4, 0);
3✔
270
      ret = ENGINE_ctrl_cmd_string(eng, cmd, arg, opt);
3✔
271
    }
272
  }
273
  return openssl_pushresult(L, ret);
12✔
274
}
275

276
static int
277
openssl_engine_gc(lua_State *L)
54✔
278
{
279
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
54✔
280
  ENGINE_free(eng);
54✔
281
  return 0;
54✔
282
}
283

284
static int
285
openssl_engine_id(lua_State *L)
9✔
286
{
287
  ENGINE     *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
9✔
288
  const char *id = NULL;
9✔
289
  if (lua_isstring(L, 2)) {
9✔
290
    int ret;
291
    id = luaL_checkstring(L, 2);
3✔
292
    ret = ENGINE_set_id(eng, id);
3✔
293
    lua_pushboolean(L, ret);
3✔
294
  } else
295
    lua_pushstring(L, ENGINE_get_id(eng));
6✔
296
  return 1;
9✔
297
}
298

299
static int
300
openssl_engine_name(lua_State *L)
6✔
301
{
302
  ENGINE     *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
6✔
303
  const char *id = NULL;
6✔
304
  if (lua_isstring(L, 2)) {
6✔
305
    int ret;
306
    id = luaL_checkstring(L, 2);
3✔
307
    ret = ENGINE_set_name(eng, id);
3✔
308
    lua_pushboolean(L, ret);
3✔
309
  } else
310
    lua_pushstring(L, ENGINE_get_name(eng));
3✔
311
  return 1;
6✔
312
}
313

314
static int
315
openssl_engine_flags(lua_State *L)
6✔
316
{
317
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
6✔
318
  if (!lua_isnone(L, 2)) {
6✔
319
    int flags = luaL_checkint(L, 2);
3✔
320
    int ret = ENGINE_set_flags(eng, flags);
3✔
321
    lua_pushboolean(L, ret);
3✔
322
  } else
323
    lua_pushinteger(L, ENGINE_get_flags(eng));
3✔
324
  return 1;
6✔
325
}
326

327
/*
328
int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
329
void *ENGINE_get_ex_data(const ENGINE *e, int idx);
330
*/
331
static int
332
openssl_engine_init(lua_State *L)
3✔
333
{
334
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
3✔
335
  int     ret = ENGINE_init(eng);
3✔
336
  lua_pushboolean(L, ret);
3✔
337
  return 1;
3✔
338
}
339

340
static int
341
openssl_engine_finish(lua_State *L)
3✔
342
{
343
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
3✔
344
  int     ret = ENGINE_finish(eng);
3✔
345
  lua_pushboolean(L, ret);
3✔
346
  return 1;
3✔
347
}
348

349
static int
350
openssl_engine_set_default(lua_State *L)
9✔
351
{
352
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
9✔
353
  int     ret = 0;
9✔
354
  int     first = 2;
9✔
355
  int     top = lua_gettop(L);
9✔
356

357
  while (first <= top) {
37✔
358
    int c = luaL_checkoption(L, first, "RSA", list);
28✔
359
    switch (c) {
28✔
360
    case TYPE_RSA:
6✔
361
      ret = ENGINE_set_default_RSA(eng);
6✔
362
      break;
6✔
363
    case TYPE_DSA:
3✔
364
      ret = ENGINE_set_default_DSA(eng);
3✔
365
      break;
3✔
366
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
367
    case TYPE_ECDH:
1✔
368
      ret = ENGINE_set_default_ECDH(eng);
1✔
369
      break;
1✔
370
    case TYPE_ECDSA:
2✔
371
      ret = ENGINE_set_default_ECDSA(eng);
2✔
372
      break;
2✔
373
#else
374
    case TYPE_EC:
4✔
375
      ret = ENGINE_set_default_EC(eng);
4✔
376
      break;
4✔
377
#endif
378
    case TYPE_DH:
3✔
379
      ret = ENGINE_set_default_DH(eng);
3✔
380
      break;
3✔
381
    case TYPE_RAND:
3✔
382
      ret = ENGINE_set_default_RAND(eng);
3✔
383
      break;
3✔
384
    case TYPE_CIPHERS:
3✔
385
      ret = ENGINE_set_default_ciphers(eng);
3✔
386
      break;
3✔
387
    case TYPE_DIGESTS:
3✔
388
      ret = ENGINE_set_default_digests(eng);
3✔
389
      break;
3✔
390
    default:
×
391
      luaL_error(L, "not support '%s' to set default", c, list[c]);
×
392
      break;
×
393
    }
394
    first++;
28✔
395
    if (ret != 1) break;
28✔
396
  }
397
  return openssl_pushresult(L, ret);
9✔
398
};
399

400
static int
401
openssl_engine_set_rand_engine(lua_State *L)
3✔
402
{
403
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
3✔
404
  int     ret = RAND_set_rand_engine(eng);
3✔
405
  return openssl_pushresult(L, ret);
3✔
406
}
407

408
static int
409
openssl_engine_load_private_key(lua_State *L)
3✔
410
{
411
  ENGINE     *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
3✔
412
  const char *key_id = luaL_checkstring(L, 2);
3✔
413
  EVP_PKEY   *pkey = ENGINE_load_private_key(eng, key_id, NULL, NULL);
3✔
414
  if (pkey != NULL) {
3✔
415
    PUSH_OBJECT(pkey, "openssl.evp_pkey");
×
416
    return 1;
×
417
  }
418
  return openssl_pushresult(L, 0);
3✔
419
}
420

421
static int
422
openssl_engine_load_public_key(lua_State *L)
3✔
423
{
424
  ENGINE     *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
3✔
425
  const char *key_id = luaL_checkstring(L, 2);
3✔
426
  EVP_PKEY   *pkey = ENGINE_load_public_key(eng, key_id, NULL, NULL);
3✔
427
  if (pkey != NULL) {
3✔
428
    PUSH_OBJECT(pkey, "openssl.evp_pkey");
×
429
    return 1;
×
430
  }
431
  return openssl_pushresult(L, 0);
3✔
432
}
433

434
static int
435
openssl_engine_load_ssl_client_cert(lua_State *L)
3✔
436
{
437
  ENGINE *eng = CHECK_OBJECT(1, ENGINE, "openssl.engine");
3✔
438
  SSL    *s = CHECK_OBJECT(2, SSL, "openssl.ssl");
3✔
439
  STACK_OF(X509_NAME) *ca_dn = SSL_get_client_CA_list(s);
3✔
440

441
  X509     *pcert = NULL;
3✔
442
  EVP_PKEY *pkey = NULL;
3✔
443
  STACK_OF(X509) *pothers = NULL;
3✔
444

445
  int ret = ENGINE_load_ssl_client_cert(eng, s, ca_dn, &pcert, &pkey, &pothers, NULL, NULL);
3✔
446
  if (ret == 1) {
3✔
447
    PUSH_OBJECT(pcert, "openssl.x509");
×
NEW
448
    if (pkey != NULL) {
×
UNCOV
449
      PUSH_OBJECT(pkey, "openssl.pkey");
×
450
      ret++;
×
451
    }
NEW
452
    if (pothers != NULL) {
×
UNCOV
453
      openssl_sk_x509_totable(L, pothers);
×
454
      ret++;
×
455
    }
456
    return ret;
×
457
  }
458
  return openssl_pushresult(L, 0);
3✔
459
}
460

461
static luaL_Reg eng_funcs[] = {
462
  { "next",                 openssl_engine_next                 },
463
  { "prev",                 openssl_engine_prev                 },
464
  { "add",                  openssl_engine_add                  },
465
  { "remove",               openssl_engine_remove               },
466
  { "register",             openssl_engine_register             },
467
  { "ctrl",                 openssl_engine_ctrl                 },
468
  { "id",                   openssl_engine_id                   },
469
  { "name",                 openssl_engine_name                 },
470
  { "flags",                openssl_engine_flags                },
471

472
  { "set_rand_engine",      openssl_engine_set_rand_engine      },
473
  { "load_private_key",     openssl_engine_load_private_key     },
474
  { "load_public_key",      openssl_engine_load_public_key      },
475
  { "load_ssl_client_cert", openssl_engine_load_ssl_client_cert },
476

477
  { "init",                 openssl_engine_init                 },
478
  { "finish",               openssl_engine_finish               },
479
  { "set_default",          openssl_engine_set_default          },
480

481
  { "__gc",                 openssl_engine_gc                   },
482
  { "__tostring",           auxiliar_tostring                   },
483

484
  { NULL,                   NULL                                },
485
};
486

487
int
488
openssl_register_engine(lua_State *L)
27✔
489
{
490
  auxiliar_newclass(L, "openssl.engine", eng_funcs);
27✔
491
  return 0;
27✔
492
}
493
#endif
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